diff --git a/ChangeLog b/ChangeLog index 792efb0..a94d0db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2005-01-02 Hartmut Goebel + * SConstruct: enhanced for supporting SCons 0.96's 'toolpath' + feature + * scons-tools/filesubst.py: likewise + * scons-tools/sourcetar.py: likewise + * SConstruct: Added traget 'dist' and 'distcheck' for creating and + testing a distribution archive (.tar.gz) + * SConstruct: env.InstallMan() for easy installation of man pages. + * SConstruct: made 'install-*' targets sub-aliases of 'install'; + this allowed some cleaning up in SConscripts. + * SConscript: likewise + * src/SConscript: likewise + * src/capisuite-py/SConscript: likewise + * scripts/SConscript: likewise + * docs/SConscript: changed to use prebuild man pages from SVN + repository. Building from docbook is still to do. + * suse/SConscript: New SConscript for building .spec files. + * suse/capisuite-mdk-9.2.spec.in: Added .spec for Mandrake 9.2 + * SConstruct: Added target 'rpms' for build source and binary RPMs + (currently the .spec file is hardcoded). + * SConstruct: updated tests to status of current ./configure script + * SConstruct-Config: likewise + * Changelog, TODO: Updated + 2004-12-30 Hartmut Goebel * scripts/cs_helpers.pyin: Changed sfftotiff to be defined depending on @sfftobmp_major_version@ during runtime. This diff --git a/SConscript b/SConscript index 7ef4b82..7221cc3 100644 --- a/SConscript +++ b/SConscript @@ -7,11 +7,11 @@ Import('env') cronfile = env.FileSubst('capisuite.cron', 'capisuite.cronin') rcfile = env.FileSubst('rc.capisuite', 'rc.capisuite.in') -env.AddPostAction([cronfile, rcfile], 'chmod gu+x $TARGET') +env.AddPostAction([cronfile, rcfile], Chmod('$TARGETS', 0755)) -Alias('install', - env.Install('$docdir', Split('COPYING NEWS README')), - env.Install('$sysconfdir/init.d/capisuite', rcfile), - env.InstallAs('$sysconfdir/cron.daily/capisuite', cronfile), - env.InstallAs('$pkgsysconfdir/cronjob.conf','cronjob.conf'), - ) +env.Alias('install', [ + env.Install('$docdir', Split('COPYING NEWS README AUTHORS')), + env.InstallAs('$sysconfdir/init.d/capisuite', rcfile), + env.InstallAs('$sysconfdir/cron.daily/capisuite', cronfile), + env.InstallAs('$pkgsysconfdir/cronjob.conf','cronjob.conf'), + ]) diff --git a/SConscript-Config b/SConscript-Config index 0c6a877..91b5c98 100644 --- a/SConscript-Config +++ b/SConscript-Config @@ -105,11 +105,26 @@ def CheckStringClear(context): context.did_show_result = 1 return ret +# capisuite special test +def CheckCapiALERT_REQ(context): + context.Display('Checking for new ALERT_REQ signature in capiutils.h ... ') + text = """ + #include + int main() { + ALERT_REQ (NULL, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); + } + \n""" + ret = context.CompileProg(text, '.cpp') + SCons.Conftest._YesNoResult(context, ret, "HAVE_NEW_CAPI4LINUX", text) + context.did_show_result = 1 + return ret + conf = Configure(env, custom_tests = {'CheckHeadersStdC': CheckHeadersStdC, 'CheckHeaderTime': CheckHeaderTime, 'CheckStringClear': CheckStringClear, + 'CheckCapiALERT_REQ': CheckCapiALERT_REQ, }, conf_dir = '.sconf_temp', # no '#' to build in build-dir log_file = 'config.log' # no '#' to build in build-dir @@ -131,21 +146,24 @@ conf.CheckHeaderTime() ###--- CapiSuite specials ---### +# CS_TEST_GCC3 # new gcc3 feature: we can #include instead of ostream.h -conf.CheckHeader('ostream', language='C++') +conf.CheckHeader('ostream', language='C++') conf.CheckStringClear() # checking for string::clear method +conf.CheckCapiALERT_REQ() # CS_TEST_CAPI4LINUX +# CS_TEST_SFFTOBMP is implemented in SConstruct.Get_sfftobmp_Version +# CS_SET_DOCDIR is implemented in SConscript-Options ###--- libs required by CapiSuite ---### - # checking for capi20_register in -lcapi20... yes if not conf.CheckLib('capi20', 'capi20_register', language='C++'): - print 'libcapi not found - aborting' + print 'libcapi20 not found - aborting' Exit(5) # checking for pthread_create in -lpthread... yes if not conf.CheckLib('pthread', 'pthread_create', language='C++'): - print 'lipthread not found - aborting' + print 'libpthread not found - aborting' Exit(5) # todo diff --git a/SConscript-Options b/SConscript-Options index 0a0d354..c12499d 100644 --- a/SConscript-Options +++ b/SConscript-Options @@ -30,14 +30,18 @@ opts.AddOptions( ('mandir', 'man documentation', '$prefix/man'), # install into another filesystem base - ('INSTALL_BASE', 'base dir for installation (userfull for RPMs)', - '#/dist'), + ('INSTALL_BASE', 'base dir for installation (usefull for RPMs)', '/'), + #('KEEP_CONFIG', 'Do not install config files (usefull for development)', + # 0), - # this is a capisuite-special + # this is a capisuite-special (CS_SET_DOCDIR) ('docdir', 'other documentation', '$datadir/doc/capisuite'), ) Import(['env', '__targets__']) opts.Update(env) Help(opts.GenerateHelpText(env) + __targets__) +if env.has_key('INSTALL_BASE'): + if str(env['INSTALL_BASE']) in ('/', ''): + del env['INSTALL_BASE'] opts.Save('options.cache', env) diff --git a/SConstruct b/SConstruct index 3e7672f..2cf9c83 100644 --- a/SConstruct +++ b/SConstruct @@ -1,10 +1,10 @@ -# -*- python -*- +# -*- mode: python ; coding: latin-1 -*- """ Main SCons build script for CapiSuite (c) Copyright 2004 by Hartmut Goebel -CapiSuite is (c) Copyright by Gernot Hiller +CapiSuite is (c) Copyright by Gernot Hillier Use 'scons --help' for a list of available options. @@ -17,123 +17,122 @@ Example: scons prefix=/ # build for prefix=/ scons # prefix=/ is taken from 'options.cache' scons prefix=/usr/local # build for prefix=/usr/local - # since this is the default, the entry in options.cache - # will be renmoved + # since this is the default, the entry in + # options.cache will be removed scons # default prefix is used -WARNING: This build method is not officially supported for CapiSuite. Please -use the usual configure;make;make install triplet instead! +WARNING: This build method is not yet officially supported for +CapiSuite. Please use the usual 'configure; make; make install' +triplet instead! """ __targets__ = """ Additional targets: configure : build the 'configure' script - (this is automatically done if 'config.h' is missing) + (this is automatically done if 'config.h' is missing) pycheck : check Python sources with PyChecker (not yet implemented) - install : install all files + install : install all files install-pylib : install only the python library install-scripts : install only the python scripts install-exec : install only the executables + install-man : install only the man pages + install-data-local: create spool- and state-dirs + + For all 'install'-targets the installation base may be set with + INSTALL_BASE=... + + dist : build distribution archive (.tar.gz) + distcheck : test whether distribution archive is slef-contained + rpms : build source and binay rpms - For all install-targets base may be set with INSTALL_BASE=... """ +## install-strip: strip the _installed_ binaries +## all == . +## clean == -c: clean all file that could be made by building +## distclean: clean all file that are made by configuring and building +## config.h, .sconf.temp, ... +## uninstall == -c install +## mostlyclean: läßt selten gebaute File stehen +## maintainer-clean: clean + bison-output, info-files, tag tables, etc. +## check: perform self-test +## +## TAGS, info, dvi, +## installcheck, installdirs +###---####---###---####---###---####---###---####---###---####---###---### -# File-Content Substitution will (hopefully ) be part of SCons 0.95 -def _file_subst(target, source, env): - import os, re - import SCons.Util - - def _substitute(matchobj, env=env): - sym = matchobj.group(1) - try: - return env.subst(str(env[sym])) - except: # TypeError: # sym not a string - print 'Not substituting', sym - return matchobj.group(0) # matched - - delim = re.escape(env.get('SUBST_DELIM', '@')) - subst_pattern = re.compile('%s(.*?)%s' % (delim, delim)) - for t, s in zip(target, source): - t = str(t) - s = s.rstr() - text = open(s, 'rb').read() - text = subst_pattern.sub(_substitute, text) - open(t, 'wb').write(text) - os.chmod(t, os.stat(s)[0]) - return None - -def _fs_strfunc(target, source, env): - return "generating '%s' from '%s'" % (target[0], source[0]) - -_fs_builder = Builder(action = Action(_file_subst, strfunction = _fs_strfunc)) - -import sys, os, os.path -import SCons.Util +# some Pythonic setup +import sys, os, os.path, glob +import SCons.Util, SCons.Script import SCons.Node.FS -EnsurePythonVersion(2,2) # capisuite requires this -#EnsureSConsVersion(0,94) - -build_dir = Dir('#/build') +# Store signatures in ".sconsign.dbmlite" in the top-level directory. +SConsignFile() class InstallableEnv(Environment): + """Extended Environment which supports INSTALL_BASE and ExtraDist.""" + def BasedFile(self, name): + if self.get('INSTALL_BASE'): name = ('$INSTALL_BASE/%s' % name) + return self.File(name) + def BasedDir(self, name): + if self.get('INSTALL_BASE'): name = ('$INSTALL_BASE/%s' % name) + return self.Dir(name) + def Install(self, dir, source): """Install specified files in the given directory.""" - if self.has_key('INSTALL_BASE'): - def _Dir(name): - return SCons.Node.FS.Dir(name, parent, self.fs) - parent = self['INSTALL_BASE'] - dir = self.arg2nodes(dir, _Dir) - return Environment.Install(self, dir, source) + dir = self.arg2nodes(dir, self.BasedDir) + files = Environment.Install(self, dir, source) + env.ExtraDist(files) + #self.SourceDist(files) + return files def InstallAs(self, target, source): """Install sources as targets.""" - def _File(name): - return SCons.Node.FS.File(name, dir, self.fs) - - if self.has_key('INSTALL_BASE'): - dir = self['INSTALL_BASE'] - targets = self.arg2nodes(target, _File) - return Environment.InstallAs(self, target, source) + target = self.arg2nodes(target, self.BasedFile) + files = Environment.InstallAs(self, target, source) + self.ExtraDist(files) + return files -env = InstallableEnv() -env.Append( - BUILDERS={'FileSubst' : _fs_builder}, - PACKAGE = 'capisuite', - VERSION = '0.5.cvs', - srcdir = build_dir, + _valid_man_extensions = '0123456789ln' # from info automake - pkgdatadir = '${datadir}/${PACKAGE}', - pkglibdir = '${libdir}/${PACKAGE}', - pkgincludedir = '${includedir}/${PACKAGE}', + def mandir(self, section): + section = str(section) + assert section in self._valid_man_extensions, section # todo: error msg + return os.path.join('$mandir', 'man%s' % section) - pkgbindir = '${bindir}', - pkgsbindir = '${sbindir}', - pkgsysconfdir = '${sysconfdir}/${PACKAGE}', - #pkglibdir = '${prefix}/lib', - spooldir = '${localstatedir}/spool/${PACKAGE}', - docdir = '${pkgdatadir}/doc/${PACKAGE}', - ) -env.SConscript('SConscript-Options', exports=['env', '__targets__']) + def InstallMan(self, source, section=None): + """ + Install man pages. + If 'section' is given, file extensions are changed to 'section'. + Otherwise, the section is taken from file extension. + """ + source = self.arg2nodes(source, self.File) + result = [] + for man in source: + base = os.path.basename(man.name) + base, ext = os.path.splitext(base) + sect = section + if sect is None: + sect = ext[1] # determine section from name/extension + else: + ext = '.%s' % sect # overwrite extension + res = self.InstallAs(os.path.join(self.mandir(sect), base + ext), + man) + result.extend(res) + return result -if env.has_key('INSTALL_BASE'): - env.Replace(INSTALL_BASE=env.Dir('$INSTALL_BASE')) -Export('env') + def ExtraDist(self, files): + """Collect Additional files to be distributed.""" + if SCons.Util.is_List(files): + files = map(File, files) + else: + files = File(files) + env.Append(__SOURCES=files) -env.BuildDir(build_dir=build_dir, src_dir='.') - - -###---####---###---####---###---####---###---####---###---####---###---### -# call configure if required - -# if config.h does not exist, build it using Scons' conftest -if not os.path.exists(str(File('config.h', build_dir))) \ - or 'configure' in COMMAND_LINE_TARGETS: - env.SConscript('SConscript-Config', build_dir=build_dir) - -###---####---###---####---###---####---###---####---###---####---###---### +# +# Support functions for linking with Python +# def GetPythonModuleSetup(env): """ @@ -190,11 +189,129 @@ def GetPythonEmbeddedSetup(env): print ' '.join(python_libspec) #print '>>>', env['LIBS'] -GetPythonModuleSetup(env) -GetPythonEmbeddedSetup(env) +def Get_sfftobmp_Version(context): + """ + Test for the sfftobmp version installed as different versions + need different parameters. :-( + """ + import commands, re + print 'Checking for sfftobmp version ...', + status, text = commands.getstatusoutput('sfftobmp -v') + if status: + print 'failed' + print text + Exit(1) + res = re.search(r'Version ([0-9,.]+)', text, re.M) or 0 + if not res: + print 'failed' + print + print '** It seams like the output of sfftobmp has changed. Please' + print '** contact the authors of capisuite to fix this.' + Exit(10) + res = res.group(1) + env.Replace(sfftobmp_major_version = res.split('.')[0]) + print res + + +# A Shortcut +is_dist = ('dist' in COMMAND_LINE_TARGETS or + 'distcheck' in COMMAND_LINE_TARGETS) + +###---####---###---####---###---####---###---####---###---####---###---### + +# capisuite requires Python 2.2 +EnsurePythonVersion(2,2) +if is_dist: + # 'dist' target requires module tarfile which is new in Python 2.3 + EnsurePythonVersion(2,3) +EnsureSConsVersion(0,96) + +###---####---###---####---###---####---###---####---###---####---###---### +# +# Setting up build-environment +# + +# Build all files in this subdir +build_dir = Dir('#/build') + +env = InstallableEnv(tools=Split('default sourcetar filesubst'), + toolpath=['scons-tools'], + + # set some build variables + PACKAGE = 'capisuite', + VERSION = '0.5.cvs', + RELEASE = '1', + + # required for some building the docs (doxygen) + srcdir = build_dir, + + # default pathes + pkgdatadir = '${datadir}/${PACKAGE}', + pkglibdir = '${libdir}/${PACKAGE}', + pkgincludedir = '${includedir}/${PACKAGE}', + pkgbindir = '${bindir}', + pkgsbindir = '${sbindir}', + pkgsysconfdir = '${sysconfdir}/${PACKAGE}', + #pkglibdir = '${prefix}/lib', + spooldir = '${localstatedir}/spool/${PACKAGE}', + docdir = '${pkgdatadir}/doc/${PACKAGE}', + + # required for ExtraDist + __SOURCES = [], + + # used for distcheck + SCONS = 'scons', + DISTCHECK_DIR = Dir('#/dist/check'), + ) + +###---####---###---####---###---####---###---####---###---####---###---### +# +# Handling of command line options +# + +# Some commonly used make targets have to be done another way. +# Inform the used if he tries to use such a target: +for ct, t in ( + ('clean', '-c'), + ('uninstall', '-c install'), + ('distclean', '-c dist'), + ): + if ct in COMMAND_LINE_TARGETS: + print + print "Please use 'scons %s' instead of the pseudo-target '%s'." \ + % (t, ct) + print + Exit(1) + +# Handle options +env.SConscript('SConscript-Options', exports=['env', '__targets__']) + +### Some more setup +env.BuildDir(build_dir=build_dir, src_dir='.') + +Export('env', 'is_dist') + +###---####---###---####---###---####---###---####---###---####---###---### +# +# Configure build (only if neither cleaning nor 'dist'-ing) +# +if not GetOption('clean') and not is_dist: + # "configure" only if necessary or requested + if not File('config.h', build_dir).exists() \ + or 'configure' in COMMAND_LINE_TARGETS: + env.SConscript('SConscript-Config')#, build_dir=build_dir) + + # get some build variables we always need to evaluate + GetPythonModuleSetup(env) + GetPythonEmbeddedSetup(env) + Get_sfftobmp_Version(env) + +###---####---###---####---###---####---###---####---###---####---###---### env.Append( CCFLAGS = Split('-g -O2'), + + # these should go into src/SConscript: LIBS = Split('pthread capi20'), CPPDEFINES={'LOCALSTATEDIR': r'\"${localstatedir}\"', 'PKGDATADIR' : r'\"${pkgdatadir}\"', @@ -212,24 +329,72 @@ env.Append( ## if env['CXX'] in ('g++', 'c++'): ## env.Append(CXXFLAGS = ['-Wall', '-Wno-non-virtual-dtor']) - ###---####---###---####---###---####---###---####---###---####---###---### - -# snippet for unittest -#mytest = env.program(...) -#Alias( 'unittest', mytest ) -#Alias( 'all', 'unittest' ) -#unittetsInstall = env.Install(...) -#Alias('unittest', unitteststInstall) - -# now build the subdirectories' stuff +# +# Build everything defined in the 'Sconscript' files. +# env.SConscript(dirs=[Dir('.', build_dir), Dir('src', build_dir), Dir('scripts', build_dir), Dir('scripts/waves', build_dir), Dir('docs', build_dir), + Dir('suse'), ]) +#--- additional files to be distributed --- +env.ExtraDist(Split(""" + ChangeLog TODO + SConstruct + SConscript-Config + SConscript-Options + scons-tools/sourcetar.py + scons-tools/filesubst.py + scons-tools/textfile.py + + SConscript + src/SConscript + scripts/SConscript + scripts/waves/SConscript + suse/SConscript + docs/SConscript + """)) + + +#--- additional files to be distributed (automake/autoconf stuff) --- +# only add these files if they exist +for f in Split(""" + INSTALL + acinclude.m4 + aclocal.m4 + config.h.in + configure + configure.in + depcomp + install-sh + missing + mkinstalldirs + Makefile.am + Makefile.in + docs/Makefile.am + docs/Makefile.in + scripts/Makefile.am + scripts/Makefile.in + scripts/waves/Makefile.am + scripts/waves/Makefile.in + src/Makefile.am + src/Makefile.in + src/application/Makefile.am + src/application/Makefile.in + src/backend/Makefile.am + src/backend/Makefile.in + src/capisuite-py/Makefile.am + src/capisuite-py/Makefile.in + src/modules/Makefile.am + src/modules/Makefile.in + """): + if os.path.exists(f): + env.ExtraDist(f) + #env.SourceCode('.', # env.CVS('pserver:anonymous@cvs.capisuite.berlios.de:/cvsroot/capisuite', # 'capisuite')) @@ -240,10 +405,73 @@ mkdir -p $RPM_BUILD_ROOT/usr/sbin ln -sf ../../etc/init.d/capisuite $RPM_BUILD_ROOT/usr/sbin/rccapisuite """ -#EXTRA_DIST = rc.capisuite.in capisuite.cronin cronjob.conf -#install-data-local: -# mkdir -p $(DESTDIR)$(localstatedir)/log -# $(mkinstalldirs) $(DESTDIR)$(spooldir)/sendq -# $(mkinstalldirs) $(DESTDIR)$(spooldir)/done -# $(mkinstalldirs) $(DESTDIR)$(spooldir)/failed -# $(mkinstalldirs) $(DESTDIR)$(spooldir)/users + +###---####---###---####---###---####---###---####---###---####---###---### +# +# Install targets +# + +for d in ( + '${DESTDIR}${localstatedir}/log', + '${DESTDIR}${spooldir}/sendq', + '${DESTDIR}${spooldir}/done', + '${DESTDIR}${spooldir}/failed', + '${DESTDIR}${spooldir}/users', + ): + if not os.path.exists(env.subst(d)): + d = env.Command(env.BasedDir(d), None, Mkdir('$TARGET')) + env.Alias('install-data-local', d) + +# 'install' includes the other parts, too +env.Alias('install', env.Alias('install-pylib')) +env.Alias('install', env.Alias('install-scripts')) +env.Alias('install', env.Alias('install-exec')) +env.Alias('install', env.Alias('install-data-local')) +env.Alias('install', env.Alias('install-man')) + +###---####---###---####---###---####---###---####---###---####---###---### +# +# 'Dist' target +# +if is_dist or 'rpms' in COMMAND_LINE_TARGETS: + dist = env.DistTar('#/dist/${PACKAGE}-${VERSION}.tar.gz', env['__SOURCES'], + TARFLAGS='-c -z')[0] + +###---####---###---####---###---####---###---####---###---####---###---### +# +# 'Dist' target +# +if 'distcheck' in COMMAND_LINE_TARGETS: + distcheck = env.Command('distcheck', + env.Dir('$DISTCHECK_DIR/${PACKAGE}-${VERSION}'), + [Delete('$SOURCE'), + Mkdir('$SOURCE'), + '$TAR xz -C ${SOURCE.dir} -f ' + dist.abspath, + '$SCONS -C $SOURCE .', + '$SCONS -C $SOURCE dist', + 'echo ; echo checkdist passed ; echo' + ]) + env.Clean(distcheck, env['DISTCHECK_DIR']) + env.Depends(distcheck, dist) + +###---####---###---####---###---####---###---####---###---####---###---### +# +# 'rpm' target +# +if 'rpms' in COMMAND_LINE_TARGETS: + _builddir = build_dir + _distdir = dist.dir + _arch = 'i586' + _rpmbasename = env.subst('capisuite-$VERSION-$RELEASE') + env.Alias('rpms', + env.Command([File('%s.%s.rpm' % (_rpmbasename, _arch), _distdir), + File('%s.%s.rpm' % (_rpmbasename, 'src'), _distdir)], + ['suse/capisuite-mdk-9.2.spec', dist], [ \ + ['rpmbuild', + '--define', '_builddir %s' % _builddir.abspath, + '--define', '_sourcedir %s' % _distdir.abspath, + '--define', '_srcrpmdir %s' % _distdir.abspath, + '--define', '_rpmdir %s' % _distdir.abspath, + '--define', '_rpmfilename $TARGET.name', + '-ba', '$SOURCE'], + ])) diff --git a/TODO b/TODO index 7cf42aa..79e3c77 100644 --- a/TODO +++ b/TODO @@ -10,6 +10,10 @@ Important for 0.5.0/capisuite-py: * Add option '--is-configured' to capisuite-checkconfig to be used by rc-file. +Build: +* Determine the path of the stylsheets automatically. These are + currently hardcoded for Suse Linux. + NICE: - more checks/options for capisuite-checkconfig - ?valgrind-clean the used libs and Python? diff --git a/docs/SConscript b/docs/SConscript index 65156d9..627e584 100644 --- a/docs/SConscript +++ b/docs/SConscript @@ -1,18 +1,24 @@ # -*- python -*- -Import('env') -#EXTRA_DIST = Doxyfile.in mainpage.doxy manual.docbook manual.README - - -## dist-hook: manual-html manual-pdf reference-html -## mkdir $(distdir)/manual -## cp -r $(srcdir)/manual/* $(distdir)/manual/ -## mkdir $(distdir)/reference -## cp $(srcdir)/reference/* $(distdir)/reference/ -## cp manual.pdf $(distdir)/ +Import('env', 'is_dist') import re +#---- man pages ----------- +env.Alias('install-man', + env.InstallMan(Split('capisuite.8 capisuite.conf.5 fax.conf.5 ' + 'answering_machine.conf.5 capisuitefax.1'))) + +env.ExtraDist(Split('Doxyfile.in mainpage.doxy manual.docbook ' + 'manual-de.docbook manual.README')) + + +# todo: +# - find stylesheet dir (how?) +# - build manpages from manual.docbook +# - build pdf-manual from manual.docbook +# - build html-manual from manual.docbook + def patch_version(target, source, env): """ Change version contained in the tag. @@ -24,43 +30,69 @@ def patch_version(target, source, env): text) open(source[0].abspath, 'w').write(text) - env.Append(docbuilddir=Dir('.')) manualdir = Dir('manual') -stylesheetdir = Dir('/usr/share/sgml/docbook/xsl-stylesheets') +#stylesheetdir = Dir('/usr/share/sgml/docbook/xsl-stylesheets') + +stylesheetdir = Dir('/usr/share/xml/docbook/stylesheet/nwalsh/current/') +profile_xsl = File("profiling/profile.xsl", stylesheetdir) +docbook_xsl = File("manpages/docbook.xsl", stylesheetdir) #images = Install(Dir('images', manualdir), images) +""" # create HTML manual -manual_html = env.Command(File('index.html', manualdir), - 'manual.docbook', [ +manual_html = env.Command('manual/index.html', 'manual.docbook', [ patch_version, - ['xmllint', '--noout', '--valid', '$SOURCE'], + 'xmllint --noout --valid $SOURCE', ['xsltproc', '-o', '${TARGET.dir}/', - File('xhtml/chunk.xsl', stylesheetdir), '$SOURCE'] - ]) -#env.Depends(manual_html, images) - -# copy missing images -env.AddPostAction(manual_html, [ \ - ['rm', '-fr', Dir('images', manualdir)], - ['cp', '-r', Dir('images', stylesheetdir), Dir(manualdir)] + File('xhtml/chunk.xsl', stylesheetdir), '$SOURCE'], + Delete('${TARGET.dir}/images'), + Copy('${TARGET.dir}/images', Dir('images', stylesheetdir).abspath), ]) # create PDF manual -manual_pdf = env.Command('manual.pdf', 'manual.docbook', - 'db2pdf -o ${TARGET.dir} $SOURCE' - ) +db_xml = env.Command('manual.xml', 'manual.docbook', + 'xsltproc --stringparam profile.condition pdf ' + '-o $TARGET $profile_xsl $SOURCE') +manual_pdf = env.Command('manual.pdf', db_xml, + ['db2pdf -o ${TARGET.dir} $SOURCE', + #Delete(Split('CATALOG.local manual.aux manual.log ' + # 'manual.out manual.tex suse-*.dsl ' + # 'manual.xml') + ]) # substitute version, capisuite_sources, srcdir doxyfile = env.FileSubst('Doxyfile', 'Doxyfile.in') -ref_html = env.Command('reference/index.html', doxyfile, [ \ - ['doxygen', doxyfile] - ]) +reference_html = env.Command('reference/index.html', doxyfile, [ + Delete('${TARGET.dir}'), + ['doxygen', doxyfile] + ]) -Alias('install', - env.Install('$docdir', manual_pdf), - #env.Install('$docdir', 'manual'), - #env.Install('$docdir', 'reference'), - ) + +#--- build man pages ------------------ +db4man = env.Command('manual-4man.docbook', 'manual.docbook', + 'xsltproc --stringparam profile.condition man ' + '-o $TARGET $profile_xsl $SOURCE') +manpages = env.Command(Split('capisuite.8 capisuite.conf.5 fax.conf.5 ' + 'answering_machine.conf.5 capisuitefax.1'), + db4man, + 'xsltproc $docbook4man_xsl $SOURCE') + +#--- install --- + +for i in (env.Install('$docdir', manual_pdf), + #env.Install('$docdir', manual_html), + #env.Install('$docdir', reference_html), + ): + env.Alias('install', i) + + +#--- dist --- + +## for t, s in ((env.Dir('${DISTDIR}/manual'), manual_html), +## (env.Dir('${DISTDIR}/reference'), reference_html), +## ('${DISTDIR}/manual.pdf', manual_pdf)): +## env.Command(t, s, Copy('$TARGET', '$SOURCE')) +""" diff --git a/scons-tools/filesubst.py b/scons-tools/filesubst.py new file mode 100644 index 0000000..40528a3 --- /dev/null +++ b/scons-tools/filesubst.py @@ -0,0 +1,47 @@ +# -*- python -*- +""" +File-Content Substitution builder for SCons +""" + +__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>" + +import os, re +import SCons + +def _action(target, source, env): + + def _substitute(matchobj, env=env): + sym = matchobj.group(1) + try: + return env.subst(str(env[sym])) + except: # TypeError: # sym not a string + txt = matchobj.group(0) # the string matched + print 'Not substituting', txt + return txt + + delim = re.escape(env['FILESUBSTDELIM']) + # compile a non-greedy pattern + subst_pattern = re.compile('%s(.*?)%s' % (delim, delim)) + for t, s in zip(target, source): + t = str(t) + s = s.rstr() + text = open(s, 'rb').read() + text = subst_pattern.sub(_substitute, text) + open(t, 'wb').write(text) + os.chmod(t, os.stat(s)[0]) + return None + +def _strfunc(target, source, env): + return "generating '%s' from '%s'" % (target[0], source[0]) + +_builder = SCons.Builder.Builder( + action = SCons.Action.Action(_action, _strfunc), + src_suffix = '.in', + ) + +def generate(env): + env['BUILDERS']['FileSubst'] = _builder + env['FILESUBSTDELIM'] = '@' + +def exists(env): + return 1 diff --git a/scons-tools/sourcetar.py b/scons-tools/sourcetar.py new file mode 100644 index 0000000..5cc6d2f --- /dev/null +++ b/scons-tools/sourcetar.py @@ -0,0 +1,62 @@ +# -*- python -*- +""" +SCons builder for creating source tars. +""" + +import SCons +from SCons.Node.FS import Base + +def _e_dist(target, source, env): + + def collect_sources(sources, collected, done, dbg=''): + for s in sources: + if s in done.keys(): continue + done[s] = None + if not s.is_derived(): # this node is not built (nor side-effect) + #assert not s.all_children() + if isinstance(s, Base) and s.is_under(env.fs.Dir('#')): + #print s + collected[s] = None + else: + collect_sources(s.all_children(scan=1), collected,done) + return collected + + def cmp_path(a, b): + return cmp(a.get_path(), b.get_path()) + + collected = collect_sources(source, {}, {}) + collected = [ c.srcnode() for c in collected.keys() ] + collected.sort(cmp_path) + return (target, collected) + +def DistTar(target, source, env): + import tarfile + tar = tarfile.open(str(target[0]), "w:gz") + for name in source: + name = str(name) + tar.add(name, env.subst('${PACKAGE}-${VERSION}/') + name) + tar.close() + +def _str_DistTar(target, source, env): + return env.subst('tar czf $TARGET $SOURCES') + +_builder = SCons.Builder.Builder( + action="$TARCOM", + emitter = _e_dist, + multi = 1, + ) + +_builder_dist = SCons.Builder.Builder( + action=SCons.Action.Action(DistTar,strfunction=_str_DistTar), + emitter = _e_dist, + multi = 0, + + ) + +def generate(env): + env['BUILDERS']['SourceTar'] = _builder + env['BUILDERS']['DistTar'] = _builder_dist + +def exists(env): + import SCons.Tools.tar + return SCons.Tools.tar.exists(env) diff --git a/scripts/Makefile.in b/scripts/Makefile.in index cc0f403..c0baec0 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -557,13 +557,7 @@ capisuitefax: capisuitefax.in .pyin.py: rm -f $@ - if test $(sfftobmp_major_version) = "2"; then \ - sed -e 's,@\pkgsysconfdir@,$(pkgsysconfdir),g' \ - -e 's,#2 ,,g' $< >$@ ;\ - else \ - sed -e 's,@\pkgsysconfdir@,$(pkgsysconfdir),g' \ - -e 's,#3 ,,g' $< >$@ ;\ - fi + sed 's,@sfftobmp_major_version@,$(sfftobmp_major_version),g' $< >$@ .confin.conf: rm -f $@ diff --git a/scripts/SConscript b/scripts/SConscript index 77b9576..00762fc 100644 --- a/scripts/SConscript +++ b/scripts/SConscript @@ -12,13 +12,13 @@ def py_compile(target, source, env): env.subst('$SOURCE.file')), ) -# these ar meant to be used by users +# these are meant to be used by users user_scripts = [env.FileSubst('capisuitefax', 'capisuitefax.in'),] -env.AddPostAction(user_scripts, 'chmod 755 $TARGETS') +env.AddPostAction(user_scripts, Chmod('$TARGETS', 0755)) # these are meant to be used by the admin sbin_scripts = [File('capisuite-checkconfig'),] -#env.AddPostAction(sbin_scripts, 'chmod 755 $TARGETS') +#env.AddPostAction(sbin_scripts, Chmod('$TARGETS', 0755)) # config files configs = [ @@ -26,8 +26,7 @@ configs = [ env.FileSubst('answering_machine.conf', 'answering_machine.confin') ] -# this is no longer needed -# todo: check cs_helper.py into cvs instead of cs_helper.pyin +# file subst. is required because of sfftobmp_major_version env.FileSubst('cs_helpers.py', 'cs_helpers.pyin') pymodules = [] @@ -37,17 +36,20 @@ for mod in Split('cs_helpers'): #--- install --- -install_pylib = env.Install('$python_moduledir', pymodules) -Alias('install-pylib',install_pylib) +env.Alias('install-pylib', env.Install('$python_moduledir', pymodules)) -for i in [env.Install('$pkgbindir', user_scripts), - env.Install('$pkgsbindir', sbin_scripts), - env.Install('$pkglibdir', Split('idle.py incoming.py'))]: - Alias('install-scripts', i) - Alias('install', i) - -Alias('install', - env.Install('$python_moduledir', pymodules), - env.Install('$pkgsysconfdir', configs), - env.Install('$pkglibdir', 'README'), - ) +for i in ( + env.Install('$pkgbindir', user_scripts), + env.Install('$pkgsbindir', sbin_scripts), + env.Install('$pkglibdir', Split('idle.py incoming.py')) + ): + env.Alias('install-scripts', i) + +for i in ( + env.Install('$python_moduledir', pymodules), + env.Install('$pkgsysconfdir', configs), + env.Install('$pkglibdir', 'README'), + ): + env.Alias('install', i) + # this also includes 'install-pylib' and 'install-scripts' + # (set in #/SConstruct) diff --git a/scripts/waves/SConscript b/scripts/waves/SConscript index 0d974c1..309544c 100644 --- a/scripts/waves/SConscript +++ b/scripts/waves/SConscript @@ -7,8 +7,9 @@ def findFiles(pattern, subdir=''): files = [] for file in os.listdir(os.path.join(Dir('.').srcnode().abspath, subdir)): if fnmatch.fnmatch(file, pattern): - files.append(os.path.join(subdir, file)) + files.append(File(os.path.join(subdir, file), Dir('.'))) return files - -Alias('install', env.Install('$pkgdatadir/waves', 'README' )) -Alias('install', env.Install('$pkgdatadir/waves', findFiles('*.la'))) + +for n in (env.Install('$pkgdatadir/waves', 'README' ), + env.Install('$pkgdatadir/waves', findFiles('*.la'))): + env.Alias('install', n) diff --git a/src/SConscript b/src/SConscript index 58f8d46..a54da0a 100644 --- a/src/SConscript +++ b/src/SConscript @@ -8,16 +8,19 @@ libmodule = SConscript('modules/SConscript') libappl = SConscript('application/SConscript') libback = SConscript('backend/SConscript') +env.ExtraDist(Split(""" + capisuite-py/SConscript + modules/SConscript + application/SConscript + backend/SConscript + """)) + capisuite = env.Program('capisuite', - ['main.cpp', libappl, libmodule, libback, ]) -env.AddPostAction(capisuite, 'strip $TARGET') + ['main.cpp', libappl, libmodule, libback]) +#env.AddPostAction(capisuite, 'strip $TARGET') capisuite_conf = env.FileSubst('capisuite.conf', 'capisuite.conf.in') -install_exec = env.Install('$sbindir', capisuite) -Alias('install-exec', install_exec) - -Alias('install', - env.Install('$pkgsysconfdir', capisuite_conf), - install_exec, - ) +# -- install -- +env.Alias('install-exec', env.Install('$sbindir', capisuite)) +env.Alias('install', env.Install('$pkgsysconfdir', capisuite_conf)) diff --git a/src/capisuite-py/SConscript b/src/capisuite-py/SConscript index 7d5f14a..b81e68b 100644 --- a/src/capisuite-py/SConscript +++ b/src/capisuite-py/SConscript @@ -14,14 +14,11 @@ def py_compile(target, source, env): # substitute "pgksysconfdir" env.FileSubst('config.py', 'config.py.in') - + modules = [] for mod in Split('__init__ config consts fax fileutils voice exceptions ' 'core'): modules.append(mod+'.py') modules.append(env.Command(mod + '.pyc', mod+'.py', py_compile)) -install_pylib = env.Install('$pkgpython_moduledir', modules) - -Alias('install-pylib',install_pylib) -Alias('install', install_pylib) +env.Alias('install-pylib', env.Install('$pkgpython_moduledir', modules)) diff --git a/suse/SConscript b/suse/SConscript new file mode 100644 index 0000000..729ba18 --- /dev/null +++ b/suse/SConscript @@ -0,0 +1,11 @@ +# -*- python -*- + +Import('env') + +specs = [] +for f in Split('capisuite-mdk-9.2.spec'): + #env.ExtraDist(File(f, Dir('.'))) + env.ExtraDist(f) + specs.append(env.FileSubst(f, '%s.in' % f)) + +#env.ExtraDist(specs) diff --git a/suse/capisuite-mdk-9.2.spec.in b/suse/capisuite-mdk-9.2.spec.in new file mode 100644 index 0000000..3f23d48 --- /dev/null +++ b/suse/capisuite-mdk-9.2.spec.in @@ -0,0 +1,197 @@ +# +# spec file for package capisuite +# +# Copyright (c) 2003 Gernot Hillier <gernot@hillier.de> +# Copyright (c) 2004 Hartmut Goebel <h.goebel@crazy-compilers.com> +# +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# + +Name: capisuite +License: GPL +Group: Communications/ISDN +Version: @VERSION@ +Release: @RELEASE@ +Requires: python>=2.2 sox>=12.17.3 sfftobmp libtiff3-progs ghostscript +#Requires: libisdn4k-utils2-devel libpython2.3-devel +Requires: jpeg2ps +Summary: ISDN telecommunication suite providing fax and voice services +Source0: %{name}-%{version}.tar.gz +URL: http://www.capisuite.de/ +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%description +CapiSuite is an ISDN telecommunication suite providing easy to use +telecommunication functions which can be controlled from Python +scripts. + +It uses a CAPI-compatible driver for accessing the ISDN-hardware, so +you'll need an AVM card with the according driver. + +CapiSuite is distributed with two example scripts for call incoming +handling and fax sending. See /usr/share/doc/capisuite-%{version} for +further information. + +Authors: +-------- + Gernot Hillier + Hartmut Goebel + +%prep +%setup +#./configure --localstatedir=/var --with-docdir=/usr/share/doc/%{name}-%{version} +#--prefix=%{_prefix} --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} --datadir=%{_datadir} --includedir=%{_includedir} --libdir=%{_libdir} --libexecdir=%{_libexecdir} --localstatedir=%{_var} --mandir=%{_mandir} +scons prefix=%{_prefix} \ + exec-prefix=%{_exec_prefix} \ + bindir=%{_bindir} \ + sbindir=%{_sbindir} \ + sysconfdir=%{_sysconfdir} \ + datadir=%{_datadir} \ + includedir=%{_includedir} \ + libdir=%{_libdir} \ + libexecdir=%{_libexecdir} \ + localstatedir=%{_var} \ + sharedstatedir=%{_sharedstatedir} \ + mandir=%{_mandir} \ + infodir=%{_infodir} \ + docdir=/usr/share/doc/%{name}-%{version} configure + +%build +scons +#make +#strip src/capisuite + +%install +scons INSTALL_BASE=$RPM_BUILD_ROOT install +builddir=build/ +#make DESTDIR=$RPM_BUILD_ROOT install +install -Dm 644 cronjob.conf $RPM_BUILD_ROOT%{_sysconfdir}/capisuite/cronjob.conf +mkdir -p $RPM_BUILD_ROOT%{_initrddir} +mv $RPM_BUILD_ROOT%{_sysconfdir}/init.d/capisuite \ + $RPM_BUILD_ROOT%{_initrddir}/capisuite +install -Dm 755 ${builddir}capisuite.cron $RPM_BUILD_ROOT%{_sysconfdir}/cron.daily/capisuite +gzip --recursive --best $RPM_BUILD_ROOT%{_mandir} + +%clean +#rm -rf $RPM_BUILD_ROOT + +%post +%_post_service capisuite + +%preun +%_preun_service capisuite + +%files +%defattr(-,root,root) +%config(noreplace) %{_sysconfdir}/capisuite/cronjob.conf +%config(noreplace) %{_sysconfdir}/capisuite/capisuite.conf +%config(noreplace) %{_sysconfdir}/capisuite/fax.conf +%config(noreplace) %{_sysconfdir}/capisuite/answering_machine.conf +#__RPM_FILES__ +%{_sbindir}/capisuite +%{_sbindir}/capisuite-checkconfig +%{_bindir}/capisuitefax +%doc %{_defaultdocdir}/%name-%version +%doc %{_mandir}/*/* +%{_datadir}/capisuite +%{_libdir}/capisuite +%dir %{_var}/spool/capisuite +%{_var}/spool/capisuite/* +%{_libexecdir}/python2.?/site-packages/cs_helpers.py* +%dir %{_libexecdir}/python2.?/site-packages/capisuite +%{_libexecdir}/python2.?/site-packages/capisuite/* +%{_initrddir}/capisuite +%{_sysconfdir}/cron.daily/capisuite + +%changelog -n capisuite +* Sun Jun 12 2004 Hartmut Goebel <h.goebel@crazy-compilers.com> +- updated for capisuite-pylib +- changed to use SCons build system + +* Sun Nov 09 2003 Steffen Barszus <steffen@mandrakeuser.de> +- initial spec for mdk, taken mostly the SuSE spec of gernot + +* Sun Jul 20 2003 - gernot@hillier.de +- updated to 0.4.3 + +* Sun Apr 27 2003 - gernot@hillier.de +- updated to 0.4.2 + +* Sat Apr 05 2003 - gernot@hillier.de +- updated to 0.4.1a (SECURITY FIX for cronjob, ...) + +* Thu Mar 20 2003 - ghillie@suse.de +- updated to 0.4.1, thrown away all patches which are already + included in this release + +* Thu Mar 13 2003 - ghillie@suse.de +- SECURITY FIX: permissions of saved documents and waves are 0600 + now instead of 0644 and dirs have 0700 instead of 0755. This + fixes critical bug #25242. Bug severity was approved by kkeil. + +* Mon Mar 10 2003 - ghillie@suse.de +- added current documentation as .tar.bz2 to avoid change of + Makefile so late (old Makefiles won't install new docs correctly) + +* Mon Mar 03 2003 - ghillie@suse.de +- added capisuite-faxid.diff: fixes sending of fax station ID, fax + headline works now + +* Sun Feb 23 2003 - ghillie@suse.de +- added capisuite-cron.diff: cron-script errors to /dev/null + +* Fri Feb 21 2003 - ghillie@suse.de +- capisuite-removesetuid.diff: fixes Bugzilla 23732 (freeze because + of usage of setuid() which isn't allowed in threads) +- capisuite-cosmetical.diff: cosmetical fixes (examples in conf files + were wrong, removed debug output) +- added tiff & ghostscript-library to Requires: fixes Bug 23962 + +* Tue Feb 18 2003 - ghillie@suse.de +- fixed Bugzilla 23731 (lock files weren't deleted in idle.py) + +* Mon Feb 17 2003 - ghillie@suse.de +- updated to 0.4 (new/old messages in remote inquiry, capisuitefax + can show sendqueue and abort jobs) + +* Tue Feb 11 2003 - ghillie@suse.de +- included cron job for cleaning up +- rc.capisuite was moved into tar ball + +* Mon Feb 10 2003 - ghillie@suse.de +- updated to 0.3.2 (got rid of CommonC++, using native pthreads now, + fixed some major bugs) + +* Mon Feb 03 2003 - ghillie@suse.de +- updated to 0.3.1: (bugfixes, use different sendqueue for each user, + script improvements, e.g. sayNumber supports 0-99 well now) + +* Wed Jan 29 2003 - ghillie@suse.de +- added sox to Require: + +* Wed Jan 29 2003 - ghillie@suse.de +- don't start if no user configured for default scripts +- added insserv to %%post (spec file) + +* Mon Jan 27 2003 - ghillie@suse.de +- included startup script + +* Mon Jan 27 2003 - ghillie@suse.de +- updated to 0.3 (split configuration files into fax and + answering machine config) + +* Thu Jan 23 2003 - ghillie@suse.de +- updated to 0.2.1 (mainly documentation improvements, has an own + manual now) + +* Mon Jan 20 2003 - ghillie@suse.de +- updated to 0.2 (see included NEWS for changes) +- added correct docdir to configure call in specfile + +* Mon Dec 16 2002 - gernot@hillier.de +- first package + +* Mon Dec 16 2002 - gernot@hillier.de +- fixed 2 small bugs (physical disconnect was missing in some cases, + file delete in remote inquiry didn't work)