# false). Current filters are:
# main -- specifies the gem5 main() function
# skip_lib -- do not put this file into the gem5 library
+# skip_no_python -- do not put this file into a no_python library
+# as it embeds compiled Python
# <unittest> -- unit tests use filters based on the unit test name
#
# A parent can now be specified for a source file and default filter
def __init__(self, package, source, **guards):
'''Specify the python package, the source file, and any guards'''
- super(SwigSource, self).__init__(source, **guards)
+ super(SwigSource, self).__init__(source, skip_no_python=True, **guards)
modname,ext = self.extname
assert ext == 'i'
cc_file = joinpath(self.dirname, modname + '_wrap.cc')
py_file = joinpath(self.dirname, modname + '.py')
- self.cc_source = Source(cc_file, swig=True, parent=self)
- self.py_source = PySource(package, py_file, parent=self)
+ self.cc_source = Source(cc_file, swig=True, parent=self, **guards)
+ self.py_source = PySource(package, py_file, parent=self, **guards)
class ProtoBuf(SourceFile):
'''Add a Protocol Buffer to build'''
''')
+ # create defines for the preprocessing and compile-time determination
for i,isa in enumerate(isas):
code('#define $0 $1', define(isa), i + 1)
+ code()
+
+ # create an enum for any run-time determination of the ISA, we
+ # reuse the same name as the namespaces
+ code('enum class Arch {')
+ for i,isa in enumerate(isas):
+ if i + 1 == len(isas):
+ code(' $0 = $1', namespace(isa), define(isa))
+ else:
+ code(' $0 = $1,', namespace(isa), define(isa))
+ code('};')
code('''
obj.cxx_param_decl(code)
code.write(target[0].abspath)
+def createSimObjectCxxConfig(is_header):
+ def body(target, source, env):
+ assert len(target) == 1 and len(source) == 1
+
+ name = str(source[0].get_contents())
+ obj = sim_objects[name]
+
+ code = code_formatter()
+ obj.cxx_config_param_file(code, is_header)
+ code.write(target[0].abspath)
+ return body
+
def createParamSwigWrapper(target, source, env):
assert len(target) == 1 and len(source) == 1
obj.swig_decl(code)
code.write(target[0].abspath)
+# dummy target for generated code
+# we start out with all the Source files so they get copied to build/*/ also.
+SWIG = env.Dummy('swig', [s.tnode for s in Source.get()])
+
# Generate all of the SimObject param C++ struct header files
params_hh_files = []
for name,simobj in sorted(sim_objects.iteritems()):
env.Command(hh_file, Value(name),
MakeAction(createSimObjectParamStruct, Transform("SO PARAM")))
env.Depends(hh_file, depends + extra_deps)
+ env.Depends(SWIG, hh_file)
+
+# C++ parameter description files
+if GetOption('with_cxx_config'):
+ for name,simobj in sorted(sim_objects.iteritems()):
+ py_source = PySource.modules[simobj.__module__]
+ extra_deps = [ py_source.tnode ]
+
+ cxx_config_hh_file = File('cxx_config/%s.hh' % name)
+ cxx_config_cc_file = File('cxx_config/%s.cc' % name)
+ env.Command(cxx_config_hh_file, Value(name),
+ MakeAction(createSimObjectCxxConfig(True),
+ Transform("CXXCPRHH")))
+ env.Command(cxx_config_cc_file, Value(name),
+ MakeAction(createSimObjectCxxConfig(False),
+ Transform("CXXCPRCC")))
+ env.Depends(cxx_config_hh_file, depends + extra_deps +
+ [File('params/%s.hh' % name), File('sim/cxx_config.hh')])
+ env.Depends(cxx_config_cc_file, depends + extra_deps +
+ [cxx_config_hh_file])
+ Source(cxx_config_cc_file)
+
+ cxx_config_init_cc_file = File('cxx_config/init.cc')
+
+ def createCxxConfigInitCC(target, source, env):
+ assert len(target) == 1 and len(source) == 1
+
+ code = code_formatter()
+
+ for name,simobj in sorted(sim_objects.iteritems()):
+ if not hasattr(simobj, 'abstract') or not simobj.abstract:
+ code('#include "cxx_config/${name}.hh"')
+ code()
+ code('void cxxConfigInit()')
+ code('{')
+ code.indent()
+ for name,simobj in sorted(sim_objects.iteritems()):
+ not_abstract = not hasattr(simobj, 'abstract') or \
+ not simobj.abstract
+ if not_abstract and 'type' in simobj.__dict__:
+ code('cxx_config_directory["${name}"] = '
+ '${name}CxxConfigParams::makeDirectoryEntry();')
+ code.dedent()
+ code('}')
+ code.write(target[0].abspath)
+
+ py_source = PySource.modules[simobj.__module__]
+ extra_deps = [ py_source.tnode ]
+ env.Command(cxx_config_init_cc_file, Value(name),
+ MakeAction(createCxxConfigInitCC, Transform("CXXCINIT")))
+ cxx_param_hh_files = ["cxx_config/%s.hh" % simobj
+ for simobj in sorted(sim_objects.itervalues())
+ if not hasattr(simobj, 'abstract') or not simobj.abstract]
+ Depends(cxx_config_init_cc_file, cxx_param_hh_files +
+ [File('sim/cxx_config.hh')])
+ Source(cxx_config_init_cc_file)
# Generate any needed param SWIG wrapper files
params_i_files = []
env.Command(i_file, Value(name),
MakeAction(createParamSwigWrapper, Transform("SW PARAM")))
env.Depends(i_file, depends)
+ env.Depends(SWIG, i_file)
SwigSource('m5.internal', i_file)
# Generate all enum header files
env.Command(cc_file, Value(name),
MakeAction(createEnumStrings, Transform("ENUM STR")))
env.Depends(cc_file, depends + extra_deps)
+ env.Depends(SWIG, cc_file)
Source(cc_file)
hh_file = File('enums/%s.hh' % name)
env.Command(hh_file, Value(name),
MakeAction(createEnumDecls, Transform("ENUMDECL")))
env.Depends(hh_file, depends + extra_deps)
+ env.Depends(SWIG, hh_file)
i_file = File('python/m5/internal/enum_%s.i' % name)
env.Command(i_file, Value(name),
MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG")))
env.Depends(i_file, depends + extra_deps)
+ env.Depends(SWIG, i_file)
SwigSource('m5.internal', i_file)
# Generate SimObject SWIG wrapper files
init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file))
env.Command(init_file, Value(swig.module),
MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW")))
+ env.Depends(SWIG, init_file)
Source(init_file, **swig.guards)
# Build all protocol buffers if we have got protoc and protobuf available
'--proto_path ${SOURCE.dir} $SOURCE',
Transform("PROTOC")))
+ env.Depends(SWIG, [proto.cc_file, proto.hh_file])
# Add the C++ source file
Source(proto.cc_file, **proto.guards)
elif ProtoBuf.all:
def makeDebugFlagCC(target, source, env):
assert(len(target) == 1 and len(source) == 1)
- val = eval(source[0].get_contents())
- name, compound, desc = val
- compound = list(sorted(compound))
-
code = code_formatter()
+ # delay definition of CompoundFlags until after all the definition
+ # of all constituent SimpleFlags
+ comp_code = code_formatter()
+
# file header
code('''
/*
- * DO NOT EDIT THIS FILE! Automatically generated
+ * DO NOT EDIT THIS FILE! Automatically generated by SCons.
*/
#include "base/debug.hh"
-''')
- for flag in compound:
- code('#include "debug/$flag.hh"')
- code()
- code('namespace Debug {')
- code()
+namespace Debug {
- if not compound:
- code('SimpleFlag $name("$name", "$desc");')
- else:
- code('CompoundFlag $name("$name", "$desc",')
- code.indent()
- last = len(compound) - 1
- for i,flag in enumerate(compound):
- if i != last:
- code('$flag,')
- else:
- code('$flag);')
- code.dedent()
+''')
+
+ for name, flag in sorted(source[0].read().iteritems()):
+ n, compound, desc = flag
+ assert n == name
+ if not compound:
+ code('SimpleFlag $name("$name", "$desc");')
+ else:
+ comp_code('CompoundFlag $name("$name", "$desc",')
+ comp_code.indent()
+ last = len(compound) - 1
+ for i,flag in enumerate(compound):
+ if i != last:
+ comp_code('$flag,')
+ else:
+ comp_code('$flag);')
+ comp_code.dedent()
+
+ code.append(comp_code)
code()
code('} // namespace Debug')
# file header boilerplate
code('''\
/*
- * DO NOT EDIT THIS FILE!
- *
- * Automatically generated by SCons
+ * DO NOT EDIT THIS FILE! Automatically generated by SCons.
*/
#ifndef __DEBUG_${name}_HH__
n, compound, desc = flag
assert n == name
- env.Command('debug/%s.hh' % name, Value(flag),
+ hh_file = 'debug/%s.hh' % name
+ env.Command(hh_file, Value(flag),
MakeAction(makeDebugFlagHH, Transform("TRACING", 0)))
- env.Command('debug/%s.cc' % name, Value(flag),
- MakeAction(makeDebugFlagCC, Transform("TRACING", 0)))
- Source('debug/%s.cc' % name)
+ env.Depends(SWIG, hh_file)
+
+env.Command('debug/flags.cc', Value(debug_flags),
+ MakeAction(makeDebugFlagCC, Transform("TRACING", 0)))
+env.Depends(SWIG, 'debug/flags.cc')
+Source('debug/flags.cc')
# Embed python files. All .py files that have been indicated by a
# PySource() call in a SConscript need to be embedded into the M5
code.write(str(target[0]))
for source in PySource.all:
- env.Command(source.cpp, source.tnode,
+ env.Command(source.cpp, source.tnode,
MakeAction(embedPyFile, Transform("EMBED PY")))
- Source(source.cpp)
+ env.Depends(SWIG, source.cpp)
+ Source(source.cpp, skip_no_python=True)
########################################################################
#
if compareVersions(env['GCC_VERSION'], '4.7') >= 0:
new_env.Append(CXXFLAGS='-Wdelete-non-virtual-dtor')
swig_env.Append(CCFLAGS='-Wno-maybe-uninitialized')
+
+ # Only gcc >= 4.9 supports UBSan, so check both the version
+ # and the command-line option before adding the compiler and
+ # linker flags.
+ if GetOption('with_ubsan') and \
+ compareVersions(env['GCC_VERSION'], '4.9') >= 0:
+ new_env.Append(CCFLAGS='-fsanitize=undefined')
+ new_env.Append(LINKFLAGS='-fsanitize=undefined')
+
if env['CLANG']:
# Always enable the warning for deletion of derived classes
# with non-virtual destructors
'-Wno-deprecated-register',
])
+ # All supported clang versions have support for UBSan, so if
+ # asked to use it, append the compiler and linker flags.
+ if GetOption('with_ubsan'):
+ new_env.Append(CCFLAGS='-fsanitize=undefined')
+ new_env.Append(LINKFLAGS='-fsanitize=undefined')
+
werror_env = new_env.Clone()
werror_env.Append(CCFLAGS='-Werror')
return obj
- static_objs = \
- [ make_obj(s, True) for s in Source.get(main=False, skip_lib=False) ]
- shared_objs = \
- [ make_obj(s, False) for s in Source.get(main=False, skip_lib=False) ]
+ lib_guards = {'main': False, 'skip_lib': False}
+
+ # Without Python, leave out all SWIG and Python content from the
+ # library builds. The option doesn't affect gem5 built as a program
+ if GetOption('without_python'):
+ lib_guards['skip_no_python'] = False
+
+ static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ]
+ shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ]
static_date = make_obj(date_source, static=True, extra_deps=static_objs)
static_objs.append(static_date)
-
+
shared_date = make_obj(date_source, static=False, extra_deps=shared_objs)
shared_objs.append(shared_date)