3 import sys, glob, os.path, datetime, pwd, time, fnmatch
4 sys.path.append('senfscons')
7 ###########################################################################
9 # This hack is needed for SCons V 0.96.1 compatibility. In current SCons versions
10 # we can just use 'env.AlwaysBuild(env.Alias(target), [], action)'
11 def PhonyTarget(env, target, action):
12 env.AlwaysBuild(env.Command(target + '.phony', 'SConstruct', env.Action(action)))
13 env.Alias(target, target + '.phony')
15 def updateRevision(target, source, env):
16 rev = env['ENV']['REVISION'][1:]
19 print "Working copy not clean. Run 'svn update'"
22 if 'm' in rev and not ARGUMENTS.get('force_deb'):
24 print "Working copy contains local changes. Commit first"
31 changelog = file('debian/changelog.template').read() % {
33 'user': pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0].strip(),
34 'date': time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) }
35 file('debian/changelog','w').write(changelog)
38 try: return os.stat(f).st_size > 0
39 except OSError: return False
41 def checkLocalConf(target, source, env):
42 if [ True for f in env['CONFIG_FILES'] if nonemptyFile(f) ]:
44 print "You have made local modifications to 'SConfig' and/or 'Doxyfile.local'."
45 print "Building a debian package would remove those files."
47 print "To continue, remove the offending file(s) and try again. Alternatively,"
48 print "build a source package using 'scons debsrc' and may then build debian"
49 print "binary packages from this source-package without disrupting your print local"
50 print "configuration."
54 ###########################################################################
55 # Load utilities and setup libraries and configure build
58 SENFSCons.UseSTLPort()
59 env = SENFSCons.MakeEnvironment()
62 Additional top-level build targets:
64 prepare Create all source files not part of the repository
65 all_tests Build and run unit tests for all modules
66 all_docs Build documentation for all modules
68 install_all Install SENF into $PREFIX
69 deb Build debian source and binary package
70 debsrc Build debian source package
71 debbin Build debian binary package
72 linklint Check links of doxygen documentation with 'linklint'
75 if os.environ.get('debian_build'):
76 rev = os.popen("dpkg-parsechangelog | awk '/^Version:/{print $2}'").read().strip()
78 rev = 'r' + os.popen("svnversion").read().strip().lower()
80 logname = os.environ.get('LOGNAME')
82 logname = pwd.getpwuid(os.getuid()).pw_name
84 def configFilesOpts(target, source, env, for_signature):
85 return [ '-I%s' % os.path.split(f)[1] for f in env['CONFIG_FILES'] ]
88 CPPPATH = [ '#/include' ],
89 LIBS = [ 'iberty', '$BOOSTREGEXLIB' ],
90 DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
91 DOXY_HTML_XSL = '#/doclib/html-munge.xsl',
92 ENV = { 'TODAY' : str(datetime.date.today()),
94 'LOGNAME' : logname, # needed by the debian build scripts
95 'CONCURRENCY_LEVEL' : env.GetOption('num_jobs') or "1",
98 CONFIG_FILES = [ 'Doxyfile.local', 'SConfig', 'local_config.hh' ],
99 CONFIG_FILES_OPTS = configFilesOpts,
100 CLEAN_PATTERNS = [ '*.pyc', 'semantic.cache', '.sconsign', '.sconsign.dblite' ],
101 BUILDPACKAGE_COMMAND = "dpkg-buildpackage -us -uc -rfakeroot -I.svn $CONFIG_FILES_OPTS",
102 TOP_INCLUDES = [ 'Packets', 'PPI', 'Scheduler', 'Socket', 'Utils',
103 'config.hh', 'local_config.hh' ]
108 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
109 if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
110 Execute(Touch("Doxyfile.local"))
112 # Create local_config.h
113 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
114 Execute(Touch("local_config.hh"))
116 ###########################################################################
117 # Define build targets
119 # Before defining any targets, check wether this is the first build in
120 # pristine directory tree. If so, call 'scons prepare' so the dependencies
121 # created later are correct
123 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
124 and not os.environ.get("SCONS"):
125 env.Execute([ "scons prepare" ])
127 env.Clean('all', '.prepare-stamp')
129 SConscript(glob.glob("*/SConscript"))
131 SENFSCons.StandardTargets(env)
132 SENFSCons.GlobalTargets(env)
133 SENFSCons.Doxygen(env)
134 SENFSCons.DoxyXRef(env,
135 HTML_HEADER = '#/doclib/doxy-header-overview.html',
136 HTML_FOOTER = '#/doclib/doxy-footer.html')
138 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
140 # Build combined library 'libsenf'
141 libsenf = env.Library(
142 SENFSCons.LibPath('senf'),
143 Flatten([ env.File(SENFSCons.LibPath(lib)).sources for lib in env['ALLLIBS'] ]))
145 env.Clean('all', 'libsenf.a')
146 env.Alias('default', 'libsenf.a')
148 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
150 env.Clean('all', [ os.path.join(path,f)
151 for path, subdirs, files in os.walk('.')
152 for pattern in env['CLEAN_PATTERNS']
153 for f in fnmatch.filter(files,pattern) ])
155 PhonyTarget(env, 'deb', [
158 "$BUILDPACKAGE_COMMAND",
161 PhonyTarget(env, 'debsrc', [
163 "$BUILDPACKAGE_COMMAND -S",
166 PhonyTarget(env, 'debbin', [
169 "$BUILDPACKAGE_COMMAND -nc",
172 PhonyTarget(env, 'linklint', [
174 'linklint -doc linklint -net -limit 99999999 `find -type d -name html -printf "/%P/@ "`',
175 '[ ! -r linklint/errorX.html ] || python linklint_addnames.py <linklint/errorX.html >linklint/errorX.html.new',
176 '[ ! -r linklint/errorX.html.new ] || mv linklint/errorX.html.new linklint/errorX.html',
177 '[ ! -r linklint/errorAX.html ] || python linklint_addnames.py <linklint/errorAX.html >linklint/errorAX.html.new',
178 '[ ! -r linklint/errorAX.html.new ] || mv linklint/errorAX.html.new linklint/errorAX.html',
179 'echo -e "\\nLokal link check results: linklint/index.html\\nRemote link check results: linklint/urlindex.html\\n"',
182 PhonyTarget(env, 'fixlinks', [
183 'python doclib/fix-links.py -v -s .svn -s linklint -s debian linklint/errorX.txt linklint/errorAX.txt',
186 PhonyTarget(env, 'prepare', [])
188 env.Clean('all', env.Dir('linklint'))
190 env.Clean('all','.prepare-stamp')
191 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
192 Execute(Touch(".prepare-stamp"))