diff options
-rw-r--r-- | SConstruct | 114 | ||||
-rw-r--r-- | src/SConscript | 42 |
2 files changed, 85 insertions, 71 deletions
diff --git a/SConstruct b/SConstruct index 062df47d6..1a54bbbf6 100644 --- a/SConstruct +++ b/SConstruct @@ -66,7 +66,7 @@ import sys import os -from os.path import isdir, join as joinpath +from os.path import isdir, isfile, join as joinpath import SCons @@ -205,6 +205,10 @@ for t in abs_targets: if build_path not in build_paths: build_paths.append(build_path) +# Make sure build_root exists (might not if this is the first build there) +if not isdir(build_root): + os.mkdir(build_root) + ################################################### # # Set up the default build environment. This environment is copied @@ -216,14 +220,6 @@ env = Environment(ENV = os.environ, # inherit user's environment vars ROOT = ROOT, SRCDIR = SRCDIR) -#Parse CC/CXX early so that we use the correct compiler for -# to test for dependencies/versions/libraries/includes -if ARGUMENTS.get('CC', None): - env['CC'] = ARGUMENTS.get('CC') - -if ARGUMENTS.get('CXX', None): - env['CXX'] = ARGUMENTS.get('CXX') - Export('env') env.SConsignFile(joinpath(build_root,"sconsign")) @@ -240,6 +236,61 @@ env.SetOption('duplicate', 'soft-copy') if False: env.TargetSignatures('content') +# +# Set up global sticky options... these are common to an entire build +# tree (not specific to a particular build like ALPHA_SE) +# + +# Option validators & converters for global sticky options +def PathListMakeAbsolute(val): + if not val: + return val + f = lambda p: os.path.abspath(os.path.expanduser(p)) + return ':'.join(map(f, val.split(':'))) + +def PathListAllExist(key, val, env): + if not val: + return + paths = val.split(':') + for path in paths: + if not isdir(path): + raise SCons.Errors.UserError("Path does not exist: '%s'" % path) + +global_sticky_opts_file = joinpath(build_root, 'options.global') + +global_sticky_opts = Options(global_sticky_opts_file, args=ARGUMENTS) + +global_sticky_opts.AddOptions( + ('CC', 'C compiler', os.environ.get('CC', env['CC'])), + ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])), + ('EXTRAS', 'Add Extra directories to the compilation', '', + PathListAllExist, PathListMakeAbsolute) + ) + + +# base help text +help_text = ''' +Usage: scons [scons options] [build options] [target(s)] + +''' + +help_text += "Global sticky options:\n" \ + + global_sticky_opts.GenerateHelpText(env) + +# Update env with values from ARGUMENTS & file global_sticky_opts_file +global_sticky_opts.Update(env) + +# Save sticky option settings back to current options file +global_sticky_opts.Save(global_sticky_opts_file, env) + +# Parse EXTRAS option to build list of all directories where we're +# look for sources etc. This list is exported as base_dir_list. +base_dir_list = [joinpath(ROOT, 'src')] +if env['EXTRAS']: + base_dir_list += env['EXTRAS'].split(':') + +Export('base_dir_list') + # M5_PLY is used by isa_parser.py to find the PLY package. env.Append(ENV = { 'M5_PLY' : str(Dir('ext/ply')) }) env['GCC'] = False @@ -467,28 +518,16 @@ Export('nonsticky_opts') # Walk the tree and execute all SConsopts scripts that wil add to the # above options -for root, dirs, files in os.walk('.'): - if 'SConsopts' in files: - SConscript(os.path.join(root, 'SConsopts')) +for base_dir in base_dir_list: + for root, dirs, files in os.walk(base_dir): + if 'SConsopts' in files: + print "Reading", joinpath(root, 'SConsopts') + SConscript(joinpath(root, 'SConsopts')) all_isa_list.sort() all_cpu_list.sort() default_cpus.sort() -def PathListMakeAbsolute(val): - if not val: - return val - f = lambda p: os.path.abspath(os.path.expanduser(p)) - return ':'.join(map(f, val.split(':'))) - -def PathListAllExist(key, val, env): - if not val: - return - paths = val.split(':') - for path in paths: - if not isdir(path): - raise SCons.Errors.UserError("Path does not exist: '%s'" % path) - sticky_opts.AddOptions( EnumOption('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), BoolOption('FULL_SYSTEM', 'Full-system support', False), @@ -509,15 +548,11 @@ sticky_opts.AddOptions( BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql), BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), BoolOption('USE_CHECKER', 'Use checker for detailed CPU models', False), - ('CC', 'C compiler', os.environ.get('CC', env['CC'])), - ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])), BoolOption('BATCH', 'Use batch pool for build and tests', False), ('BATCH_CMD', 'Batch pool submission command name', 'qdo'), ('PYTHONHOME', 'Override the default PYTHONHOME for this system (use with caution)', '%s:%s' % (sys.prefix, sys.exec_prefix)), - ('EXTRAS', 'Add Extra directories to the compilation', '', - PathListAllExist, PathListMakeAbsolute) ) nonsticky_opts.AddOptions( @@ -607,12 +642,6 @@ concat_builder = Builder(action = Action(['cat $SOURCES > $TARGET', env.Append(BUILDERS = { 'Concat' : concat_builder }) -# base help text -help_text = ''' -Usage: scons [scons options] [build options] [target(s)] - -''' - # libelf build is shared across all configs in the build root. env.SConscript('ext/libelf/SConscript', build_dir = joinpath(build_root, 'libelf'), @@ -669,13 +698,14 @@ base_env = env for build_path in build_paths: print "Building in", build_path + + # Make a copy of the build-root environment to use for this config. + env = base_env.Copy() env['BUILDDIR'] = build_path # build_dir is the tail component of build path, and is used to # determine the build parameters (e.g., 'ALPHA_SE') (build_root, build_dir) = os.path.split(build_path) - # Make a copy of the build-root environment to use for this config. - env = base_env.Copy() # Set env options according to the build directory config. sticky_opts.files = [] @@ -683,7 +713,7 @@ for build_path in build_paths: # $BUILD_ROOT/options/$BUILD_DIR so you can nuke # $BUILD_ROOT/$BUILD_DIR without losing your options settings. current_opts_file = joinpath(build_root, 'options', build_dir) - if os.path.isfile(current_opts_file): + if isfile(current_opts_file): sticky_opts.files.append(current_opts_file) print "Using saved options file %s" % current_opts_file else: @@ -691,7 +721,7 @@ for build_path in build_paths: # Make sure the directory is there so we can create it later opt_dir = os.path.dirname(current_opts_file) - if not os.path.isdir(opt_dir): + if not isdir(opt_dir): os.mkdir(opt_dir) # Get default build options from source tree. Options are @@ -699,7 +729,7 @@ for build_path in build_paths: # overriden by 'default=' arg on command line. default_opts_file = joinpath('build_opts', ARGUMENTS.get('default', build_dir)) - if os.path.isfile(default_opts_file): + if isfile(default_opts_file): sticky_opts.files.append(default_opts_file) print "Options file %s not found,\n using defaults in %s" \ % (current_opts_file, default_opts_file) @@ -712,7 +742,7 @@ for build_path in build_paths: sticky_opts.Update(env) nonsticky_opts.Update(env) - help_text += "Sticky options for %s:\n" % build_dir \ + help_text += "\nSticky options for %s:\n" % build_dir \ + sticky_opts.GenerateHelpText(env) \ + "\nNon-sticky options for %s:\n" % build_dir \ + nonsticky_opts.GenerateHelpText(env) diff --git a/src/SConscript b/src/SConscript index 8e6e1b45e..69c5b946d 100644 --- a/src/SConscript +++ b/src/SConscript @@ -32,11 +32,7 @@ import imp import os import sys -from os.path import basename -from os.path import join as joinpath -from os.path import exists -from os.path import isdir -from os.path import isfile +from os.path import basename, exists, isdir, isfile, join as joinpath import SCons @@ -181,31 +177,19 @@ env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) ######################################################################## # -# Walk the tree and execute all SConscripts +# Walk the tree and execute all SConscripts in subdirectories # -srcdir = env['SRCDIR'] -for root, dirs, files in os.walk(srcdir, topdown=True): - if root == srcdir: - # we don't want to recurse back into this SConscript - continue - - if 'SConscript' in files: - # strip off the srcdir part since scons will try to find the - # script in the build directory - base = root[len(srcdir) + 1:] - SConscript(joinpath(base, 'SConscript')) - -extra_string = env['EXTRAS'] -if extra_string and extra_string != '' and not extra_string.isspace(): - for extra in extra_string.split(':'): - print 'Adding', extra, 'to source directory list' - env.Append(CPPPATH=[Dir(extra)]) - for root, dirs, files in os.walk(extra, topdown=True): - if 'SConscript' in files: - subdir = root[len(os.path.dirname(extra))+1:] - print ' Found SConscript in', subdir - build_dir = joinpath(env['BUILDDIR'], subdir) - SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) + +for base_dir in base_dir_list: + here = Dir('.').srcnode().abspath + for root, dirs, files in os.walk(base_dir, topdown=True): + if root == here: + # we don't want to recurse back into this SConscript + continue + + if 'SConscript' in files: + build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) + SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) for opt in env.ExportOptions: env.ConfigFile(opt) |