aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2010-03-17 12:48:44 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2010-03-17 12:48:44 -0400
commit24141cda67fe0cbe680c2d3ca15a5ba0799ed744 (patch)
treef49c7d815a2a81e8aedf467e962939825e9b48e6
parent64ffc8b736d5f13f02fb9405904f6a8b8caea3de (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--.gitignore1
-rw-r--r--SConstruct207
2 files changed, 144 insertions, 64 deletions
diff --git a/.gitignore b/.gitignore
index 74b4f43..f420aa3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ measure_syscall
24.sconsign.dblite 24.sconsign.dblite
25.sconf_temp/* 25.sconf_temp/*
26config.log 26config.log
27.config
diff --git a/SConstruct b/SConstruct
index e7885d3..c41e41e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,6 +1,25 @@
1# ##################################################################### 1Help("""
2# User configuration. 2=============================================
3LITMUS_KERNEL = '../litmus2010' 3liblitmus --- The LITMUS^RT Userspace Library
4
5There are a number of user-configurable build
6variables. These can either be set on the
7command line (e.g., scons ARCH=x86) or read
8from a local configuration file (.config).
9
10Run 'scons --dump-config' to see the final
11build configuration.
12
13""")
14
15import os
16(ostype, _, _, _, arch) = os.uname()
17
18# sanity check
19if 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
23KERNEL_INCLUDE = '%s/include/' % LITMUS_KERNEL 42# name of the directory that has the arch headers in the Linux source
24INCLUDE_DIRS = 'include/ ' + KERNEL_INCLUDE 43INCLUDE_ARCH = {
44 'sparc64' : 'sparc',
45 'x86' : 'x86',
46 'x86_64' : 'x86',
47}
48
49INCLUDE_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
29nrSrc = """#include <linux/unistd.h> 61vars = Variables('.config', ARGUMENTS)
30int main(int argc, char **argv)
31{
32 return __NR_set_rt_task_param;
33}
34"""
35 62
36def CheckASMLink(context): 63vars.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
74AddOption('--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.
44from os import uname, environ
45 82
46# sanity check 83env = Environment(variables = vars)
47(ostype, _, _, _, arch) = uname()
48if 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.
53if 'ARCH' in ARGUMENTS: 86arch = env['ARCH']
54 arch = ARGUMENTS['ARCH']
55elif '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
59if arch in ARCH_ALIAS: 89if arch in ARCH_ALIAS:
60 arch = ARCH_ALIAS[arch] 90 arch = ARCH_ALIAS[arch]
91 env['ARCH'] = arch
61 92
62if arch not in SUPPORTED_ARCHS: 93# Get include directory for arch.
63 print 'Error: Building liblitmus is only supported for the following', \ 94env['INCLUDE_ARCH'] = INCLUDE_ARCH[arch]
64 'architectures: %s.' % ', '.join(sorted(SUPPORTED_ARCHS))
65 Exit(1)
66else:
67 arch_flags = Split(SUPPORTED_ARCHS[arch])
68
69# add architecture dependent include search path
70if arch in ['x86','x86_64']:
71 include_arch = 'x86'
72else:
73 include_arch = 'sparc'
74 95
75KERNEL_ARCH_INCLUDE = '%s/arch/%s/include' % (LITMUS_KERNEL, include_arch) 96arch_flags = Split(SUPPORTED_ARCHS[arch])
76INCLUDE_DIRS = INCLUDE_DIRS + ' ' + KERNEL_ARCH_INCLUDE 97dbg_flags = Split(DEBUG_FLAGS)
98api_flags = Split(API_FLAGS)
77 99
78# Set Environment 100# Set up environment
79env = Environment( 101env.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
108def 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
118if 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
128def CheckSyscallNr(context):
129 context.Message('Checking for LITMUS^RT syscall numbers... ')
130 nrSrc = """
131#include <linux/unistd.h>
132int 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
142def 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
87if not env.GetOption('clean'): 154if 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
108rt = env.Clone( 179rt = env.Clone(
109 LIBS = Split('litmus rt'), 180 LIBS = Split('litmus rt'),
@@ -121,7 +192,7 @@ mtrt = rt.Clone()
121mtrt.Append(LINKFLAGS = '-pthread') 192mtrt.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.
126env.Library('litmus', 197env.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
152catalog = test.TestCatalog('tests/__test_catalog.inc', Glob('tests/*.c')) 223catalog = test.TestCatalog('tests/__test_catalog.inc', Glob('tests/*.c'))
153test.Program('runtests', Glob('tests/*.c')) 224test.Program('runtests', Glob('tests/*.c'))
225
226# #####################################################################
227# Additional Help
228
229Help("Build Variables\n")
230Help("---------------\n")
231Help(vars.GenerateHelpText(env))
232