changeset 010490fd482a in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=010490fd482a
description:
        scons: re-work the *Source functions to take more information.
        Start by turning all of the *Source functions into classes
        so we can do more calculations and more easily collect the data we need.
        Add parameters to the new classes for indicating what sorts of flags the
        objects should be compiled with so we can allow certain files to be 
compiled
        without Werror for example.

diffstat:

3 files changed, 197 insertions(+), 178 deletions(-)
SConstruct         |    2 
src/SConscript     |  371 +++++++++++++++++++++++++++-------------------------
src/sim/SConscript |    2 

diffs (truncated from 619 to 300 lines):

diff -r af13ed3bea48 -r 010490fd482a SConstruct
--- a/SConstruct        Sun Apr 26 16:49:24 2009 -0700
+++ b/SConstruct        Mon May 04 16:58:24 2009 -0700
@@ -394,7 +394,7 @@
 if main['GCC']:
     main.Append(CCFLAGS='-pipe')
     main.Append(CCFLAGS='-fno-strict-aliasing')
-    main.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
+    main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
     main.Append(CXXFLAGS='-Wno-deprecated')
 elif main['ICC']:
     pass #Fix me... add warning flags once we clean up icc warnings
diff -r af13ed3bea48 -r 010490fd482a src/SConscript
--- a/src/SConscript    Sun Apr 26 16:49:24 2009 -0700
+++ b/src/SConscript    Mon May 04 16:58:24 2009 -0700
@@ -29,6 +29,7 @@
 # Authors: Nathan Binkert
 
 import array
+import bisect
 import imp
 import marshal
 import os
@@ -50,122 +51,144 @@
 
 build_env = dict([(opt, env[opt]) for opt in export_vars])
 
-def sort_list(_list):
-    """return a sorted copy of '_list'"""
-    if isinstance(_list, list):
-        _list = _list[:]
-    else:
-        _list = list(_list)
-    _list.sort()
-    return _list
+########################################################################
+# Code for adding source files of various types
+#
+class SourceMeta(type):
+    def __init__(cls, name, bases, dict):
+        super(SourceMeta, cls).__init__(name, bases, dict)
+        cls.all = []
+        
+    def get(cls, **kwargs):
+        for src in cls.all:
+            for attr,value in kwargs.iteritems():
+                if getattr(src, attr) != value:
+                    break
+            else:
+                yield src
 
-class PySourceFile(object):
+class SourceFile(object):
+    __metaclass__ = SourceMeta
+    def __init__(self, source):
+        tnode = source
+        if not isinstance(source, SCons.Node.FS.File):
+            tnode = File(source)
+
+        self.tnode = tnode
+        self.snode = tnode.srcnode()
+        self.filename = str(tnode)
+        self.dirname = dirname(self.filename)
+        self.basename = basename(self.filename)
+        index = self.basename.rfind('.')
+        if index <= 0:
+            # dot files aren't extensions
+            self.extname = self.basename, None
+        else:
+            self.extname = self.basename[:index], self.basename[index+1:]
+
+        for base in type(self).__mro__:
+            if issubclass(base, SourceFile):
+                bisect.insort_right(base.all, self)       
+
+    def __lt__(self, other): return self.filename < other.filename
+    def __le__(self, other): return self.filename <= other.filename
+    def __gt__(self, other): return self.filename > other.filename
+    def __ge__(self, other): return self.filename >= other.filename
+    def __eq__(self, other): return self.filename == other.filename
+    def __ne__(self, other): return self.filename != other.filename
+        
+class Source(SourceFile):
+    '''Add a c/c++ source file to the build'''
+    def __init__(self, source, Werror=True, swig=False, bin_only=False,
+                 skip_lib=False):
+        super(Source, self).__init__(source)
+
+        self.Werror = Werror
+        self.swig = swig
+        self.bin_only = bin_only
+        self.skip_lib = bin_only or skip_lib
+
+class PySource(SourceFile):
+    '''Add a python source file to the named package'''
     invalid_sym_char = re.compile('[^A-z0-9_]')
-    def __init__(self, package, tnode):
-        snode = tnode.srcnode()
-        filename = str(tnode)
-        pyname = basename(filename)
-        assert pyname.endswith('.py')
-        name = pyname[:-3]
+    modules = {}
+    tnodes = {}
+    symnames = {}
+    
+    def __init__(self, package, source):
+        super(PySource, self).__init__(source)
+
+        modname,ext = self.extname
+        assert ext == 'py'
+
         if package:
             path = package.split('.')
         else:
             path = []
 
         modpath = path[:]
-        if name != '__init__':
-            modpath += [name]
+        if modname != '__init__':
+            modpath += [ modname ]
         modpath = '.'.join(modpath)
 
-        arcpath = path + [ pyname ]
-        arcname = joinpath(*arcpath)
+        arcpath = path + [ self.basename ]
+        debugname = self.snode.abspath
+        if not exists(debugname):
+            debugname = self.tnode.abspath
 
-        debugname = snode.abspath
-        if not exists(debugname):
-            debugname = tnode.abspath
+        self.package = package
+        self.modname = modname
+        self.modpath = modpath
+        self.arcname = joinpath(*arcpath)
+        self.debugname = debugname
+        self.compiled = File(self.filename + 'c')
+        self.assembly = File(self.filename + '.s')
+        self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath)
 
-        self.tnode = tnode
-        self.snode = snode
-        self.pyname = pyname
-        self.package = package
-        self.modpath = modpath
-        self.arcname = arcname
-        self.debugname = debugname
-        self.compiled = File(filename + 'c')
-        self.assembly = File(filename + '.s')
-        self.symname = "PyEMB_" + self.invalid_sym_char.sub('_', modpath)
-        
+        PySource.modules[modpath] = self
+        PySource.tnodes[self.tnode] = self
+        PySource.symnames[self.symname] = self
 
-########################################################################
-# Code for adding source files of various types
-#
-cc_lib_sources = []
-def Source(source):
-    '''Add a source file to the libm5 build'''
-    if not isinstance(source, SCons.Node.FS.File):
-        source = File(source)
-
-    cc_lib_sources.append(source)
-
-cc_bin_sources = []
-def BinSource(source):
-    '''Add a source file to the m5 binary build'''
-    if not isinstance(source, SCons.Node.FS.File):
-        source = File(source)
-
-    cc_bin_sources.append(source)
-
-py_sources = []
-def PySource(package, source):
-    '''Add a python source file to the named package'''
-    if not isinstance(source, SCons.Node.FS.File):
-        source = File(source)
-
-    source = PySourceFile(package, source)
-    py_sources.append(source)
-
-sim_objects_fixed = False
-sim_object_modfiles = set()
-def SimObject(source):
+class SimObject(PySource):
     '''Add a SimObject python file as a python source object and add
     it to a list of sim object modules'''
 
-    if sim_objects_fixed:
-        raise AttributeError, "Too late to call SimObject now."
+    fixed = False
+    modnames = []
 
-    if not isinstance(source, SCons.Node.FS.File):
-        source = File(source)
+    def __init__(self, source):
+        super(SimObject, self).__init__('m5.objects', source)
+        if self.fixed:
+            raise AttributeError, "Too late to call SimObject now."
 
-    PySource('m5.objects', source)
-    modfile = basename(str(source))
-    assert modfile.endswith('.py')
-    modname = modfile[:-3]
-    sim_object_modfiles.add(modname)
+        bisect.insort_right(SimObject.modnames, self.modname)
 
-swig_sources = []
-def SwigSource(package, source):
+class SwigSource(SourceFile):
     '''Add a swig file to build'''
-    if not isinstance(source, SCons.Node.FS.File):
-        source = File(source)
-    val = source,package
-    swig_sources.append(val)
+
+    def __init__(self, package, source):
+        super(SwigSource, self).__init__(source)
+
+        modname,ext = self.extname
+        assert ext == 'i'
+
+        self.module = modname
+        cc_file = joinpath(self.dirname, modname + '_wrap.cc')
+        py_file = joinpath(self.dirname, modname + '.py')
+
+        self.cc_source = Source(cc_file, swig=True)
+        self.py_source = PySource(package, py_file)
 
 unit_tests = []
 def UnitTest(target, sources):
     if not isinstance(sources, (list, tuple)):
         sources = [ sources ]
-    
-    srcs = []
-    for source in sources:
-        if not isinstance(source, SCons.Node.FS.File):
-            source = File(source)
-        srcs.append(source)
-            
-    unit_tests.append((target, srcs))
+
+    sources = [ Source(src, skip_lib=True) for src in sources ]
+    unit_tests.append((target, sources))
 
 # Children should have access
 Export('Source')
-Export('BinSource')
 Export('PySource')
 Export('SimObject')
 Export('SwigSource')
@@ -276,7 +299,8 @@
         if fullname.startswith('m5.internal'):
             return None
 
-        if fullname in self.modules and exists(self.modules[fullname]):
+        source = self.modules.get(fullname, None)
+        if source is not None and exists(source.snode.abspath):
             return self
 
         return None
@@ -295,34 +319,28 @@
             mod.__dict__['buildEnv'] = build_env
             return mod
 
-        srcfile = self.modules[fullname]
-        if basename(srcfile) == '__init__.py':
-            mod.__path__ = fullname.split('.')
-        mod.__file__ = srcfile
+        source = self.modules[fullname]
+        if source.modname == '__init__':
+            mod.__path__ = source.modpath
+        mod.__file__ = source.snode.abspath
 
-        exec file(srcfile, 'r') in mod.__dict__
+        exec file(source.snode.abspath, 'r') in mod.__dict__
 
         return mod
 
-py_modules = {}
-for source in py_sources:
-    py_modules[source.modpath] = source.snode.abspath
-
 # install the python importer so we can grab stuff from the source
 # tree itself.  We can't have SimObjects added after this point or
 # else we won't know about them for the rest of the stuff.
-sim_objects_fixed = True
-importer = DictImporter(py_modules)
+SimObject.fixed = True
+importer = DictImporter(PySource.modules)
 sys.meta_path[0:0] = [ importer ]
 
 import m5
 
 # import all sim objects so we can populate the all_objects list
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to