Produfce more detailed statistics in fix-links.py
[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 'SConfig' and/or 'Doxyfile.local'."
45         print "Building a debian package would remove those files."
46         print
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."
51         print
52         return 1
53
54 ###########################################################################
55 # Load utilities and setup libraries and configure build
56
57 SENFSCons.UseBoost()
58 SENFSCons.UseSTLPort()
59 env = SENFSCons.MakeEnvironment()
60
61 env.Help("""
62 Additional top-level build targets:
63
64 all_tests    Build and run unit tests for all modules
65 all_docs     Build documentation for all modules
66 all          Build everything
67 install_all  Install SENF into $PREFIX
68 deb          Build debian source and binary package
69 debsrc       Build debian source package
70 debbin       Build debian binary package
71 linklint     Check links of doxygen documentation with 'linklint'
72 """)
73
74 if os.environ.get('debian_build'):
75     rev = os.popen("dpkg-parsechangelog | awk '/^Version:/{print $2}'").read().strip()
76 else:
77     rev = 'r' + os.popen("svnversion").read().strip().lower()
78
79 logname = os.environ.get('LOGNAME')
80 if not logname:
81     logname = pwd.getpwuid(os.getuid()).pw_name
82
83 def configFilesOpts(target, source, env, for_signature):
84     return [ '-I%s' % os.path.split(f)[1] for f in env['CONFIG_FILES'] ]
85
86 env.Append(
87    CPPPATH = [ '#/include' ],
88    LIBS = [ 'iberty', '$BOOSTREGEXLIB' ],
89    DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
90    DOXY_HTML_XSL = '#/doclib/html-munge.xsl',
91    ENV = { 'TODAY' : str(datetime.date.today()),
92            'REVISION' : rev,
93            'LOGNAME' : logname, # needed by the debian build scripts
94            'CONCURRENCY_LEVEL' : env.GetOption('num_jobs') or "1"
95            },
96    CONFIG_FILES = [ 'Doxyfile.local', 'SConfig', 'local_config.hh' ],
97    CONFIG_FILES_OPTS = configFilesOpts,
98    CLEAN_PATTERNS = [ '*.pyc', 'semantic.cache', '.sconsign', '.sconsign.dblite' ],
99    BUILDPACKAGE_COMMAND = "dpkg-buildpackage -us -uc -rfakeroot -I.svn $CONFIG_FILES_OPTS",
100    TOP_INCLUDES = [ 'Packets', 'PPI', 'Scheduler', 'Socket', 'Utils',
101                     'config.hh', 'local_config.hh' ]
102 )
103
104 Export('env')
105
106 # Create Doxyfile.local if not cleaning and the file does not exist
107 # otherwise doxygen will barf on this non-existent file
108 if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
109     Execute(Touch("Doxyfile.local"))
110
111 # Create local_config.h
112 if not env.GetOption('clean') and not os.path.exists("local_config.hh"):
113     Execute(Touch("local_config.hh"))
114
115 ###########################################################################
116 # Define build targets
117
118 SConscript(glob.glob("*/SConscript"))
119
120 SENFSCons.StandardTargets(env)
121 SENFSCons.GlobalTargets(env)
122 SENFSCons.Doxygen(env)
123 SENFSCons.DoxyXRef(env,
124                    HTML_HEADER = '#/doclib/doxy-header-overview.html',
125                    HTML_FOOTER = '#/doclib/doxy-footer.html')
126
127 SENFSCons.InstallIncludeFiles(env, [ 'config.hh' ])
128
129 # Build combined library 'libsenf'
130 libsenf = env.Library(
131     SENFSCons.LibPath('senf'),
132     Flatten([ env.File(SENFSCons.LibPath(lib)).sources for lib in env['ALLLIBS'] ]))
133 env.Default(libsenf)
134 env.Clean('all', 'libsenf.a')
135 env.Alias('all', 'libsenf.a')
136
137 env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
138
139 env.Clean('all', [ os.path.join(path,f)
140                    for path, subdirs, files in os.walk('.')
141                    for pattern in env['CLEAN_PATTERNS']
142                    for f in fnmatch.filter(files,pattern) ])
143
144 PhonyTarget(env, 'deb', [
145     checkLocalConf,
146     updateRevision,
147     "$BUILDPACKAGE_COMMAND",
148 ])
149
150 PhonyTarget(env, 'debsrc', [
151     updateRevision,
152     "$BUILDPACKAGE_COMMAND -S",
153 ])
154
155 PhonyTarget(env, 'debbin', [
156     checkLocalConf,
157     updateRevision,
158     "$BUILDPACKAGE_COMMAND -nc",
159 ])
160
161 PhonyTarget(env, 'linklint', [
162     'rm -rf linklint',
163     'linklint -doc linklint -net -limit 99999999 `find -type d -name html -printf "/%P/@ "`',
164     '[ ! -r linklint/errorX.html ] || python linklint_addnames.py <linklint/errorX.html >linklint/errorX.html.new',
165     '[ ! -r linklint/errorX.html.new ] || mv linklint/errorX.html.new linklint/errorX.html',
166     '[ ! -r linklint/errorAX.html ] || python linklint_addnames.py <linklint/errorAX.html >linklint/errorAX.html.new',
167     '[ ! -r linklint/errorAX.html.new ] || mv linklint/errorAX.html.new linklint/errorAX.html',
168     'echo -e "\\nLokal link check results: linklint/index.html\\nRemote link check results: linklint/urlindex.html\\n"',
169 ])
170
171 PhonyTarget(env, 'fixlinks', [
172     'python doclib/fix-links.py -v -s .svn -s linklint -s debian linklint/errorX.txt linklint/errorAX.txt',
173 ])
174
175 env.Clean('all', env.Dir('linklint'))