Utils: Implement IpChecksum helper class
[senf.git] / SConstruct
1 # -*- python -*-
2
3 import sys, glob, os.path, datetime, pwd, time, fnmatch
4 sys.path.append('senfscons')
5 import SENFSCons
6
7 ###########################################################################
8
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')
14
15 def updateRevision(target, source, env):
16     rev = env['ENV']['REVISION'][1:]
17     if ':' in rev:
18         print
19         print "Working copy not clean. Run 'svn update'"
20         print
21         return 1
22     if 'm' in rev and not ARGUMENTS.get('force_deb'):
23         print
24         print "Working copy contains local changes. Commit first"
25         print
26         return 1
27     if 's' in rev:
28         rev = rev[:-1]
29     if 'm' in rev:
30         rev = rev[:-1]
31     changelog = file('debian/changelog.template').read() % {
32         'rev': rev,
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)
36
37 def nonemptyFile(f):
38     try: return os.stat(f).st_size > 0
39     except OSError: return False
40
41 def checkLocalConf(target, source, env):
42     if [ True for f in env['CONFIG_FILES'] if nonemptyFile(f) ]:
43         print
44         print "You have made local modifications to one of the following local configuration"
45         print "files:"
46         for f in env['CONFIG_FILES']:
47             print "    ",f
48         print
49         print "Building a debian package would remove those files."
50         print
51         print "To continue, remove the offending file(s) and try again. Alternatively,"
52         print "build a source package using 'scons debsrc' and may then build debian"
53         print "binary packages from this source-package without disrupting your local"
54         print "configuration."
55         print
56         return 1
57
58 ###########################################################################
59 # Load utilities and setup libraries and configure build
60
61 SENFSCons.UseBoost()
62 SENFSCons.UseSTLPort()
63 env = SENFSCons.MakeEnvironment()
64
65 env.Help("""
66 Additional top-level build targets:
67
68 prepare      Create all source files not part of the repository
69 all_tests    Build and run unit tests for all modules
70 all_docs     Build documentation for all modules
71 all          Build everything
72 install_all  Install SENF into $PREFIX
73 deb          Build debian source and binary package
74 debsrc       Build debian source package
75 debbin       Build debian binary package
76 linklint     Check links of doxygen documentation with 'linklint'
77 fixlinks     Fix broken links in doxygen documentation
78 """)
79
80 if os.environ.get('debian_build'):
81     rev = os.popen("dpkg-parsechangelog | awk '/^Version:/{print $2}'").read().strip()
82 else:
83     rev = 'r' + os.popen("svnversion").read().strip().lower()
84
85 logname = os.environ.get('LOGNAME')
86 if not logname:
87     logname = pwd.getpwuid(os.getuid()).pw_name
88
89 def configFilesOpts(target, source, env, for_signature):
90     return [ '-I%s' % os.path.split(f)[1] for f in env['CONFIG_FILES'] ]
91
92 env.Append(
93    CPPPATH = [ '#/include' ],
94    LIBS = [ 'iberty', '$BOOSTREGEXLIB', '$BOOSTFSLIB' ],
95    DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
96    DOXY_HTML_XSL = '#/doclib/html-munge.xsl',
97    ENV = { 'TODAY' : str(datetime.date.today()),
98            'REVISION' : rev,
99            'LOGNAME' : logname, # needed by the debian build scripts
100            'CONCURRENCY_LEVEL' : env.GetOption('num_jobs') or "1",
101            'SCONS' : 1
102            },
103    CONFIG_FILES = [ 'Doxyfile.local', 'SConfig', 'local_config.hh' ],
104    CONFIG_FILES_OPTS = configFilesOpts,
105    CLEAN_PATTERNS = [ '*.pyc', 'semantic.cache', '.sconsign', '.sconsign.dblite' ],
106    BUILDPACKAGE_COMMAND = "dpkg-buildpackage -us -uc -rfakeroot -I.svn $CONFIG_FILES_OPTS",
107    TOP_INCLUDES = [ 'Packets', 'PPI', 'Scheduler', 'Socket', 'Utils',
108                     'config.hh', 'local_config.hh' ]
109 )
110
111 Export('env')
112
113 # Create Doxyfile.local otherwise doxygen will barf on this non-existent file
114 if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
115     Execute(Touch("Doxyfile.local"))
116
117 # Create local_config.h
118 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
119     Execute(Touch("local_config.hh"))
120
121 ###########################################################################
122 # Define build targets
123
124 # Before defining any targets, check wether this is the first build in
125 # pristine directory tree. If so, call 'scons prepare' so the dependencies
126 # created later are correct
127
128 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp") \
129    and not os.environ.get("SCONS"):
130     env.Execute([ "scons prepare" ])
131
132 env.Clean('all', '.prepare-stamp')
133
134 SConscript(glob.glob("*/SConscript"))
135
136 SENFSCons.StandardTargets(env)
137 SENFSCons.GlobalTargets(env)
138 SENFSCons.Doxygen(env)
139 SENFSCons.DoxyXRef(env,
140                    HTML_HEADER = '#/doclib/doxy-header-overview.html',
141                    HTML_FOOTER = '#/doclib/doxy-footer.html')
142
143 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
144
145 # Build combined library 'libsenf'
146 libsenf = env.Library(
147     SENFSCons.LibPath('senf'),
148     Flatten([ env.File(SENFSCons.LibPath(lib)).sources for lib in env['ALLLIBS'] ]))
149 env.Default(libsenf)
150 env.Clean('all', 'libsenf.a')
151 env.Alias('default', 'libsenf.a')
152
153 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
154
155 env.Clean('all', [ os.path.join(path,f)
156                    for path, subdirs, files in os.walk('.')
157                    for pattern in env['CLEAN_PATTERNS']
158                    for f in fnmatch.filter(files,pattern) ])
159
160 PhonyTarget(env, 'deb', [
161     checkLocalConf,
162     updateRevision,
163     "$BUILDPACKAGE_COMMAND",
164 ])
165
166 PhonyTarget(env, 'debsrc', [
167     updateRevision,
168     "$BUILDPACKAGE_COMMAND -S",
169 ])
170
171 PhonyTarget(env, 'debbin', [
172     checkLocalConf,
173     updateRevision,
174     "$BUILDPACKAGE_COMMAND -nc",
175 ])
176
177 PhonyTarget(env, 'linklint', [
178     'rm -rf linklint',
179     'linklint -doc linklint -limit 99999999 `find -type d -name html -printf "/%P/@ "`',
180     '[ ! -r linklint/errorX.html ] || python linklint_addnames.py <linklint/errorX.html >linklint/errorX.html.new',
181     '[ ! -r linklint/errorX.html.new ] || mv linklint/errorX.html.new linklint/errorX.html',
182     '[ ! -r linklint/errorAX.html ] || python linklint_addnames.py <linklint/errorAX.html >linklint/errorAX.html.new',
183     '[ ! -r linklint/errorAX.html.new ] || mv linklint/errorAX.html.new linklint/errorAX.html',
184     'echo -e "\\nLokal link check results: linklint/index.html\\nRemote link check results: linklint/urlindex.html\\n"',
185 ])
186
187 PhonyTarget(env, 'fixlinks', [
188     'python doclib/fix-links.py -v -s .svn -s linklint -s debian linklint/errorX.txt linklint/errorAX.txt',
189 ])
190
191 PhonyTarget(env, 'prepare', [])
192
193 env.Clean('all', env.Dir('linklint'))
194
195 env.Clean('all','.prepare-stamp')
196 if not env.GetOption('clean') and not os.path.exists(".prepare-stamp"):
197     Execute(Touch(".prepare-stamp"))