diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-03-17 12:48:44 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-03-17 12:48:44 -0400 |
commit | 24141cda67fe0cbe680c2d3ca15a5ba0799ed744 (patch) | |
tree | f49c7d815a2a81e8aedf467e962939825e9b48e6 | |
parent | 64ffc8b736d5f13f02fb9405904f6a8b8caea3de (diff) |
Improve build system.
Restructure SConstruct to reduce the likelihood
of errors and to provide additional feedback.
Features:
- Better help. You can now run 'scons -h' to
get a listing of all build options.
- Local configuration. Build variables are picked up
in a local .config file, if present.
- Added --dump-config option to display the build
configuration.
- Use scons substitution system to avoid having to do
parameter substitutions manually.
- Some assorted fixes.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | SConstruct | 207 |
2 files changed, 144 insertions, 64 deletions
@@ -24,3 +24,4 @@ measure_syscall | |||
24 | .sconsign.dblite | 24 | .sconsign.dblite |
25 | .sconf_temp/* | 25 | .sconf_temp/* |
26 | config.log | 26 | config.log |
27 | .config | ||
@@ -1,6 +1,25 @@ | |||
1 | # ##################################################################### | 1 | Help(""" |
2 | # User configuration. | 2 | ============================================= |
3 | LITMUS_KERNEL = '../litmus2010' | 3 | liblitmus --- The LITMUS^RT Userspace Library |
4 | |||
5 | There are a number of user-configurable build | ||
6 | variables. These can either be set on the | ||
7 | command line (e.g., scons ARCH=x86) or read | ||
8 | from a local configuration file (.config). | ||
9 | |||
10 | Run 'scons --dump-config' to see the final | ||
11 | build configuration. | ||
12 | |||
13 | """) | ||
14 | |||
15 | import os | ||
16 | (ostype, _, _, _, arch) = os.uname() | ||
17 | |||
18 | # sanity check | ||
19 | if ostype != 'Linux': | ||
20 | print 'Error: Building liblitmus is only supported on Linux.' | ||
21 | Exit(1) | ||
22 | |||
4 | 23 | ||
5 | # ##################################################################### | 24 | # ##################################################################### |
6 | # Internal configuration. | 25 | # Internal configuration. |
@@ -20,90 +39,142 @@ ARCH_ALIAS = { | |||
20 | 'i686' : 'x86' | 39 | 'i686' : 'x86' |
21 | } | 40 | } |
22 | 41 | ||
23 | KERNEL_INCLUDE = '%s/include/' % LITMUS_KERNEL | 42 | # name of the directory that has the arch headers in the Linux source |
24 | INCLUDE_DIRS = 'include/ ' + KERNEL_INCLUDE | 43 | INCLUDE_ARCH = { |
44 | 'sparc64' : 'sparc', | ||
45 | 'x86' : 'x86', | ||
46 | 'x86_64' : 'x86', | ||
47 | } | ||
48 | |||
49 | INCLUDE_DIRS = [ | ||
50 | # library headers | ||
51 | 'include/', | ||
52 | # Linux kernel headers | ||
53 | '${LITMUS_KERNEL}/include/', | ||
54 | # Linux architecture-specific kernel headers | ||
55 | '$LITMUS_KERNEL/arch/${INCLUDE_ARCH}/include' | ||
56 | ] | ||
25 | 57 | ||
26 | # ##################################################################### | 58 | # ##################################################################### |
27 | # Build checks. | 59 | # User configuration. |
28 | 60 | ||
29 | nrSrc = """#include <linux/unistd.h> | 61 | vars = Variables('.config', ARGUMENTS) |
30 | int main(int argc, char **argv) | ||
31 | { | ||
32 | return __NR_set_rt_task_param; | ||
33 | } | ||
34 | """ | ||
35 | 62 | ||
36 | def CheckASMLink(context): | 63 | vars.AddVariables( |
37 | context.Message('Checking for asm/ link in kernel include/... ') | 64 | PathVariable('LITMUS_KERNEL', |
38 | result = context.TryLink(nrSrc, '.c') | 65 | 'Where to find the LITMUS^RT kernel.', |
39 | context.Result(result) | 66 | '../litmus2010'), |
40 | return result | 67 | |
68 | EnumVariable('ARCH', | ||
69 | 'Target architecture.', | ||
70 | arch, | ||
71 | SUPPORTED_ARCHS.keys() + ARCH_ALIAS.keys()), | ||
72 | ) | ||
73 | |||
74 | AddOption('--dump-config', | ||
75 | dest='dump', | ||
76 | action='store_true', | ||
77 | default=False, | ||
78 | help="dump the build configuration and exit") | ||
41 | 79 | ||
42 | # ##################################################################### | 80 | # ##################################################################### |
43 | # Build configuration. | 81 | # Build configuration. |
44 | from os import uname, environ | ||
45 | 82 | ||
46 | # sanity check | 83 | env = Environment(variables = vars) |
47 | (ostype, _, _, _, arch) = uname() | ||
48 | if ostype != 'Linux': | ||
49 | print 'Error: Building liblitmus is only supported on Linux.' | ||
50 | Exit(1) | ||
51 | 84 | ||
52 | # override arch if ARCH is set in environment or command line | 85 | # Check what we are building for. |
53 | if 'ARCH' in ARGUMENTS: | 86 | arch = env['ARCH'] |
54 | arch = ARGUMENTS['ARCH'] | ||
55 | elif 'ARCH' in environ: | ||
56 | arch = environ['ARCH'] | ||
57 | 87 | ||
58 | # replace if the arch has an alternative name | 88 | # replace if the arch has an alternative name |
59 | if arch in ARCH_ALIAS: | 89 | if arch in ARCH_ALIAS: |
60 | arch = ARCH_ALIAS[arch] | 90 | arch = ARCH_ALIAS[arch] |
91 | env['ARCH'] = arch | ||
61 | 92 | ||
62 | if arch not in SUPPORTED_ARCHS: | 93 | # Get include directory for arch. |
63 | print 'Error: Building liblitmus is only supported for the following', \ | 94 | env['INCLUDE_ARCH'] = INCLUDE_ARCH[arch] |
64 | 'architectures: %s.' % ', '.join(sorted(SUPPORTED_ARCHS)) | ||
65 | Exit(1) | ||
66 | else: | ||
67 | arch_flags = Split(SUPPORTED_ARCHS[arch]) | ||
68 | |||
69 | # add architecture dependent include search path | ||
70 | if arch in ['x86','x86_64']: | ||
71 | include_arch = 'x86' | ||
72 | else: | ||
73 | include_arch = 'sparc' | ||
74 | 95 | ||
75 | KERNEL_ARCH_INCLUDE = '%s/arch/%s/include' % (LITMUS_KERNEL, include_arch) | 96 | arch_flags = Split(SUPPORTED_ARCHS[arch]) |
76 | INCLUDE_DIRS = INCLUDE_DIRS + ' ' + KERNEL_ARCH_INCLUDE | 97 | dbg_flags = Split(DEBUG_FLAGS) |
98 | api_flags = Split(API_FLAGS) | ||
77 | 99 | ||
78 | # Set Environment | 100 | # Set up environment |
79 | env = Environment( | 101 | env.Replace( |
80 | CC = 'gcc', | 102 | CC = 'gcc', |
81 | CPPPATH = Split(INCLUDE_DIRS), | 103 | CPPPATH = INCLUDE_DIRS, |
82 | CCFLAGS = Split(DEBUG_FLAGS) + Split(API_FLAGS) + arch_flags, | 104 | CCFLAGS = dbg_flags + api_flags + arch_flags, |
83 | LINKFLAGS = arch_flags, | 105 | LINKFLAGS = arch_flags, |
84 | ) | 106 | ) |
85 | 107 | ||
108 | def dump_config(env): | ||
109 | def dump(key): | ||
110 | print "%15s = %s" % (key, env.subst("${%s}" % key)) | ||
111 | |||
112 | dump('ARCH') | ||
113 | dump('LITMUS_KERNEL') | ||
114 | dump('CPPPATH') | ||
115 | dump('CCFLAGS') | ||
116 | dump('LINKFLAGS') | ||
117 | |||
118 | if GetOption('dump'): | ||
119 | print "\n" | ||
120 | print "Build Configuration:" | ||
121 | dump_config(env) | ||
122 | print "\n" | ||
123 | Exit(0) | ||
124 | |||
125 | # ##################################################################### | ||
126 | # Build checks. | ||
127 | |||
128 | def CheckSyscallNr(context): | ||
129 | context.Message('Checking for LITMUS^RT syscall numbers... ') | ||
130 | nrSrc = """ | ||
131 | #include <linux/unistd.h> | ||
132 | int main(int argc, char **argv) | ||
133 | { | ||
134 | return __NR_set_rt_task_param; | ||
135 | } | ||
136 | """ | ||
137 | result = context.TryLink(nrSrc, '.c') | ||
138 | context.Result(result) | ||
139 | return result | ||
140 | |||
141 | |||
142 | def abort(msg, help=None): | ||
143 | print "Error: %s" % env.subst(msg) | ||
144 | print "-" * 80 | ||
145 | print "This is the build configuration in use:" | ||
146 | dump_config(env) | ||
147 | if help: | ||
148 | print "-" * 80 | ||
149 | print env.subst(help) | ||
150 | print "\n" | ||
151 | Exit(1) | ||
152 | |||
86 | # Check compile environment | 153 | # Check compile environment |
87 | if not env.GetOption('clean'): | 154 | if not (env.GetOption('clean') or env.GetOption('help')): |
88 | print 'Building %s binaries.' % arch | 155 | print env.subst('Building ${ARCH} binaries.') |
89 | # Check for kernel headers. | 156 | # Check for kernel headers. |
90 | conf = Configure(env, custom_tests = {'CheckASMLink' : CheckASMLink}) | 157 | conf = Configure(env, custom_tests = {'CheckSyscallNr' : CheckSyscallNr}) |
91 | if not conf.CheckCHeader('litmus/rt_param.h'): | 158 | |
92 | print 'Env CCFLAGS = %s' % env['CCFLAGS'] | 159 | conf.CheckCHeader('linux/unistd.h') or \ |
93 | print 'Env CPPPATH = %s' % env['CPPPATH'] | 160 | abort("Cannot find kernel headers in '$LITMUS_KERNEL'", |
94 | print "Error: Canot find kernel headers in '%s'." % LITMUS_KERNEL | 161 | "Please ensure that LITMUS_KERNEL in .config is set to a valid path.") |
95 | print "Please ensure that LITMUS_KERNEL in SConstruct", \ | 162 | |
96 | "contains a valid path." | 163 | conf.CheckCHeader('litmus/rt_param.h') or \ |
97 | Exit(1) | 164 | abort("Cannot find LITMUS^RT headers in '$LITMUS_KERNEL'", |
98 | if not conf.CheckASMLink(): | 165 | "Please ensure sure that the kernel in '$LITMUS_KERNEL'" |
99 | print 'Env CCFLAGS = %s' % env['CCFLAGS'] | 166 | " is a LITMUS^RT kernel.") |
100 | print 'Env CPPPATH = %s' % env['CPPPATH'] | 167 | |
101 | print "Error: The LITMUS^RT syscall numbers are not available." | 168 | conf.CheckSyscallNr() or \ |
102 | print "Please ensure sure that the kernel in '%s' is configured." \ | 169 | abort("The LITMUS^RT syscall numbers are not available.", |
103 | % LITMUS_KERNEL | 170 | "Please ensure sure that the kernel in '$LITMUS_KERNEL'" |
104 | Exit(1) | 171 | " is a LITMUS^RT kernel.") |
172 | |||
105 | env = conf.Finish() | 173 | env = conf.Finish() |
106 | 174 | ||
175 | # ##################################################################### | ||
176 | # Derived environments | ||
177 | |||
107 | # link with liblitmus | 178 | # link with liblitmus |
108 | rt = env.Clone( | 179 | rt = env.Clone( |
109 | LIBS = Split('litmus rt'), | 180 | LIBS = Split('litmus rt'), |
@@ -121,7 +192,7 @@ mtrt = rt.Clone() | |||
121 | mtrt.Append(LINKFLAGS = '-pthread') | 192 | mtrt.Append(LINKFLAGS = '-pthread') |
122 | 193 | ||
123 | # ##################################################################### | 194 | # ##################################################################### |
124 | # Targets: liblitmus libst | 195 | # Targets: liblitmus |
125 | # All the files in src/ are part of the library. | 196 | # All the files in src/ are part of the library. |
126 | env.Library('litmus', | 197 | env.Library('litmus', |
127 | ['src/kernel_iface.c', 'src/litmus.c', | 198 | ['src/kernel_iface.c', 'src/litmus.c', |
@@ -151,3 +222,11 @@ test.Append(CPPPATH = ['tests/']) | |||
151 | 222 | ||
152 | catalog = test.TestCatalog('tests/__test_catalog.inc', Glob('tests/*.c')) | 223 | catalog = test.TestCatalog('tests/__test_catalog.inc', Glob('tests/*.c')) |
153 | test.Program('runtests', Glob('tests/*.c')) | 224 | test.Program('runtests', Glob('tests/*.c')) |
225 | |||
226 | # ##################################################################### | ||
227 | # Additional Help | ||
228 | |||
229 | Help("Build Variables\n") | ||
230 | Help("---------------\n") | ||
231 | Help(vars.GenerateHelpText(env)) | ||
232 | |||