Regression tests now run under scons!
For example, 'scons ALPHA_SE/test/opt/quick' will build ALPHA_SE/m5.opt if necessary and run all the self-identified "quick" tests on it. Other possibilities: - Run just test1: scons ALPHA_SE/test/opt/test1 - Run all tests: scons ALPHA_SE/test/opt - Run all tests on debug build: scons ALPHA_SE/test/debug - Update test1 reference outputs in m5-test: scons update_ref=y ALPHA_SE/test/opt/test1 The proper tests will be selected based on the setting of FULL_SYSTEM, ALPHA_TLASER, etc. README: Update directions to use scons-based test invocation. SConscript: Return list of generated build environments to SConstruct so it can associate tests with each of them. Set 'M5Binary' attribute on each env to record name of generated binary to be tested. build/SConstruct: - Support invoking m5-test tests via scons. - Add new non-sticky option category, for 'update_ref'. - Move existing "sticky" option definitions out of build_dir loop. Someday we can generate help text from these. - Make 'CC' and 'CXX' sticky options; use environment vars as defaults if available. - Make config builder more scons-y. python/m5/__init__.py: Make AddToPath() correctly handle relative path arguments. Assumes that sys.path[0] has the directory where the current Python file lives; new m5execfile() function sets this up properly for exec'd files. --HG-- extra : convert_revision : 48896688592e210d8e63f96c34e57474853d0e66
This commit is contained in:
parent
9196fbfe5e
commit
845bdb0d8e
4 changed files with 156 additions and 76 deletions
16
README
16
README
|
@ -61,21 +61,15 @@ make) to run N jobs in parallel.
|
||||||
|
|
||||||
To build and test the syscall-emulation simulator:
|
To build and test the syscall-emulation simulator:
|
||||||
|
|
||||||
1. In $top/m5/build, run "scons ALPHA_SE/m5.opt".
|
cd $top/m5/build
|
||||||
2. In $top/m5-test, run "./do-tests.pl -B ALPHA_SE".
|
scons ALPHA_SE/test/opt/quick
|
||||||
|
|
||||||
The tests should end with "finished do-tests successfully!"
|
|
||||||
Note: if you're running under Cygwin, several tests will fail with an
|
|
||||||
"EIO trace inconsistency: ICNT mismatch" error. This is due to the
|
|
||||||
lack of fesetround() under Cygwin causing differences in floating-point
|
|
||||||
rounding. Other than that discrepancy your simulator is working perfectly.
|
|
||||||
|
|
||||||
To build and test the full-system simualator:
|
To build and test the full-system simualator:
|
||||||
|
|
||||||
1. Download the full-system binary package from XXX. This package includes
|
1. Download the full-system binary package from
|
||||||
|
http://m5.eecs.umich.edu/dist/m5_system_1.1.tar.bz2. This package includes
|
||||||
disk images and kernel, palcode, and console binaries for Linux and FreeBSD.
|
disk images and kernel, palcode, and console binaries for Linux and FreeBSD.
|
||||||
2. Edit SYSTEMDIR in $top/m5-test/SysPaths.py to point to your local copy
|
2. Edit SYSTEMDIR in $top/m5-test/SysPaths.py to point to your local copy
|
||||||
of the binaries.
|
of the binaries.
|
||||||
3. In $top/m5/build, run "scons ALPHA_FS/m5.opt".
|
3. In $top/m5/build, run "scons ALPHA_FS/opt/test/quick".
|
||||||
4. In $top/m5-test, run "./do-tests.pl -B ALPHA_FS".
|
|
||||||
|
|
||||||
|
|
49
SConscript
49
SConscript
|
@ -430,25 +430,42 @@ def make_objs(sources, env):
|
||||||
env.Append(CPPPATH='.')
|
env.Append(CPPPATH='.')
|
||||||
|
|
||||||
# Debug binary
|
# Debug binary
|
||||||
debug = env.Copy(OBJSUFFIX='.do')
|
debugEnv = env.Copy(OBJSUFFIX='.do')
|
||||||
debug.Append(CCFLAGS=Split('-g -gstabs+ -O0'))
|
debugEnv.Label = 'debug'
|
||||||
debug.Append(CPPDEFINES='DEBUG')
|
debugEnv.Append(CCFLAGS=Split('-g -gstabs+ -O0'))
|
||||||
debug.Program(target = 'm5.debug', source = make_objs(sources, debug))
|
debugEnv.Append(CPPDEFINES='DEBUG')
|
||||||
|
tlist = debugEnv.Program(target = 'm5.debug',
|
||||||
|
source = make_objs(sources, debugEnv))
|
||||||
|
debugEnv.M5Binary = tlist[0]
|
||||||
|
|
||||||
# Optimized binary
|
# Optimized binary
|
||||||
opt = env.Copy()
|
optEnv = env.Copy()
|
||||||
opt.Append(CCFLAGS=Split('-g -O5'))
|
optEnv.Label = 'opt'
|
||||||
opt.Program(target = 'm5.opt', source = make_objs(sources, opt))
|
optEnv.Append(CCFLAGS=Split('-g -O5'))
|
||||||
|
tlist = optEnv.Program(target = 'm5.opt',
|
||||||
|
source = make_objs(sources, optEnv))
|
||||||
|
optEnv.M5Binary = tlist[0]
|
||||||
|
|
||||||
# "Fast" binary
|
# "Fast" binary
|
||||||
fast = env.Copy(OBJSUFFIX='.fo')
|
fastEnv = env.Copy(OBJSUFFIX='.fo')
|
||||||
fast.Append(CCFLAGS=Split('-O5'))
|
fastEnv.Label = 'fast'
|
||||||
fast.Append(CPPDEFINES='NDEBUG')
|
fastEnv.Append(CCFLAGS=Split('-O5'))
|
||||||
fast.Program(target = 'm5.fast.unstripped', source = make_objs(sources, fast))
|
fastEnv.Append(CPPDEFINES='NDEBUG')
|
||||||
fast.Command(target = 'm5.fast', source = 'm5.fast.unstripped',
|
fastEnv.Program(target = 'm5.fast.unstripped',
|
||||||
action = 'strip $SOURCE -o $TARGET')
|
source = make_objs(sources, fastEnv))
|
||||||
|
tlist = fastEnv.Command(target = 'm5.fast',
|
||||||
|
source = 'm5.fast.unstripped',
|
||||||
|
action = 'strip $SOURCE -o $TARGET')
|
||||||
|
fastEnv.M5Binary = tlist[0]
|
||||||
|
|
||||||
# Profiled binary
|
# Profiled binary
|
||||||
prof = env.Copy(OBJSUFFIX='.po')
|
profEnv = env.Copy(OBJSUFFIX='.po')
|
||||||
prof.Append(CCFLAGS=Split('-O5 -g -pg'), LINKFLAGS='-pg')
|
profEnv.Label = 'prof'
|
||||||
prof.Program(target = 'm5.prof', source = make_objs(sources, prof))
|
profEnv.Append(CCFLAGS=Split('-O5 -g -pg'), LINKFLAGS='-pg')
|
||||||
|
tlist = profEnv.Program(target = 'm5.prof',
|
||||||
|
source = make_objs(sources, profEnv))
|
||||||
|
profEnv.M5Binary = tlist[0]
|
||||||
|
|
||||||
|
envList = [debugEnv, optEnv, fastEnv, profEnv]
|
||||||
|
|
||||||
|
Return('envList')
|
||||||
|
|
146
build/SConstruct
146
build/SConstruct
|
@ -160,11 +160,11 @@ env = Environment(ENV = os.environ, # inherit user's environment vars
|
||||||
|
|
||||||
env.SConsignFile("sconsign")
|
env.SConsignFile("sconsign")
|
||||||
|
|
||||||
if os.environ.has_key('CC'):
|
# I waffle on this setting... it does avoid a few painful but
|
||||||
env.Replace(CC=os.environ['CC'])
|
# unnecessary builds, but it also seems to make trivial builds take
|
||||||
|
# noticeably longer.
|
||||||
if os.environ.has_key('CXX'):
|
if False:
|
||||||
env.Replace(CXX=os.environ['CXX'])
|
env.TargetSignatures('content')
|
||||||
|
|
||||||
# M5_EXT is used by isa_parser.py to find the PLY package.
|
# M5_EXT is used by isa_parser.py to find the PLY package.
|
||||||
env.Append(ENV = { 'M5_EXT' : EXT_SRCDIR })
|
env.Append(ENV = { 'M5_EXT' : EXT_SRCDIR })
|
||||||
|
@ -220,27 +220,91 @@ if have_mysql:
|
||||||
|
|
||||||
env = conf.Finish()
|
env = conf.Finish()
|
||||||
|
|
||||||
# The source operand is a Value node containing the value of the option.
|
# Sticky options get saved in the options file so they persist from
|
||||||
def build_config_file(target, source, env, option):
|
# one invocation to the next (unless overridden, in which case the new
|
||||||
f = file(str(target[0]), 'w')
|
# value becomes sticky).
|
||||||
print >> f, '#define', option, int(eval(str(source[0])))
|
sticky_opts = Options(args=ARGUMENTS)
|
||||||
f.close()
|
sticky_opts.AddOptions(
|
||||||
return None
|
EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha')),
|
||||||
|
BoolOption('FULL_SYSTEM', 'Full-system support', False),
|
||||||
|
BoolOption('ALPHA_TLASER',
|
||||||
|
'Model Alpha TurboLaser platform (vs. Tsunami)', False),
|
||||||
|
BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
|
||||||
|
BoolOption('EFENCE', 'Link with Electric Fence malloc debugger',
|
||||||
|
False),
|
||||||
|
BoolOption('SS_COMPATIBLE_FP',
|
||||||
|
'Make floating-point results compatible with SimpleScalar',
|
||||||
|
False),
|
||||||
|
BoolOption('STATS_BINNING', 'Bin statistics by CPU mode', have_mysql),
|
||||||
|
BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
|
||||||
|
BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
|
||||||
|
('CC', 'C compiler', os.environ.get('CC', env['CC'])),
|
||||||
|
('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX']))
|
||||||
|
)
|
||||||
|
|
||||||
def config_builder(env, option):
|
# Non-sticky options only apply to the current build.
|
||||||
target = os.path.join('config', option.lower() + '.hh')
|
nonsticky_opts = Options(args=ARGUMENTS)
|
||||||
source = Value(env[option])
|
nonsticky_opts.AddOptions(
|
||||||
def my_build_config_file(target, source, env):
|
BoolOption('update_ref', 'Update test reference outputs', False)
|
||||||
build_config_file(target, source, env, option)
|
)
|
||||||
env.Command(target, source, my_build_config_file)
|
|
||||||
|
|
||||||
env.Append(BUILDERS = { 'ConfigFile' : config_builder })
|
# These options get exported to #defines in config/*.hh (see m5/SConscript).
|
||||||
|
env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
|
||||||
|
'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
|
||||||
|
'STATS_BINNING']
|
||||||
|
|
||||||
|
# Define a handy 'no-op' action
|
||||||
|
def no_action(target, source, env):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
env.NoAction = Action(no_action, None)
|
||||||
|
|
||||||
# libelf build is described in its own SConscript file.
|
# libelf build is described in its own SConscript file.
|
||||||
# SConscript-global is the build in build/libelf shared among all
|
# SConscript-global is the build in build/libelf shared among all
|
||||||
# configs.
|
# configs.
|
||||||
env.SConscript('m5/libelf/SConscript-global', exports = 'env')
|
env.SConscript('m5/libelf/SConscript-global', exports = 'env')
|
||||||
|
|
||||||
|
###################################################
|
||||||
|
#
|
||||||
|
# Define a SCons builder for configuration flag headers.
|
||||||
|
#
|
||||||
|
###################################################
|
||||||
|
|
||||||
|
# This function generates a config header file that #defines the
|
||||||
|
# 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.
|
||||||
|
def build_config_file(target, source, env):
|
||||||
|
(option, value) = [s.get_contents() for s in source]
|
||||||
|
f = file(str(target[0]), 'w')
|
||||||
|
print >> f, '#define', option, value
|
||||||
|
f.close()
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Generate the message to be printed when building the config file.
|
||||||
|
def build_config_file_string(target, source, env):
|
||||||
|
(option, value) = [s.get_contents() for s in source]
|
||||||
|
return "Defining %s as %s in %s." % (option, value, target[0])
|
||||||
|
|
||||||
|
# Combine the two functions into a scons Action object.
|
||||||
|
config_action = Action(build_config_file, build_config_file_string)
|
||||||
|
|
||||||
|
# The emitter munges the source & target node lists to reflect what
|
||||||
|
# we're really doing.
|
||||||
|
def config_emitter(target, source, env):
|
||||||
|
# extract option name from Builder arg
|
||||||
|
option = str(target[0])
|
||||||
|
# True target is config header file
|
||||||
|
target = os.path.join('config', option.lower() + '.hh')
|
||||||
|
# Force value to 0/1 even if it's a Python bool
|
||||||
|
val = int(eval(str(env[option])))
|
||||||
|
# Sources are option name & value (packaged in SCons Value nodes)
|
||||||
|
return ([target], [Value(option), Value(val)])
|
||||||
|
|
||||||
|
config_builder = Builder(emitter = config_emitter, action = config_action)
|
||||||
|
|
||||||
|
env.Append(BUILDERS = { 'ConfigFile' : config_builder })
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
#
|
#
|
||||||
# Define build environments for selected configurations.
|
# Define build environments for selected configurations.
|
||||||
|
@ -255,31 +319,13 @@ for build_dir in build_dirs:
|
||||||
env = base_env.Copy()
|
env = base_env.Copy()
|
||||||
# Set env according to the build directory config.
|
# Set env according to the build directory config.
|
||||||
options_file = os.path.join('build_options', build_dir)
|
options_file = os.path.join('build_options', build_dir)
|
||||||
if not os.path.isfile(options_file):
|
if os.path.isfile(options_file):
|
||||||
|
sticky_opts.files = [options_file]
|
||||||
|
else:
|
||||||
print "Options file %s not found, using defaults." % options_file
|
print "Options file %s not found, using defaults." % options_file
|
||||||
opts = Options(options_file, ARGUMENTS)
|
|
||||||
opts.AddOptions(
|
|
||||||
EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha')),
|
|
||||||
BoolOption('FULL_SYSTEM', 'Full-system support', False),
|
|
||||||
BoolOption('ALPHA_TLASER',
|
|
||||||
'Model Alpha TurboLaser platform (vs. Tsunami)', False),
|
|
||||||
BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
|
|
||||||
BoolOption('EFENCE', 'Link with Electric Fence malloc debugger',
|
|
||||||
False),
|
|
||||||
BoolOption('SS_COMPATIBLE_FP',
|
|
||||||
'Make floating-point results compatible with SimpleScalar',
|
|
||||||
False),
|
|
||||||
BoolOption('STATS_BINNING', 'Bin statistics by CPU mode', have_mysql),
|
|
||||||
BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
|
|
||||||
BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv)
|
|
||||||
)
|
|
||||||
|
|
||||||
opts.Update(env)
|
sticky_opts.Update(env)
|
||||||
opts.Save(options_file, env)
|
nonsticky_opts.Update(env)
|
||||||
|
|
||||||
env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
|
|
||||||
'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
|
|
||||||
'STATS_BINNING']
|
|
||||||
|
|
||||||
# Process option settings.
|
# Process option settings.
|
||||||
|
|
||||||
|
@ -305,11 +351,21 @@ for build_dir in build_dirs:
|
||||||
print "Compiling in", build_dir, "with MySQL support."
|
print "Compiling in", build_dir, "with MySQL support."
|
||||||
env.ParseConfig(mysql_config_libs)
|
env.ParseConfig(mysql_config_libs)
|
||||||
env.ParseConfig(mysql_config_include)
|
env.ParseConfig(mysql_config_include)
|
||||||
|
|
||||||
|
# Save sticky option settings back to file
|
||||||
|
sticky_opts.Save(options_file, env)
|
||||||
|
|
||||||
# The m5/SConscript file sets up the build rules in 'env' according
|
# The m5/SConscript file sets up the build rules in 'env' according
|
||||||
# to the configured options.
|
# to the configured options. It returns a list of environments,
|
||||||
SConscript('m5/SConscript', build_dir = build_dir, exports = 'env',
|
# one for each variant build (debug, opt, etc.)
|
||||||
duplicate=0)
|
envList = SConscript('m5/SConscript', build_dir = build_dir,
|
||||||
|
exports = 'env', duplicate = False)
|
||||||
|
|
||||||
|
# Set up the regression tests for each build.
|
||||||
|
for e in envList:
|
||||||
|
SConscript('m5-test/SConscript',
|
||||||
|
build_dir = os.path.join(build_dir, 'test', e.Label),
|
||||||
|
exports = { 'env' : e }, duplicate = False)
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
#
|
#
|
||||||
|
|
|
@ -31,12 +31,25 @@ def panic(string):
|
||||||
print >>sys.stderr, 'panic:', string
|
print >>sys.stderr, 'panic:', string
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Add given directory to system module search path, if it is not
|
def m5execfile(f, global_dict):
|
||||||
# already there.
|
# copy current sys.path
|
||||||
|
oldpath = sys.path[:]
|
||||||
|
# push file's directory onto front of path
|
||||||
|
sys.path.insert(0, os.path.abspath(os.path.dirname(f)))
|
||||||
|
execfile(f, global_dict)
|
||||||
|
# restore original path
|
||||||
|
sys.path = oldpath
|
||||||
|
|
||||||
|
# Prepend given directory to system module search path.
|
||||||
def AddToPath(path):
|
def AddToPath(path):
|
||||||
|
# if it's a relative path and we know what directory the current
|
||||||
|
# python script is in, make the path relative to that directory.
|
||||||
|
if not os.path.isabs(path) and sys.path[0]:
|
||||||
|
path = os.path.join(sys.path[0], path)
|
||||||
path = os.path.realpath(path)
|
path = os.path.realpath(path)
|
||||||
if os.path.isdir(path) and path not in sys.path:
|
# sys.path[0] should always refer to the current script's directory,
|
||||||
sys.path.append(path)
|
# so place the new dir right after that.
|
||||||
|
sys.path.insert(1, path)
|
||||||
|
|
||||||
# find the m5 compile options: must be specified as a dict in
|
# find the m5 compile options: must be specified as a dict in
|
||||||
# __main__.m5_build_env.
|
# __main__.m5_build_env.
|
||||||
|
|
Loading…
Reference in a new issue