This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: generic-build-script extension to update version numbers in README


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christian Franke wrote:
> What would you think about an autoconf-like approach generating a
> "package-VER.sh" script from some "package.sh.in" (yes, no version).
> 
> Then fixes and new features will be added to only one generation tool
> (autogbs ?-)) which can be part of a standard Cygwin package managed by
> setup.exe.
> The generator can check the actual structure of the source tree to
> create a smaller build-script.
> 
> New features can be opt'ed in by directives in the package.sh.in script
> if desired.
> Like with autoconf, it would be possibled to do special hacks by
> including shell code verbatim.

It is a good idea, but I would avoid .in naming, since I think we will
want to go beyond simple autoconf-style variable substitution.

I'm already doing programmatic editing of the g-b-s for my own packages.
Attached is 'gbsmunge.py', which reads a control file, and the
generic-build-script source, and outputs a build script munged according
to instructions in the control file.

For illustrative purposes, here is the control file for my neon package:
=======
ConfigureArg --enable-shared
ConfigureArg --disable-static
ConfigureArg --with-ssl

SubPackage libneon24-$VER-$REL.tar.bz2 usr/bin/cygneon-24.dll
=======

Max.




P.S.: The control file for the (much more complex) apache2 package:
======
ConfigureArg --enable-shared
ConfigureArg --disable-static
ConfigureArg --with-apr=/usr
ConfigureArg --with-apr-util=/usr
ConfigureArg --with-neon=/usr
ConfigureArg --with-swig=/usr/bin/swig
ConfigureArg --with-apxs=/usr/sbin/apxs2

SubPackage subversion-devel-$VER-$REL.tar.bz2 usr/include
  usr/lib/libsvn_[a-rt-z]* usr/lib/libsvn_subr*
SubPackage subversion-python-$VER-$REL.tar.bz2 usr/lib/python*
  usr/bin/cygsvn_swig_py* usr/lib/libsvn_swig_py*
SubPackage subversion-perl-$VER-$REL.tar.bz2 usr/lib/perl5
  usr/bin/cygsvn_swig_perl* usr/lib/libsvn_swig_perl*
SubPackage subversion-apache2-$VER-$REL.tar.bz2 usr/lib/apache2
SubPackage subversion-book-$VER-$REL.tar.bz2
  usr/share/doc/subversion-*/svn-book.html
  usr/share/doc/subversion-*/images

AutoreconfCmd ./autogen.sh
AutoreconfCmd find . -name "autom4te.cache" | xargs rm -rf
AutoreconfCmd sed -e 's/relink_command=\\"$relink_command\\""/"/'
  ac-helpers/ltmain.sh > gbs.$$.tmp &&
  mv gbs.$$.tmp ac-helpers/ltmain.sh

MakeTarget
MakeTarget swig-py swig_pydir=/usr/lib/python2.4/site-packages/libsvn
  swig_pydir_extra=/usr/lib/python2.4/site-packages/svn
MakeTarget swig-pl

MakeInstallTarget install
MakeInstallTarget install-swig-py
  swig_pydir=/usr/lib/python2.4/site-packages/libsvn
  swig_pydir_extra=/usr/lib/python2.4/site-packages/svn
MakeInstallTarget install-swig-pl

InstallExtraCmd mkdir -p ${instdir}/usr/share/doc/${BASEPKG}
InstallExtraCmd cp ${srcdir}/doc/book/svn-book.html
  ${instdir}/usr/share/doc/${BASEPKG}/svn-book.html
InstallExtraCmd cp -r ${srcdir}/doc/book/images
  ${instdir}/usr/share/doc/${BASEPKG}/images

# Kill perllocal.pod and containing dirs
InstallExtraCmd rm ${instdir}/usr/lib/perl5/5.8/cygwin/perllocal.pod
InstallExtraCmd rmdir ${instdir}/usr/lib/perl5/5.8/cygwin
InstallExtraCmd rmdir ${instdir}/usr/lib/perl5/5.8

UnpackExclude */apr
UnpackExclude */apr-util
UnpackExclude */neon

DiffExclude configure
DiffExclude build-outputs.mk
======
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Cygwin)

iD8DBQFDf3HnfFNSmcDyxYARAkCXAKDcA+n68ib+7RoGPB5KA5PKh+z82wCbBL6Z
LcCrLFQDRtSn07pjb2GYMFE=
=Qa9j
-----END PGP SIGNATURE-----
#!/usr/bin/python

# A script to customize the generic-build-script based on a set of rules
# Rules are expressed by a simple configuration file
# Last updated for revision 1.38
#
# Syntax: gbsmunge.py -F configfile [file-to-filter]

import sys, os, fileinput, getopt

class PkgConfig:
  I_DEFAULT, = range(1)
  info = {
  "ConfigureArg":           ([], ),
  "TestMakeRule":           ("", ),
  "PrepCmd":                ([], ),
  "MakeTarget":             ([], ),
  "MakeInstallTarget":      ([], ),
  "InstallExtraCmd":        ([], ),
  "PreConfigureCmd":        ([], ),
  "AutoreconfCmd":          ([], ),
  "UnpackExclude":          ([], ),
  "DiffExclude":            (['*.orig', '*.rej'], ),
  "ExtraDocFile":           ([], ),
  "NoDefaultConfigureArgs": (False, ),
  "BuildInSourceDir":       (False, ),
  "NoDiffNewFiles":         (False, ),
  "AlternateTarballStem":   ("", ),
  "AlternateShareDocDir":   ("", ),
  "VersionLimit":           ("", ),
  "SubPackage":             ({}, ),
  "ExtraFile":              ({}, ),
  }
  def __init__(self):
    for directive, info in self.info.items():
      setattr(self, directive, info[self.I_DEFAULT])

  def register_option(self, optstr):
    "Parse and store a single configuration statement"
    directive_and_arg = optstr.split(" ", 1)
    directive = directive_and_arg[0]
    try:
      arg = directive_and_arg[1]
    except IndexError:
      arg = None
    try:
      info = self.info[directive]
    except KeyError:
      sys.exit("Invalid directive '%s'" % directive)
    if type(info[self.I_DEFAULT]) == list:
      getattr(self, directive).append(arg)
    elif type(info[self.I_DEFAULT]) == str:
      setattr(self, directive, arg)
    elif type(info[self.I_DEFAULT]) == bool:
      setattr(self, directive, not info[self.I_DEFAULT])
    elif type(info[self.I_DEFAULT]) == dict:
      items = arg.split(" ")
      if directive == "ExtraFile":
        if len(items) == 1:
          val = os.path.basename(items[0])
        else:
          val = items[1]
      else:
        val = items[1:]
      getattr(self, directive)[items[0]] = val

  def dump_config(self):
    for directive in self.info.keys():
      print >> sys.stderr, "%s: %s" % (directive, getattr(self, directive))

  def read_fp(self, fp):
    for line in fp.readlines():
      line = line.rstrip('\r\n')
      if line and line[0] != '#':
        self.register_option(line)

def main():
  c = PkgConfig()
  opts, args = getopt.gnu_getopt(sys.argv[1:], 'F:')
  for o, a in opts:
    if o == "-F":
      f = open(a)
      c.read_fp(f)
      f.close()
  c.dump_config()
  gbsmunge(c, args[0])

def gbsmunge(c, from_fn, to_fn=None):
  if to_fn:
    to_fp = file(to_fn, 'w')
  else:
    to_fp = sys.stdout

  def out(s):
    to_fp.write(s + "\n")

  for line in fileinput.FileInput(from_fn):
    line = line.rstrip()
    # prologue
    if line == "export BASEPKG=${PKG}-${VER}":
      if c.AlternateTarballStem:
        out("export BASEPKG=" + c.AlternateTarballStem + "-${VER}")
        continue
    elif line == 'export install_docs="\\':
      out(line)
      for i in c.ExtraDocFile:
        out("\t%s\\" % (i,))
      continue
    elif line == "export test_rule=check":
      if c.TestMakeRule:
        out("export test_rule=" + c.TestMakeRule)
        continue
    # unpack
    elif line == '  tar xv${opt_decomp}f "$1"':
      if c.UnpackExclude:
        out("  tar --exclude='%s' -xv${opt_decomp}f \"$1\""
            % ("' --exclude='".join(c.UnpackExclude)))
        continue
    # prep
    elif line == "  mkdirs )":
      if c.PrepCmd:
        for cmd in c.PrepCmd:
          out("  %s && \\" % cmd)
      if c.AutoreconfCmd:
        out("  (cd ${BASEPKG} && \\")
        for cmd in c.AutoreconfCmd[:-1]:
          out("  %s && \\" % cmd)
        out("  %s ) && \\" % c.AutoreconfCmd[-1])
      out("  mkdirs )")
      continue
    # conf
    elif line == '  CFLAGS="${MY_CFLAGS}" LDFLAGS="${MY_LDFLAGS}" \\':
      if c.PreConfigureCmd:
        for cmd in c.PreConfigureCmd:
          out("  %s && \\" % cmd)
    elif line in (
        """  --srcdir=${srcdir} --prefix="${prefix}" \\""",
        """  --exec-prefix='${prefix}' --sysconfdir="${sysconfdir}" \\""",
        "  --libdir='${prefix}/lib' --includedir='${prefix}/include' \\",
        "  --mandir='${prefix}/share/man' --infodir='${prefix}/share/info' \\",
        """  --libexecdir='${sbindir}' --localstatedir="${localstatedir}" \\""",
        ):
      if c.NoDefaultConfigureArgs:
        continue
    elif line == "  --datadir='${prefix}/share' )":
      if c.ConfigureArg:
        if not c.NoDefaultConfigureArgs:
          out(line[:-1]+"\\")
        out("  " + " ".join(c.ConfigureArg) + " )")
        continue
      elif c.NoDefaultConfigureArgs:
        out("  )")
        continue
    # build
    elif line == "  make CFLAGS=\"${MY_CFLAGS}\" )":
      # This CFLAGS override can break builds!
      # e.g. neon 0.24.7, knocks out needed -I flag
      if c.MakeTarget:
        for i in c.MakeTarget[:-1]:
          out("  make %s && \\" % i)
        out("  make %s )" % c.MakeTarget[-1])
        continue
      else:
        out("  make )")
        continue
    # install
    elif line == "  make install DESTDIR=${instdir} && \\":
      if c.MakeInstallTarget:
        for i in c.MakeInstallTarget:
          out("  make %s DESTDIR=${instdir} && \\" % i)
      else:
        out(line)
      if c.InstallExtraCmd:
        for i in c.InstallExtraCmd:
          out("  %s && \\" % i)
      if c.ExtraFile:
        for to_f, from_f in c.ExtraFile.items():
          out("  mkdir -p ${instdir}%s && \\" % (os.path.dirname(to_f)))
          out("  cp ${srcdir}/CYGWIN-PATCHES/%s ${instdir}%s && \\"
              % (from_f, to_f))
      continue
    elif line.find("${prefix}/share/doc/${SHORTPKG} ") != -1:
      if c.AlternateShareDocDir:
        line = line.replace("${prefix}/share/doc/${SHORTPKG} ",
            "${prefix}/share/doc/%s " % c.AlternateShareDocDir)
        out(line)
        continue
    # pkg
    elif line == "  tar cvjf ${bin_pkg} * )":
      if c.SubPackage:
        allitems = []
        for tarball, items in c.SubPackage.items():
          allitems.extend(items)
          out("  tar -cjvf \"${topdir}/%s\" %s && \\"
              % (tarball, " ".join(items)))
        out("  tar --exclude='%s' -cjvf ${bin_pkg} * )"
            % ("' --exclude='".join(allitems)))
        continue
    # mkpatch
    elif line == '  mv ${BASEPKG} ../${BASEPKG}-orig && \\':
      if c.AutoreconfCmd:
        out(line)
        out("  (cd ../${BASEPKG}-orig && \\")
        for cmd in c.AutoreconfCmd[:-1]:
          out("  %s && \\" % cmd)
        out("  %s ) && \\" % c.AutoreconfCmd[-1])
        continue
    elif line == "  diff -urN -x '.build' -x '.inst' -x '.sinst' \\":
      if c.NoDiffNewFiles:
        line = line.replace(' -urN ', ' -ur ')
      if c.DiffExclude:
        out(line)
        out("    -x '" + "' -x '".join(c.DiffExclude) + "' \\")
        continue
    # several (conf, build, check, clean, install)
    elif line == '  (cd ${objdir} && \\':
      if c.BuildInSourceDir:
        out('  (cd ${srcdir} && \\')
        continue
    out(line)

if __name__ == '__main__':
  main()


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]