changeset d0365cc3d05f in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=d0365cc3d05f
description:
config: Add a --without-python option to build process
Add the ability to build libgem5 without embedded Python or the
ability to configure with Python.
This is a prelude to a patch to allow config.ini files to be loaded
into libgem5 using only C++ which would make embedding gem5 within
other simulation systems easier.
This adds a few registration interfaces to things which cross
between Python and C++. Namely: stats dumping and SimObject resolving
diffstat:
SConstruct | 80 ++++++++++++----------
src/SConscript | 27 ++++--
src/base/statistics.cc | 40 +++++++++++
src/base/statistics.hh | 19 +++++
src/python/SConscript | 4 +-
src/python/m5/stats/__init__.py | 1 +
src/python/swig/pyobject.cc | 11 ++-
src/python/swig/pyobject.hh | 14 ++-
src/python/swig/stats.i | 21 +----
src/sim/SConscript | 5 +-
src/sim/debug.cc | 18 -----
src/sim/debug.hh | 2 -
src/sim/init.cc | 85 ------------------------
src/sim/init.hh | 5 -
src/sim/init_signals.cc | 138 ++++++++++++++++++++++++++++++++++++++++
src/sim/init_signals.hh | 40 +++++++++++
src/sim/main.cc | 1 +
src/sim/py_interact.cc | 51 ++++++++++++++
src/sim/py_interact.hh | 40 +++++++++++
src/sim/serialize.cc | 8 +-
src/sim/serialize.hh | 16 ++++-
src/sim/stat_register.cc | 53 +++++++++++++++
src/sim/stat_register.hh | 57 ++++++++++++++++
23 files changed, 547 insertions(+), 189 deletions(-)
diffs (truncated from 1074 to 300 lines):
diff -r be23c690f8c0 -r d0365cc3d05f SConstruct
--- a/SConstruct Thu Oct 16 05:49:31 2014 -0400
+++ b/SConstruct Thu Oct 16 05:49:32 2014 -0400
@@ -183,6 +183,9 @@
help='Update test reference outputs')
AddLocalOption('--verbose', dest='verbose', action='store_true',
help='Print full tool command lines')
+AddLocalOption('--without-python', dest='without_python',
+ action='store_true',
+ help='Build without Python configuration support')
termcap = get_termcap(GetOption('use_colors'))
@@ -884,47 +887,50 @@
print 'Using build cache located at', main['M5_BUILD_CACHE']
CacheDir(main['M5_BUILD_CACHE'])
-# Find Python include and library directories for embedding the
-# interpreter. We rely on python-config to resolve the appropriate
-# includes and linker flags. ParseConfig does not seem to understand
-# the more exotic linker flags such as -Xlinker and -export-dynamic so
-# we add them explicitly below. If you want to link in an alternate
-# version of python, see above for instructions on how to invoke
-# scons with the appropriate PATH set.
-#
-# First we check if python2-config exists, else we use python-config
-python_config = readCommand(['which', 'python2-config'], exception='').strip()
-if not os.path.exists(python_config):
- python_config = readCommand(['which', 'python-config'],
+if not GetOption('without_python'):
+ # Find Python include and library directories for embedding the
+ # interpreter. We rely on python-config to resolve the appropriate
+ # includes and linker flags. ParseConfig does not seem to understand
+ # the more exotic linker flags such as -Xlinker and -export-dynamic so
+ # we add them explicitly below. If you want to link in an alternate
+ # version of python, see above for instructions on how to invoke
+ # scons with the appropriate PATH set.
+ #
+ # First we check if python2-config exists, else we use python-config
+ python_config = readCommand(['which', 'python2-config'],
exception='').strip()
-py_includes = readCommand([python_config, '--includes'],
- exception='').split()
-# Strip the -I from the include folders before adding them to the
-# CPPPATH
-main.Append(CPPPATH=map(lambda inc: inc[2:], py_includes))
+ if not os.path.exists(python_config):
+ python_config = readCommand(['which', 'python-config'],
+ exception='').strip()
+ py_includes = readCommand([python_config, '--includes'],
+ exception='').split()
+ # Strip the -I from the include folders before adding them to the
+ # CPPPATH
+ main.Append(CPPPATH=map(lambda inc: inc[2:], py_includes))
-# Read the linker flags and split them into libraries and other link
-# flags. The libraries are added later through the call the CheckLib.
-py_ld_flags = readCommand([python_config, '--ldflags'], exception='').split()
-py_libs = []
-for lib in py_ld_flags:
- if not lib.startswith('-l'):
- main.Append(LINKFLAGS=[lib])
- else:
- lib = lib[2:]
- if lib not in py_libs:
- py_libs.append(lib)
+ # Read the linker flags and split them into libraries and other link
+ # flags. The libraries are added later through the call the CheckLib.
+ py_ld_flags = readCommand([python_config, '--ldflags'],
+ exception='').split()
+ py_libs = []
+ for lib in py_ld_flags:
+ if not lib.startswith('-l'):
+ main.Append(LINKFLAGS=[lib])
+ else:
+ lib = lib[2:]
+ if lib not in py_libs:
+ py_libs.append(lib)
-# verify that this stuff works
-if not conf.CheckHeader('Python.h', '<>'):
- print "Error: can't find Python.h header in", py_includes
- print "Install Python headers (package python-dev on Ubuntu and RedHat)"
- Exit(1)
+ # verify that this stuff works
+ if not conf.CheckHeader('Python.h', '<>'):
+ print "Error: can't find Python.h header in", py_includes
+ print "Install Python headers (package python-dev on Ubuntu and
RedHat)"
+ Exit(1)
-for lib in py_libs:
- if not conf.CheckLib(lib):
- print "Error: can't find library %s required by python" % lib
- Exit(1)
+ for lib in py_libs:
+ if not conf.CheckLib(lib):
+ print "Error: can't find library %s required by python" % lib
+ Exit(1)
# On Solaris you need to use libsocket for socket ops
if not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'):
diff -r be23c690f8c0 -r d0365cc3d05f src/SConscript
--- a/src/SConscript Thu Oct 16 05:49:31 2014 -0400
+++ b/src/SConscript Thu Oct 16 05:49:32 2014 -0400
@@ -63,6 +63,8 @@
# 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
@@ -229,7 +231,7 @@
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'
@@ -238,8 +240,8 @@
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'''
@@ -874,9 +876,9 @@
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)
+ Source(source.cpp, skip_no_python=True)
########################################################################
#
@@ -973,14 +975,19 @@
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)
diff -r be23c690f8c0 -r d0365cc3d05f src/base/statistics.cc
--- a/src/base/statistics.cc Thu Oct 16 05:49:31 2014 -0400
+++ b/src/base/statistics.cc Thu Oct 16 05:49:32 2014 -0400
@@ -462,10 +462,32 @@
return root ? root->str() : "";
}
+Handler resetHandler = NULL;
+Handler dumpHandler = NULL;
+
+void
+registerHandlers(Handler reset_handler, Handler dump_handler)
+{
+ resetHandler = reset_handler;
+ dumpHandler = dump_handler;
+}
+
CallbackQueue dumpQueue;
CallbackQueue resetQueue;
void
+processResetQueue()
+{
+ resetQueue.process();
+}
+
+void
+processDumpQueue()
+{
+ dumpQueue.process();
+}
+
+void
registerResetCallback(Callback *cb)
{
resetQueue.add(cb);
@@ -489,6 +511,24 @@
}
void
+dump()
+{
+ if (dumpHandler)
+ dumpHandler();
+ else
+ fatal("No registered Stats::dump handler");
+}
+
+void
+reset()
+{
+ if (resetHandler)
+ resetHandler();
+ else
+ fatal("No registered Stats::reset handler");
+}
+
+void
registerDumpCallback(Callback *cb)
{
dumpQueue.add(cb);
diff -r be23c690f8c0 -r d0365cc3d05f src/base/statistics.hh
--- a/src/base/statistics.hh Thu Oct 16 05:49:31 2014 -0400
+++ b/src/base/statistics.hh Thu Oct 16 05:49:32 2014 -0400
@@ -3209,6 +3209,15 @@
bool enabled();
/**
+ * Register reset and dump handlers. These are the functions which
+ * will actually perform the whole statistics reset/dump actions
+ * including processing the reset/dump callbacks
+ */
+typedef void (*Handler)();
+
+void registerHandlers(Handler reset_handler, Handler dump_handler);
+
+/**
* Register a callback that should be called whenever statistics are
* reset
*/
@@ -3220,6 +3229,16 @@
*/
void registerDumpCallback(Callback *cb);
+/**
+ * Process all the callbacks in the reset callbacks queue
+ */
+void processResetQueue();
+
+/**
+ * Process all the callbacks in the dump callbacks queue
+ */
+void processDumpQueue();
+
std::list<Info *> &statsList();
typedef std::map<const void *, Info *> MapType;
diff -r be23c690f8c0 -r d0365cc3d05f src/python/SConscript
--- a/src/python/SConscript Thu Oct 16 05:49:31 2014 -0400
+++ b/src/python/SConscript Thu Oct 16 05:49:32 2014 -0400
@@ -31,8 +31,8 @@
Import('*')
-Source('swig/pyevent.cc')
-Source('swig/pyobject.cc')
+Source('swig/pyevent.cc', skip_no_python=True)
+Source('swig/pyobject.cc', skip_no_python=True)
PySource('', 'importer.py')
PySource('m5', 'm5/__init__.py')
diff -r be23c690f8c0 -r d0365cc3d05f src/python/m5/stats/__init__.py
--- a/src/python/m5/stats/__init__.py Thu Oct 16 05:49:31 2014 -0400
+++ b/src/python/m5/stats/__init__.py Thu Oct 16 05:49:32 2014 -0400
@@ -41,6 +41,7 @@
def initSimStats():
internal.stats.initSimStats()
+ internal.stats.registerPythonStatsHandlers()
names = []
stats_dict = {}
diff -r be23c690f8c0 -r d0365cc3d05f src/python/swig/pyobject.cc
--- a/src/python/swig/pyobject.cc Thu Oct 16 05:49:31 2014 -0400
+++ b/src/python/swig/pyobject.cc Thu Oct 16 05:49:32 2014 -0400
@@ -157,9 +157,12 @@
// these in sim/main.cc as well that are handled without this define.
#define PCC(s) const_cast<char *>(s)
+/** Single instance of PythonSimObjectResolver as its action is effectively
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev