From 24141cda67fe0cbe680c2d3ca15a5ba0799ed744 Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Wed, 17 Mar 2010 12:48:44 -0400 Subject: 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. --- .gitignore | 1 + SConstruct | 207 ++++++++++++++++++++++++++++++++++++++++++------------------- 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 .sconsign.dblite .sconf_temp/* config.log +.config diff --git a/SConstruct b/SConstruct index e7885d3..c41e41e 100644 --- a/SConstruct +++ b/SConstruct @@ -1,6 +1,25 @@ -# ##################################################################### -# User configuration. -LITMUS_KERNEL = '../litmus2010' +Help(""" +============================================= +liblitmus --- The LITMUS^RT Userspace Library + +There are a number of user-configurable build +variables. These can either be set on the +command line (e.g., scons ARCH=x86) or read +from a local configuration file (.config). + +Run 'scons --dump-config' to see the final +build configuration. + +""") + +import os +(ostype, _, _, _, arch) = os.uname() + +# sanity check +if ostype != 'Linux': + print 'Error: Building liblitmus is only supported on Linux.' + Exit(1) + # ##################################################################### # Internal configuration. @@ -20,90 +39,142 @@ ARCH_ALIAS = { 'i686' : 'x86' } -KERNEL_INCLUDE = '%s/include/' % LITMUS_KERNEL -INCLUDE_DIRS = 'include/ ' + KERNEL_INCLUDE +# name of the directory that has the arch headers in the Linux source +INCLUDE_ARCH = { + 'sparc64' : 'sparc', + 'x86' : 'x86', + 'x86_64' : 'x86', +} + +INCLUDE_DIRS = [ + # library headers + 'include/', + # Linux kernel headers + '${LITMUS_KERNEL}/include/', + # Linux architecture-specific kernel headers + '$LITMUS_KERNEL/arch/${INCLUDE_ARCH}/include' + ] # ##################################################################### -# Build checks. +# User configuration. -nrSrc = """#include -int main(int argc, char **argv) -{ - return __NR_set_rt_task_param; -} -""" +vars = Variables('.config', ARGUMENTS) -def CheckASMLink(context): - context.Message('Checking for asm/ link in kernel include/... ') - result = context.TryLink(nrSrc, '.c') - context.Result(result) - return result +vars.AddVariables( + PathVariable('LITMUS_KERNEL', + 'Where to find the LITMUS^RT kernel.', + '../litmus2010'), + + EnumVariable('ARCH', + 'Target architecture.', + arch, + SUPPORTED_ARCHS.keys() + ARCH_ALIAS.keys()), +) + +AddOption('--dump-config', + dest='dump', + action='store_true', + default=False, + help="dump the build configuration and exit") # ##################################################################### # Build configuration. -from os import uname, environ -# sanity check -(ostype, _, _, _, arch) = uname() -if ostype != 'Linux': - print 'Error: Building liblitmus is only supported on Linux.' - Exit(1) +env = Environment(variables = vars) -# override arch if ARCH is set in environment or command line -if 'ARCH' in ARGUMENTS: - arch = ARGUMENTS['ARCH'] -elif 'ARCH' in environ: - arch = environ['ARCH'] +# Check what we are building for. +arch = env['ARCH'] # replace if the arch has an alternative name if arch in ARCH_ALIAS: arch = ARCH_ALIAS[arch] + env['ARCH'] = arch -if arch not in SUPPORTED_ARCHS: - print 'Error: Building liblitmus is only supported for the following', \ - 'architectures: %s.' % ', '.join(sorted(SUPPORTED_ARCHS)) - Exit(1) -else: - arch_flags = Split(SUPPORTED_ARCHS[arch]) - -# add architecture dependent include search path -if arch in ['x86','x86_64']: - include_arch = 'x86' -else: - include_arch = 'sparc' +# Get include directory for arch. +env['INCLUDE_ARCH'] = INCLUDE_ARCH[arch] -KERNEL_ARCH_INCLUDE = '%s/arch/%s/include' % (LITMUS_KERNEL, include_arch) -INCLUDE_DIRS = INCLUDE_DIRS + ' ' + KERNEL_ARCH_INCLUDE +arch_flags = Split(SUPPORTED_ARCHS[arch]) +dbg_flags = Split(DEBUG_FLAGS) +api_flags = Split(API_FLAGS) -# Set Environment -env = Environment( +# Set up environment +env.Replace( CC = 'gcc', - CPPPATH = Split(INCLUDE_DIRS), - CCFLAGS = Split(DEBUG_FLAGS) + Split(API_FLAGS) + arch_flags, + CPPPATH = INCLUDE_DIRS, + CCFLAGS = dbg_flags + api_flags + arch_flags, LINKFLAGS = arch_flags, ) +def dump_config(env): + def dump(key): + print "%15s = %s" % (key, env.subst("${%s}" % key)) + + dump('ARCH') + dump('LITMUS_KERNEL') + dump('CPPPATH') + dump('CCFLAGS') + dump('LINKFLAGS') + +if GetOption('dump'): + print "\n" + print "Build Configuration:" + dump_config(env) + print "\n" + Exit(0) + +# ##################################################################### +# Build checks. + +def CheckSyscallNr(context): + context.Message('Checking for LITMUS^RT syscall numbers... ') + nrSrc = """ +#include +int main(int argc, char **argv) +{ + return __NR_set_rt_task_param; +} +""" + result = context.TryLink(nrSrc, '.c') + context.Result(result) + return result + + +def abort(msg, help=None): + print "Error: %s" % env.subst(msg) + print "-" * 80 + print "This is the build configuration in use:" + dump_config(env) + if help: + print "-" * 80 + print env.subst(help) + print "\n" + Exit(1) + # Check compile environment -if not env.GetOption('clean'): - print 'Building %s binaries.' % arch +if not (env.GetOption('clean') or env.GetOption('help')): + print env.subst('Building ${ARCH} binaries.') # Check for kernel headers. - conf = Configure(env, custom_tests = {'CheckASMLink' : CheckASMLink}) - if not conf.CheckCHeader('litmus/rt_param.h'): - print 'Env CCFLAGS = %s' % env['CCFLAGS'] - print 'Env CPPPATH = %s' % env['CPPPATH'] - print "Error: Canot find kernel headers in '%s'." % LITMUS_KERNEL - print "Please ensure that LITMUS_KERNEL in SConstruct", \ - "contains a valid path." - Exit(1) - if not conf.CheckASMLink(): - print 'Env CCFLAGS = %s' % env['CCFLAGS'] - print 'Env CPPPATH = %s' % env['CPPPATH'] - print "Error: The LITMUS^RT syscall numbers are not available." - print "Please ensure sure that the kernel in '%s' is configured." \ - % LITMUS_KERNEL - Exit(1) + conf = Configure(env, custom_tests = {'CheckSyscallNr' : CheckSyscallNr}) + + conf.CheckCHeader('linux/unistd.h') or \ + abort("Cannot find kernel headers in '$LITMUS_KERNEL'", + "Please ensure that LITMUS_KERNEL in .config is set to a valid path.") + + conf.CheckCHeader('litmus/rt_param.h') or \ + abort("Cannot find LITMUS^RT headers in '$LITMUS_KERNEL'", + "Please ensure sure that the kernel in '$LITMUS_KERNEL'" + " is a LITMUS^RT kernel.") + + conf.CheckSyscallNr() or \ + abort("The LITMUS^RT syscall numbers are not available.", + "Please ensure sure that the kernel in '$LITMUS_KERNEL'" + " is a LITMUS^RT kernel.") + env = conf.Finish() +# ##################################################################### +# Derived environments + # link with liblitmus rt = env.Clone( LIBS = Split('litmus rt'), @@ -121,7 +192,7 @@ mtrt = rt.Clone() mtrt.Append(LINKFLAGS = '-pthread') # ##################################################################### -# Targets: liblitmus libst +# Targets: liblitmus # All the files in src/ are part of the library. env.Library('litmus', ['src/kernel_iface.c', 'src/litmus.c', @@ -151,3 +222,11 @@ test.Append(CPPPATH = ['tests/']) catalog = test.TestCatalog('tests/__test_catalog.inc', Glob('tests/*.c')) test.Program('runtests', Glob('tests/*.c')) + +# ##################################################################### +# Additional Help + +Help("Build Variables\n") +Help("---------------\n") +Help(vars.GenerateHelpText(env)) + -- cgit v1.2.2