29a30
> # Nathan Binkert
66c67,97
< import sys
---
> # Check for recent-enough Python and SCons versions.
> try:
> # Really old versions of scons only take two options for the
> # function, so check once without the revision and once with the
> # revision, the first instance will fail for stuff other than
> # 0.98, and the second will fail for 0.98.0
> EnsureSConsVersion(0, 98)
> EnsureSConsVersion(0, 98, 1)
> except SystemExit, e:
> print """
> For more details, see:
> http://m5sim.org/wiki/index.php/Compiling_M5
> """
> raise
>
> # We ensure the python version early because we have stuff that
> # requires python 2.4
> try:
> EnsurePythonVersion(2, 4)
> except SystemExit, e:
> print """
> You can use a non-default installation of the Python interpreter by
> either (1) rearranging your PATH so that scons finds the non-default
> 'python' first or (2) explicitly invoking an alternative interpreter
> on the scons script.
>
> For more details, see:
> http://m5sim.org/wiki/index.php/Using_a_non-default_Python_installation
> """
> raise
>
68a100,101
> import subprocess
> import sys
70c103,106
< from os.path import isdir, isfile, join as joinpath
---
> from os import mkdir, environ
> from os.path import abspath, basename, dirname, expanduser, normpath
> from os.path import exists, isdir, isfile
> from os.path import join as joinpath, split as splitpath
74,80c110,115
< # Check for recent-enough Python and SCons versions. If your system's
< # default installation of Python is not recent enough, you can use a
< # non-default installation of the Python interpreter by either (1)
< # rearranging your PATH so that scons finds the non-default 'python'
< # first or (2) explicitly invoking an alternative interpreter on the
< # scons script, e.g., "/usr/local/bin/python2.4 `which scons` [args]".
< EnsurePythonVersion(2,4)
---
> def read_command(cmd):
> """run the command cmd, read the results and return them
> this is sorta like `cmd` in shell"""
> from subprocess import Popen, PIPE, STDOUT
> subp = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, close_fds=True)
> return subp.communicate()[0]
82,85d116
< # Import subprocess after we check the version since it doesn't exist in
< # Python < 2.4.
< import subprocess
<
109,148d139
< # SCons version numbers need special processing because they can have
< # charecters and an release date embedded in them. This function does
< # the magic to extract them in a similar way to the SCons internal function
< # function does and then checks that the current version is not contained in
< # a list of version tuples (bad_ver_strs)
< def CheckSCons(bad_ver_strs):
< def scons_ver(v):
< num_parts = v.split(' ')[0].split('.')
< major = int(num_parts[0])
< minor = int(re.match('\d+', num_parts[1]).group())
< rev = 0
< rdate = 0
< if len(num_parts) > 2:
< try: rev = int(re.match('\d+', num_parts[2]).group())
< except: pass
< rev_parts = num_parts[2].split('d')
< if len(rev_parts) > 1:
< rdate = int(re.match('\d+', rev_parts[1]).group())
<
< return (major, minor, rev, rdate)
<
< sc_ver = scons_ver(SCons.__version__)
< for bad_ver in bad_ver_strs:
< bv = (scons_ver(bad_ver[0]), scons_ver(bad_ver[1]))
< if compare_versions(sc_ver, bv[0]) != -1 and\
< compare_versions(sc_ver, bv[1]) != 1:
< print "The version of SCons that you have installed: ", SCons.__version__
< print "has a bug that prevents it from working correctly with M5."
< print "Please install a version NOT contained within the following",
< print "ranges (inclusive):"
< for bad_ver in bad_ver_strs:
< print " %s - %s" % bad_ver
< Exit(2)
<
< CheckSCons((
< # We need a version that is 0.96.91 or newer
< ('0.0.0', '0.96.90'),
< ))
<
<
157a149,167
> ###################################################
> # Mercurial Stuff.
> # 1) Grab repository revision if we know it.
> # 2) Ensure that the style hook is in place.
> ###################################################
>
> hg_info = "Unknown"
> try:
> if not exists(ROOT) or not isdir(ROOT) or \
> not exists(joinpath(ROOT, ".hg")):
> raise ValueError(".hg directory not found")
> hg_info = read_command("cd %s; hg id -n -i -t -b" % ROOT).strip()
> except ImportError, e:
> print "Mercurial not found"
> except ValueError, e:
> print e
> except Exception, e:
> print "Other mercurial exception: %s" % e
>
185a196
>
194c205
< Default(os.environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
---
> Default(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
214,215c225,226
< abs_targets = map(lambda x: os.path.normpath(joinpath(launch_dir, str(x))),
< COMMAND_LINE_TARGETS)
---
> abs_targets = [ normpath(joinpath(launch_dir, str(x))) for x in \
> COMMAND_LINE_TARGETS]
218,219c229,230
< abs_targets = map(lambda x: os.path.normpath(joinpath(ROOT, str(x))),
< DEFAULT_TARGETS)
---
> abs_targets = [ normpath(joinpath(ROOT, str(x))) for x in \
> DEFAULT_TARGETS]
224c235
< build_paths = []
---
> variant_paths = []
241,243c252,254
< build_path = joinpath('/',*path_dirs[:build_top+2])
< if build_path not in build_paths:
< build_paths.append(build_path)
---
> variant_path = joinpath('/',*path_dirs[:build_top+2])
> if variant_path not in variant_paths:
> variant_paths.append(variant_path)
247c258
< os.mkdir(build_root)
---
> mkdir(build_root)
256c267
< env = Environment(ENV = os.environ, # inherit user's environment vars
---
> env = Environment(ENV = environ, # inherit user's environment vars
258c269,270
< SRCDIR = SRCDIR)
---
> SRCDIR = SRCDIR,
> HG_INFO = hg_info)
262c274
< env.SConsignFile(joinpath(build_root,"sconsign"))
---
> env.SConsignFile(joinpath(build_root, "sconsign"))
270,275d281
< # I waffle on this setting... it does avoid a few painful but
< # unnecessary builds, but it also seems to make trivial builds take
< # noticeably longer.
< if False:
< env.TargetSignatures('content')
<
277c283
< # Set up global sticky options... these are common to an entire build
---
> # Set up global sticky variables... these are common to an entire build
281c287
< # Option validators & converters for global sticky options
---
> # Variable validators & converters for global sticky variables
285c291
< f = lambda p: os.path.abspath(os.path.expanduser(p))
---
> f = lambda p: abspath(expanduser(p))
296c302
< global_sticky_opts_file = joinpath(build_root, 'options.global')
---
> global_sticky_vars_file = joinpath(build_root, 'variables.global')
298c304
< global_sticky_opts = Options(global_sticky_opts_file, args=ARGUMENTS)
---
> global_sticky_vars = Variables(global_sticky_vars_file, args=ARGUMENTS)
300,302c306,308
< global_sticky_opts.AddOptions(
< ('CC', 'C compiler', os.environ.get('CC', env['CC'])),
< ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
---
> global_sticky_vars.AddVariables(
> ('CC', 'C compiler', environ.get('CC', env['CC'])),
> ('CXX', 'C++ compiler', environ.get('CXX', env['CXX'])),
309d314
<
313a319
> Global sticky options:
316,317c322
< help_text += "Global sticky options:\n" \
< + global_sticky_opts.GenerateHelpText(env)
---
> help_text += global_sticky_vars.GenerateHelpText(env)
319,320c324,325
< # Update env with values from ARGUMENTS & file global_sticky_opts_file
< global_sticky_opts.Update(env)
---
> # Update env with values from ARGUMENTS & file global_sticky_vars_file
> global_sticky_vars.Update(env)
322,323c327,328
< # Save sticky option settings back to current options file
< global_sticky_opts.Save(global_sticky_opts_file, env)
---
> # Save sticky variable settings back to current variables file
> global_sticky_vars.Save(global_sticky_vars_file, env)
325c330
< # Parse EXTRAS option to build list of all directories where we're
---
> # Parse EXTRAS variable to build list of all directories where we're
338,346c343,345
< env['GCC'] = subprocess.Popen(env['CXX'] + ' --version', shell=True,
< stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
< close_fds=True).communicate()[0].find('g++') >= 0
< env['SUNCC'] = subprocess.Popen(env['CXX'] + ' -V', shell=True,
< stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
< close_fds=True).communicate()[0].find('Sun C++') >= 0
< env['ICC'] = subprocess.Popen(env['CXX'] + ' -V', shell=True,
< stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
< close_fds=True).communicate()[0].find('Intel') >= 0
---
> env['GCC'] = read_command(env['CXX'] + ' --version').find('g++') >= 0
> env['SUNCC'] = read_command(env['CXX'] + ' -V').find('Sun C++') >= 0
> env['ICC'] = read_command(env['CXX'] + ' -V').find('Intel') >= 0
351d349
<
393c391
< swig_version = os.popen('swig -version').read().split()
---
> swig_version = read_command('swig -version').split()
473,475c471
< if int(subprocess.Popen('sysctl -n hw.cpu64bit_capable', shell=True,
< stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
< close_fds=True).communicate()[0][0]):
---
> if int(read_command('sysctl -n hw.cpu64bit_capable')[0]):
506a503
> from distutils import sysconfig
508,510c505
< # Get brief Python version name (e.g., "python2.4") for locating
< # include & library files
< py_version_name = 'python' + sys.version[:3]
---
> py_getvar = sysconfig.get_config_var
512,515c507,531
< # include path, e.g. /usr/local/include/python2.4
< py_header_path = joinpath(sys.exec_prefix, 'include', py_version_name)
< env.Append(CPPPATH = py_header_path)
< # verify that it works
---
> py_version = 'python' + py_getvar('VERSION')
>
> py_general_include = sysconfig.get_python_inc()
> py_platform_include = sysconfig.get_python_inc(plat_specific=True)
> py_includes = [ py_general_include ]
> if py_platform_include != py_general_include:
> py_includes.append(py_platform_include)
>
> py_lib_path = []
> # add the prefix/lib/pythonX.Y/config dir, but only if there is no
> # shared library in prefix/lib/.
> if not py_getvar('Py_ENABLE_SHARED'):
> py_lib_path.append('-L' + py_getvar('LIBPL'))
>
> py_libs = []
> for lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split():
> if lib not in py_libs:
> py_libs.append(lib)
> py_libs.append('-l' + py_version)
>
> env.Append(CPPPATH=py_includes)
> env.Append(LIBPATH=py_lib_path)
> #env.Append(LIBS=py_libs)
>
> # verify that this stuff works
517c533
< print "Error: can't find Python.h header in", py_header_path
---
> print "Error: can't find Python.h header in", py_includes
520,532c536,541
< # add library path too if it's not in the default place
< py_lib_path = None
< if sys.exec_prefix != '/usr':
< py_lib_path = joinpath(sys.exec_prefix, 'lib')
< elif sys.platform == 'cygwin':
< # cygwin puts the .dll in /bin for some reason
< py_lib_path = '/bin'
< if py_lib_path:
< env.Append(LIBPATH = py_lib_path)
< print 'Adding', py_lib_path, 'to LIBPATH for', py_version_name
< if not conf.CheckLib(py_version_name):
< print "Error: can't find Python library", py_version_name
< Exit(1)
---
> for lib in py_libs:
> assert lib.startswith('-l')
> lib = lib[2:]
> if not conf.CheckLib(lib):
> print "Error: can't find library %s required by python" % lib
> Exit(1)
553a563,564
> ######################################################################
> #
554a566
> #
556c568
< have_mysql = mysql_config != None
---
> have_mysql = bool(mysql_config)
560c572
< mysql_version = os.popen(mysql_config + ' --version').read()
---
> mysql_version = read_command(mysql_config + ' --version')
576a589,592
> ######################################################################
> #
> # Finish the configuration
> #
578a595,599
> ######################################################################
> #
> # Collect all non-global variables
> #
>
588c609
< # Sticky options get saved in the options file so they persist from
---
> # Sticky variables get saved in the variables file so they persist from
591,592c612,613
< sticky_opts = Options(args=ARGUMENTS)
< Export('sticky_opts')
---
> sticky_vars = Variables(args=ARGUMENTS)
> Export('sticky_vars')
594,596c615,617
< # Non-sticky options only apply to the current build.
< nonsticky_opts = Options(args=ARGUMENTS)
< Export('nonsticky_opts')
---
> # Non-sticky variables only apply to the current build.
> nonsticky_vars = Variables(args=ARGUMENTS)
> Export('nonsticky_vars')
599c620
< # above options
---
> # above variables
610,633c631,650
< sticky_opts.AddOptions(
< EnumOption('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
< BoolOption('FULL_SYSTEM', 'Full-system support', False),
< # There's a bug in scons 0.96.1 that causes ListOptions with list
< # values (more than one value) not to be able to be restored from
< # a saved option file. If this causes trouble then upgrade to
< # scons 0.96.90 or later.
< ListOption('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list),
< BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
< BoolOption('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
< False),
< BoolOption('FAST_ALLOC_STATS', 'Enable fast object allocator statistics',
< False),
< BoolOption('EFENCE', 'Link with Electric Fence malloc debugger',
< False),
< BoolOption('SS_COMPATIBLE_FP',
< 'Make floating-point results compatible with SimpleScalar',
< False),
< BoolOption('USE_SSE2',
< 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
< False),
< 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),
---
> sticky_vars.AddVariables(
> EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
> BoolVariable('FULL_SYSTEM', 'Full-system support', False),
> ListVariable('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list),
> BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False),
> BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
> False),
> BoolVariable('FAST_ALLOC_STATS', 'Enable fast object allocator statistics',
> False),
> BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger',
> False),
> BoolVariable('SS_COMPATIBLE_FP',
> 'Make floating-point results compatible with SimpleScalar',
> False),
> BoolVariable('USE_SSE2',
> 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
> False),
> BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
> BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
> BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
636,637c653,654
< nonsticky_opts.AddOptions(
< BoolOption('update_ref', 'Update test reference outputs', False)
---
> nonsticky_vars.AddVariables(
> BoolVariable('update_ref', 'Update test reference outputs', False)
640,644c657,661
< # These options get exported to #defines in config/*.hh (see src/SConscript).
< env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
< 'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
< 'FAST_ALLOC_STATS', 'SS_COMPATIBLE_FP', \
< 'USE_CHECKER', 'TARGET_ISA']
---
> # These variables get exported to #defines in config/*.hh (see src/SConscript).
> env.ExportVariables = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
> 'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
> 'FAST_ALLOC_STATS', 'SS_COMPATIBLE_FP', \
> 'USE_CHECKER', 'TARGET_ISA']
646,651d662
< # Define a handy 'no-op' action
< def no_action(target, source, env):
< return 0
<
< env.NoAction = Action(no_action, None)
<
659,661c670,672
< # option symbol to the current option setting (0 or 1). The source
< # operands are the name of the option and a Value node containing the
< # value of the option.
---
> # variable symbol to the current variable setting (0 or 1). The source
> # operands are the name of the variable and a Value node containing the
> # value of the variable.
663c674
< (option, value) = [s.get_contents() for s in source]
---
> (variable, value) = [s.get_contents() for s in source]
665c676
< print >> f, '#define', option, value
---
> print >> f, '#define', variable, value
671,672c682,683
< (option, value) = [s.get_contents() for s in source]
< return "Defining %s as %s in %s." % (option, value, target[0])
---
> (variable, value) = [s.get_contents() for s in source]
> return "Defining %s as %s in %s." % (variable, value, target[0])
680,681c691,692
< # extract option name from Builder arg
< option = str(target[0])
---
> # extract variable name from Builder arg
> variable = str(target[0])
683,684c694,695
< target = joinpath('config', option.lower() + '.hh')
< val = env[option]
---
> target = joinpath('config', variable.lower() + '.hh')
> val = env[variable]
691,692c702,703
< # Sources are option name & value (packaged in SCons Value nodes)
< return ([target], [Value(option), Value(val)])
---
> # Sources are variable name & value (packaged in SCons Value nodes)
> return ([target], [Value(variable), Value(val)])
698,723d708
< ###################################################
< #
< # Define a SCons builder for copying files. This is used by the
< # Python zipfile code in src/python/SConscript, but is placed up here
< # since it's potentially more generally applicable.
< #
< ###################################################
<
< copy_builder = Builder(action = Copy("$TARGET", "$SOURCE"))
<
< env.Append(BUILDERS = { 'CopyFile' : copy_builder })
<
< ###################################################
< #
< # Define a simple SCons builder to concatenate files.
< #
< # Used to append the Python zip archive to the executable.
< #
< ###################################################
<
< concat_builder = Builder(action = Action(['cat $SOURCES > $TARGET',
< 'chmod +x $TARGET']))
<
< env.Append(BUILDERS = { 'Concat' : concat_builder })
<
<
726c711
< build_dir = joinpath(build_root, 'libelf'),
---
> variant_dir = joinpath(build_root, 'libelf'),
731c716
< build_dir = joinpath(build_root, 'gzstream'),
---
> variant_dir = joinpath(build_root, 'gzstream'),
741c726
< def make_switching_dir(dirname, switch_headers, env):
---
> def make_switching_dir(dname, switch_headers, env):
747c732
< basename = os.path.basename(fname)
---
> bname = basename(fname)
753c738
< % (cond, isa.upper(), dirname, isa, basename))
---
> % (cond, isa.upper(), dname, isa, bname))
783,784c768,769
< for build_path in build_paths:
< print "Building in", build_path
---
> for variant_path in variant_paths:
> print "Building in", variant_path
787,788c772,773
< env = base_env.Copy()
< env['BUILDDIR'] = build_path
---
> env = base_env.Clone()
> env['BUILDDIR'] = variant_path
790c775
< # build_dir is the tail component of build path, and is used to
---
> # variant_dir is the tail component of build path, and is used to
792c777
< (build_root, build_dir) = os.path.split(build_path)
---
> (build_root, variant_dir) = splitpath(variant_path)
794,802c779,787
< # Set env options according to the build directory config.
< sticky_opts.files = []
< # Options for $BUILD_ROOT/$BUILD_DIR are stored in
< # $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 isfile(current_opts_file):
< sticky_opts.files.append(current_opts_file)
< print "Using saved options file %s" % current_opts_file
---
> # Set env variables according to the build directory config.
> sticky_vars.files = []
> # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in
> # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke
> # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings.
> current_vars_file = joinpath(build_root, 'variables', variant_dir)
> if isfile(current_vars_file):
> sticky_vars.files.append(current_vars_file)
> print "Using saved variables file %s" % current_vars_file
804c789
< # Build dir-specific options file doesn't exist.
---
> # Build dir-specific variables file doesn't exist.
807c792
< opt_dir = os.path.dirname(current_opts_file)
---
> opt_dir = dirname(current_vars_file)
809c794
< os.mkdir(opt_dir)
---
> mkdir(opt_dir)
811,812c796,797
< # Get default build options from source tree. Options are
< # normally determined by name of $BUILD_DIR, but can be
---
> # Get default build variables from source tree. Variables are
> # normally determined by name of $VARIANT_DIR, but can be
814,819c799,804
< default_opts_file = joinpath('build_opts',
< ARGUMENTS.get('default', build_dir))
< 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)
---
> default_vars_file = joinpath('build_opts',
> ARGUMENTS.get('default', variant_dir))
> if isfile(default_vars_file):
> sticky_vars.files.append(default_vars_file)
> print "Variables file %s not found,\n using defaults in %s" \
> % (current_vars_file, default_vars_file)
821,822c806,807
< print "Error: cannot find options file %s or %s" \
< % (current_opts_file, default_opts_file)
---
> print "Error: cannot find variables file %s or %s" \
> % (current_vars_file, default_vars_file)
825,827c810,812
< # Apply current option settings to env
< sticky_opts.Update(env)
< nonsticky_opts.Update(env)
---
> # Apply current variable settings to env
> sticky_vars.Update(env)
> nonsticky_vars.Update(env)
829,832c814,817
< 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)
---
> help_text += "\nSticky variables for %s:\n" % variant_dir \
> + sticky_vars.GenerateHelpText(env) \
> + "\nNon-sticky variables for %s:\n" % variant_dir \
> + nonsticky_vars.GenerateHelpText(env)
834c819
< # Process option settings.
---
> # Process variable settings.
838c823
< "forcing USE_FENV to False in", build_dir + "."
---
> "forcing USE_FENV to False in", variant_dir + "."
842c827
< print "Warning: No IEEE FP rounding mode control in", build_dir + "."
---
> print "Warning: No IEEE FP rounding mode control in", variant_dir + "."
851c836
< "forcing USE_MYSQL to False in", build_dir + "."
---
> "forcing USE_MYSQL to False in", variant_dir + "."
854c839
< print "Compiling in", build_dir, "with MySQL support."
---
> print "Compiling in", variant_dir, "with MySQL support."
858,859c843,844
< # Save sticky option settings back to current options file
< sticky_opts.Save(current_opts_file, env)
---
> # Save sticky variable settings back to current variables file
> sticky_vars.Save(current_vars_file, env)
865c850
< # to the configured options. It returns a list of environments,
---
> # to the configured variables. It returns a list of environments,
867c852
< envList = SConscript('src/SConscript', build_dir = build_path,
---
> envList = SConscript('src/SConscript', variant_dir = variant_path,
873c858
< build_dir = joinpath(build_path, 'tests', e.Label),
---
> variant_dir = joinpath(variant_path, 'tests', e.Label),