SConscript revision 7811
17375Sgblack@eecs.umich.edu# -*- mode:python -*-
27375Sgblack@eecs.umich.edu
37375Sgblack@eecs.umich.edu# Copyright (c) 2004-2005 The Regents of The University of Michigan
47375Sgblack@eecs.umich.edu# All rights reserved.
57375Sgblack@eecs.umich.edu#
67375Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
77375Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
87375Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
97375Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
107375Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
117375Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
127375Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
137375Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
147375Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
157375Sgblack@eecs.umich.edu# this software without specific prior written permission.
167375Sgblack@eecs.umich.edu#
177375Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187375Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
197375Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
207375Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
217375Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
227375Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
237375Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
247375Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
257375Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
267375Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
277375Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
287375Sgblack@eecs.umich.edu#
297375Sgblack@eecs.umich.edu# Authors: Nathan Binkert
307375Sgblack@eecs.umich.edu
317375Sgblack@eecs.umich.eduimport array
327375Sgblack@eecs.umich.eduimport bisect
337375Sgblack@eecs.umich.eduimport imp
347375Sgblack@eecs.umich.eduimport marshal
357375Sgblack@eecs.umich.eduimport os
367375Sgblack@eecs.umich.eduimport re
377375Sgblack@eecs.umich.eduimport sys
387375Sgblack@eecs.umich.eduimport zlib
397375Sgblack@eecs.umich.edu
407375Sgblack@eecs.umich.edufrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath
417375Sgblack@eecs.umich.edu
427375Sgblack@eecs.umich.eduimport SCons
437375Sgblack@eecs.umich.edu
447378Sgblack@eecs.umich.edu# This file defines how to build a particular configuration of M5
457378Sgblack@eecs.umich.edu# based on variable settings in the 'env' build environment.
467382Sgblack@eecs.umich.edu
477375Sgblack@eecs.umich.eduImport('*')
487384Sgblack@eecs.umich.edu
497384Sgblack@eecs.umich.edu# Children need to see the environment
507384Sgblack@eecs.umich.eduExport('env')
517375Sgblack@eecs.umich.edu
527375Sgblack@eecs.umich.edubuild_env = [(opt, env[opt]) for opt in export_vars]
537375Sgblack@eecs.umich.edu
547375Sgblack@eecs.umich.edufrom m5.util import code_formatter
557375Sgblack@eecs.umich.edu
567375Sgblack@eecs.umich.edu########################################################################
577375Sgblack@eecs.umich.edu# Code for adding source files of various types
587375Sgblack@eecs.umich.edu#
597375Sgblack@eecs.umich.educlass SourceMeta(type):
607375Sgblack@eecs.umich.edu    def __init__(cls, name, bases, dict):
617375Sgblack@eecs.umich.edu        super(SourceMeta, cls).__init__(name, bases, dict)
627375Sgblack@eecs.umich.edu        cls.all = []
637375Sgblack@eecs.umich.edu        
647375Sgblack@eecs.umich.edu    def get(cls, **kwargs):
657375Sgblack@eecs.umich.edu        for src in cls.all:
667375Sgblack@eecs.umich.edu            for attr,value in kwargs.iteritems():
677375Sgblack@eecs.umich.edu                if getattr(src, attr) != value:
687375Sgblack@eecs.umich.edu                    break
697375Sgblack@eecs.umich.edu            else:
707375Sgblack@eecs.umich.edu                yield src
717375Sgblack@eecs.umich.edu
727375Sgblack@eecs.umich.educlass SourceFile(object):
737375Sgblack@eecs.umich.edu    __metaclass__ = SourceMeta
747375Sgblack@eecs.umich.edu    def __init__(self, source):
757375Sgblack@eecs.umich.edu        tnode = source
767375Sgblack@eecs.umich.edu        if not isinstance(source, SCons.Node.FS.File):
777376Sgblack@eecs.umich.edu            tnode = File(source)
787376Sgblack@eecs.umich.edu
797376Sgblack@eecs.umich.edu        self.tnode = tnode
807375Sgblack@eecs.umich.edu        self.snode = tnode.srcnode()
817375Sgblack@eecs.umich.edu        self.filename = str(tnode)
827378Sgblack@eecs.umich.edu        self.dirname = dirname(self.filename)
837378Sgblack@eecs.umich.edu        self.basename = basename(self.filename)
847378Sgblack@eecs.umich.edu        index = self.basename.rfind('.')
857378Sgblack@eecs.umich.edu        if index <= 0:
867378Sgblack@eecs.umich.edu            # dot files aren't extensions
877378Sgblack@eecs.umich.edu            self.extname = self.basename, None
887378Sgblack@eecs.umich.edu        else:
897378Sgblack@eecs.umich.edu            self.extname = self.basename[:index], self.basename[index+1:]
907378Sgblack@eecs.umich.edu
917378Sgblack@eecs.umich.edu        for base in type(self).__mro__:
927378Sgblack@eecs.umich.edu            if issubclass(base, SourceFile):
937378Sgblack@eecs.umich.edu                base.all.append(self)
947378Sgblack@eecs.umich.edu
957378Sgblack@eecs.umich.edu    def __lt__(self, other): return self.filename < other.filename
967378Sgblack@eecs.umich.edu    def __le__(self, other): return self.filename <= other.filename
977378Sgblack@eecs.umich.edu    def __gt__(self, other): return self.filename > other.filename
987378Sgblack@eecs.umich.edu    def __ge__(self, other): return self.filename >= other.filename
997378Sgblack@eecs.umich.edu    def __eq__(self, other): return self.filename == other.filename
1007378Sgblack@eecs.umich.edu    def __ne__(self, other): return self.filename != other.filename
1017378Sgblack@eecs.umich.edu        
1027378Sgblack@eecs.umich.educlass Source(SourceFile):
1037378Sgblack@eecs.umich.edu    '''Add a c/c++ source file to the build'''
1047378Sgblack@eecs.umich.edu    def __init__(self, source, Werror=True, swig=False, bin_only=False,
1057378Sgblack@eecs.umich.edu                 skip_lib=False):
1067378Sgblack@eecs.umich.edu        super(Source, self).__init__(source)
1077378Sgblack@eecs.umich.edu
1087382Sgblack@eecs.umich.edu        self.Werror = Werror
1097396Sgblack@eecs.umich.edu        self.swig = swig
1107396Sgblack@eecs.umich.edu        self.bin_only = bin_only
1117396Sgblack@eecs.umich.edu        self.skip_lib = bin_only or skip_lib
1127396Sgblack@eecs.umich.edu
1137396Sgblack@eecs.umich.educlass PySource(SourceFile):
1147396Sgblack@eecs.umich.edu    '''Add a python source file to the named package'''
1157396Sgblack@eecs.umich.edu    invalid_sym_char = re.compile('[^A-z0-9_]')
1167396Sgblack@eecs.umich.edu    modules = {}
1177396Sgblack@eecs.umich.edu    tnodes = {}
1187396Sgblack@eecs.umich.edu    symnames = {}
1197396Sgblack@eecs.umich.edu    
1207396Sgblack@eecs.umich.edu    def __init__(self, package, source):
1217396Sgblack@eecs.umich.edu        super(PySource, self).__init__(source)
1227396Sgblack@eecs.umich.edu
1237396Sgblack@eecs.umich.edu        modname,ext = self.extname
1247396Sgblack@eecs.umich.edu        assert ext == 'py'
1257396Sgblack@eecs.umich.edu
1267396Sgblack@eecs.umich.edu        if package:
1277396Sgblack@eecs.umich.edu            path = package.split('.')
1287396Sgblack@eecs.umich.edu        else:
1297396Sgblack@eecs.umich.edu            path = []
1307397Sgblack@eecs.umich.edu
1317397Sgblack@eecs.umich.edu        modpath = path[:]
1327397Sgblack@eecs.umich.edu        if modname != '__init__':
1337397Sgblack@eecs.umich.edu            modpath += [ modname ]
1347397Sgblack@eecs.umich.edu        modpath = '.'.join(modpath)
1357397Sgblack@eecs.umich.edu
1367397Sgblack@eecs.umich.edu        arcpath = path + [ self.basename ]
1377397Sgblack@eecs.umich.edu        abspath = self.snode.abspath
1387397Sgblack@eecs.umich.edu        if not exists(abspath):
1397397Sgblack@eecs.umich.edu            abspath = self.tnode.abspath
1407397Sgblack@eecs.umich.edu
1417397Sgblack@eecs.umich.edu        self.package = package
1427397Sgblack@eecs.umich.edu        self.modname = modname
1437397Sgblack@eecs.umich.edu        self.modpath = modpath
1447397Sgblack@eecs.umich.edu        self.arcname = joinpath(*arcpath)
1457397Sgblack@eecs.umich.edu        self.abspath = abspath
1467397Sgblack@eecs.umich.edu        self.compiled = File(self.filename + 'c')
1477384Sgblack@eecs.umich.edu        self.cpp = File(self.filename + '.cc')
1487384Sgblack@eecs.umich.edu        self.symname = PySource.invalid_sym_char.sub('_', modpath)
1497384Sgblack@eecs.umich.edu
1507384Sgblack@eecs.umich.edu        PySource.modules[modpath] = self
1517384Sgblack@eecs.umich.edu        PySource.tnodes[self.tnode] = self
1527384Sgblack@eecs.umich.edu        PySource.symnames[self.symname] = self
1537384Sgblack@eecs.umich.edu
1547384Sgblack@eecs.umich.educlass SimObject(PySource):
1557384Sgblack@eecs.umich.edu    '''Add a SimObject python file as a python source object and add
1567384Sgblack@eecs.umich.edu    it to a list of sim object modules'''
1577384Sgblack@eecs.umich.edu
1587384Sgblack@eecs.umich.edu    fixed = False
1597384Sgblack@eecs.umich.edu    modnames = []
1607384Sgblack@eecs.umich.edu
1617384Sgblack@eecs.umich.edu    def __init__(self, source):
1627384Sgblack@eecs.umich.edu        super(SimObject, self).__init__('m5.objects', source)
1637384Sgblack@eecs.umich.edu        if self.fixed:
1647384Sgblack@eecs.umich.edu            raise AttributeError, "Too late to call SimObject now."
1657384Sgblack@eecs.umich.edu
1667384Sgblack@eecs.umich.edu        bisect.insort_right(SimObject.modnames, self.modname)
1677384Sgblack@eecs.umich.edu
1687384Sgblack@eecs.umich.educlass SwigSource(SourceFile):
1697384Sgblack@eecs.umich.edu    '''Add a swig file to build'''
1707384Sgblack@eecs.umich.edu
1717384Sgblack@eecs.umich.edu    def __init__(self, package, source):
1727384Sgblack@eecs.umich.edu        super(SwigSource, self).__init__(source)
1737384Sgblack@eecs.umich.edu
1747384Sgblack@eecs.umich.edu        modname,ext = self.extname
1757384Sgblack@eecs.umich.edu        assert ext == 'i'
1767384Sgblack@eecs.umich.edu
1777384Sgblack@eecs.umich.edu        self.module = modname
1787384Sgblack@eecs.umich.edu        cc_file = joinpath(self.dirname, modname + '_wrap.cc')
1797384Sgblack@eecs.umich.edu        py_file = joinpath(self.dirname, modname + '.py')
1807384Sgblack@eecs.umich.edu
1817384Sgblack@eecs.umich.edu        self.cc_source = Source(cc_file, swig=True)
1827384Sgblack@eecs.umich.edu        self.py_source = PySource(package, py_file)
1837384Sgblack@eecs.umich.edu
1847384Sgblack@eecs.umich.eduunit_tests = []
1857384Sgblack@eecs.umich.edudef UnitTest(target, sources):
1867384Sgblack@eecs.umich.edu    if not isinstance(sources, (list, tuple)):
1877384Sgblack@eecs.umich.edu        sources = [ sources ]
1887384Sgblack@eecs.umich.edu
1897384Sgblack@eecs.umich.edu    sources = [ Source(src, skip_lib=True) for src in sources ]
1907384Sgblack@eecs.umich.edu    unit_tests.append((target, sources))
1917384Sgblack@eecs.umich.edu
1927384Sgblack@eecs.umich.edu# Children should have access
1937384Sgblack@eecs.umich.eduExport('Source')
1947384Sgblack@eecs.umich.eduExport('PySource')
1957396Sgblack@eecs.umich.eduExport('SimObject')
1967396Sgblack@eecs.umich.eduExport('SwigSource')
1977396Sgblack@eecs.umich.eduExport('UnitTest')
1987396Sgblack@eecs.umich.edu
1997396Sgblack@eecs.umich.edu########################################################################
2007396Sgblack@eecs.umich.edu#
2017396Sgblack@eecs.umich.edu# Trace Flags
2027396Sgblack@eecs.umich.edu#
2037396Sgblack@eecs.umich.edutrace_flags = {}
2047396Sgblack@eecs.umich.edudef TraceFlag(name, desc=None):
2057396Sgblack@eecs.umich.edu    if name in trace_flags:
2067396Sgblack@eecs.umich.edu        raise AttributeError, "Flag %s already specified" % name
2077396Sgblack@eecs.umich.edu    trace_flags[name] = (name, (), desc)
2087396Sgblack@eecs.umich.edu
2097396Sgblack@eecs.umich.edudef CompoundFlag(name, flags, desc=None):
2107396Sgblack@eecs.umich.edu    if name in trace_flags:
2117396Sgblack@eecs.umich.edu        raise AttributeError, "Flag %s already specified" % name
2127396Sgblack@eecs.umich.edu
2137396Sgblack@eecs.umich.edu    compound = tuple(flags)
2147396Sgblack@eecs.umich.edu    trace_flags[name] = (name, compound, desc)
2157396Sgblack@eecs.umich.edu
2167396Sgblack@eecs.umich.eduExport('TraceFlag')
2177396Sgblack@eecs.umich.eduExport('CompoundFlag')
2187396Sgblack@eecs.umich.edu
2197396Sgblack@eecs.umich.edu########################################################################
2207396Sgblack@eecs.umich.edu#
2217396Sgblack@eecs.umich.edu# Set some compiler variables
2227396Sgblack@eecs.umich.edu#
2237396Sgblack@eecs.umich.edu
2247396Sgblack@eecs.umich.edu# Include file paths are rooted in this directory.  SCons will
2257396Sgblack@eecs.umich.edu# automatically expand '.' to refer to both the source directory and
2267396Sgblack@eecs.umich.edu# the corresponding build directory to pick up generated include
2277396Sgblack@eecs.umich.edu# files.
2287396Sgblack@eecs.umich.eduenv.Append(CPPPATH=Dir('.'))
2297396Sgblack@eecs.umich.edu
2307396Sgblack@eecs.umich.edufor extra_dir in extras_dir_list:
2317396Sgblack@eecs.umich.edu    env.Append(CPPPATH=Dir(extra_dir))
2327396Sgblack@eecs.umich.edu
2337396Sgblack@eecs.umich.edu# Workaround for bug in SCons version > 0.97d20071212
2347396Sgblack@eecs.umich.edu# Scons bug id: 2006 M5 Bug id: 308 
2357396Sgblack@eecs.umich.edufor root, dirs, files in os.walk(base_dir, topdown=True):
2367396Sgblack@eecs.umich.edu    Dir(root[len(base_dir) + 1:])
2377396Sgblack@eecs.umich.edu
2387396Sgblack@eecs.umich.edu########################################################################
2397396Sgblack@eecs.umich.edu#
2407396Sgblack@eecs.umich.edu# Walk the tree and execute all SConscripts in subdirectories
2417396Sgblack@eecs.umich.edu#
2427396Sgblack@eecs.umich.edu
2437384Sgblack@eecs.umich.eduhere = Dir('.').srcnode().abspath
2447384Sgblack@eecs.umich.edufor root, dirs, files in os.walk(base_dir, topdown=True):
2457386Sgblack@eecs.umich.edu    if root == here:
2467386Sgblack@eecs.umich.edu        # we don't want to recurse back into this SConscript
2477386Sgblack@eecs.umich.edu        continue
2487386Sgblack@eecs.umich.edu
2497386Sgblack@eecs.umich.edu    if 'SConscript' in files:
2507386Sgblack@eecs.umich.edu        build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:])
2517386Sgblack@eecs.umich.edu        SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir)
2527386Sgblack@eecs.umich.edu
2537386Sgblack@eecs.umich.edufor extra_dir in extras_dir_list:
2547386Sgblack@eecs.umich.edu    prefix_len = len(dirname(extra_dir)) + 1
2557386Sgblack@eecs.umich.edu    for root, dirs, files in os.walk(extra_dir, topdown=True):
2567386Sgblack@eecs.umich.edu        if 'SConscript' in files:
2577386Sgblack@eecs.umich.edu            build_dir = joinpath(env['BUILDDIR'], root[prefix_len:])
2587386Sgblack@eecs.umich.edu            SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir)
2597386Sgblack@eecs.umich.edu
2607386Sgblack@eecs.umich.edufor opt in export_vars:
2617386Sgblack@eecs.umich.edu    env.ConfigFile(opt)
2627396Sgblack@eecs.umich.edu
2637386Sgblack@eecs.umich.edudef makeTheISA(source, target, env):
2647386Sgblack@eecs.umich.edu    isas = [ src.get_contents() for src in source ]
2657386Sgblack@eecs.umich.edu    target_isa = env['TARGET_ISA']
2667386Sgblack@eecs.umich.edu    def define(isa):
2677386Sgblack@eecs.umich.edu        return isa.upper() + '_ISA'
2687386Sgblack@eecs.umich.edu    
2697386Sgblack@eecs.umich.edu    def namespace(isa):
2707385Sgblack@eecs.umich.edu        return isa[0].upper() + isa[1:].lower() + 'ISA' 
2717384Sgblack@eecs.umich.edu
2727385Sgblack@eecs.umich.edu
2737385Sgblack@eecs.umich.edu    code = code_formatter()
2747385Sgblack@eecs.umich.edu    code('''\
2757384Sgblack@eecs.umich.edu#ifndef __CONFIG_THE_ISA_HH__
2767384Sgblack@eecs.umich.edu#define __CONFIG_THE_ISA_HH__
2777384Sgblack@eecs.umich.edu
2787384Sgblack@eecs.umich.edu''')
2797384Sgblack@eecs.umich.edu
2807384Sgblack@eecs.umich.edu    for i,isa in enumerate(isas):
2817384Sgblack@eecs.umich.edu        code('#define $0 $1', define(isa), i + 1)
2827384Sgblack@eecs.umich.edu
2837384Sgblack@eecs.umich.edu    code('''
2847384Sgblack@eecs.umich.edu
2857384Sgblack@eecs.umich.edu#define THE_ISA ${{define(target_isa)}}
2867384Sgblack@eecs.umich.edu#define TheISA ${{namespace(target_isa)}}
2877384Sgblack@eecs.umich.edu
2887384Sgblack@eecs.umich.edu#endif // __CONFIG_THE_ISA_HH__''')
2897384Sgblack@eecs.umich.edu
2907384Sgblack@eecs.umich.edu    code.write(str(target[0]))
2917384Sgblack@eecs.umich.edu
2927385Sgblack@eecs.umich.eduenv.Command('config/the_isa.hh', map(Value, all_isa_list),
2937385Sgblack@eecs.umich.edu            MakeAction(makeTheISA, " [ CFG ISA] $STRIP_TARGET"))
2947385Sgblack@eecs.umich.edu
2957385Sgblack@eecs.umich.edu########################################################################
2967396Sgblack@eecs.umich.edu#
2977385Sgblack@eecs.umich.edu# Prevent any SimObjects from being added after this point, they
2987384Sgblack@eecs.umich.edu# should all have been added in the SConscripts above
2997384Sgblack@eecs.umich.edu#
3007384Sgblack@eecs.umich.eduSimObject.fixed = True
3017384Sgblack@eecs.umich.edu
3027386Sgblack@eecs.umich.educlass DictImporter(object):
3037386Sgblack@eecs.umich.edu    '''This importer takes a dictionary of arbitrary module names that
3047386Sgblack@eecs.umich.edu    map to arbitrary filenames.'''
3057386Sgblack@eecs.umich.edu    def __init__(self, modules):
3067386Sgblack@eecs.umich.edu        self.modules = modules
3077386Sgblack@eecs.umich.edu        self.installed = set()
3087386Sgblack@eecs.umich.edu
3097386Sgblack@eecs.umich.edu    def __del__(self):
3107386Sgblack@eecs.umich.edu        self.unload()
3117386Sgblack@eecs.umich.edu
3127386Sgblack@eecs.umich.edu    def unload(self):
3137386Sgblack@eecs.umich.edu        import sys
3147386Sgblack@eecs.umich.edu        for module in self.installed:
3157386Sgblack@eecs.umich.edu            del sys.modules[module]
3167386Sgblack@eecs.umich.edu        self.installed = set()
3177386Sgblack@eecs.umich.edu
3187386Sgblack@eecs.umich.edu    def find_module(self, fullname, path):
3197396Sgblack@eecs.umich.edu        if fullname == 'm5.defines':
3207386Sgblack@eecs.umich.edu            return self
3217396Sgblack@eecs.umich.edu
3227396Sgblack@eecs.umich.edu        if fullname == 'm5.objects':
3237396Sgblack@eecs.umich.edu            return self
3247396Sgblack@eecs.umich.edu
3257386Sgblack@eecs.umich.edu        if fullname.startswith('m5.internal'):
3267386Sgblack@eecs.umich.edu            return None
3277386Sgblack@eecs.umich.edu
3287386Sgblack@eecs.umich.edu        source = self.modules.get(fullname, None)
3297386Sgblack@eecs.umich.edu        if source is not None and fullname.startswith('m5.objects'):
3307386Sgblack@eecs.umich.edu            return self
3317386Sgblack@eecs.umich.edu
3327386Sgblack@eecs.umich.edu        return None
3337386Sgblack@eecs.umich.edu
3347386Sgblack@eecs.umich.edu    def load_module(self, fullname):
3357386Sgblack@eecs.umich.edu        mod = imp.new_module(fullname)
3367386Sgblack@eecs.umich.edu        sys.modules[fullname] = mod
3377386Sgblack@eecs.umich.edu        self.installed.add(fullname)
3387386Sgblack@eecs.umich.edu
3397386Sgblack@eecs.umich.edu        mod.__loader__ = self
3407386Sgblack@eecs.umich.edu        if fullname == 'm5.objects':
3417386Sgblack@eecs.umich.edu            mod.__path__ = fullname.split('.')
3427386Sgblack@eecs.umich.edu            return mod
3437386Sgblack@eecs.umich.edu
3447396Sgblack@eecs.umich.edu        if fullname == 'm5.defines':
3457396Sgblack@eecs.umich.edu            mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env)
3467396Sgblack@eecs.umich.edu            return mod
3477396Sgblack@eecs.umich.edu
3487386Sgblack@eecs.umich.edu        source = self.modules[fullname]
3497386Sgblack@eecs.umich.edu        if source.modname == '__init__':
3507386Sgblack@eecs.umich.edu            mod.__path__ = source.modpath
3517386Sgblack@eecs.umich.edu        mod.__file__ = source.abspath
3527386Sgblack@eecs.umich.edu
3537386Sgblack@eecs.umich.edu        exec file(source.abspath, 'r') in mod.__dict__
3547386Sgblack@eecs.umich.edu
3557396Sgblack@eecs.umich.edu        return mod
3567386Sgblack@eecs.umich.edu
3577396Sgblack@eecs.umich.eduimport m5.SimObject
3587396Sgblack@eecs.umich.eduimport m5.params
3597396Sgblack@eecs.umich.edufrom m5.util import code_formatter
3607396Sgblack@eecs.umich.edu
3617386Sgblack@eecs.umich.edum5.SimObject.clear()
3627386Sgblack@eecs.umich.edum5.params.clear()
3637386Sgblack@eecs.umich.edu
3647386Sgblack@eecs.umich.edu# install the python importer so we can grab stuff from the source
3657386Sgblack@eecs.umich.edu# tree itself.  We can't have SimObjects added after this point or
3667386Sgblack@eecs.umich.edu# else we won't know about them for the rest of the stuff.
3677396Sgblack@eecs.umich.eduimporter = DictImporter(PySource.modules)
3687396Sgblack@eecs.umich.edusys.meta_path[0:0] = [ importer ]
3697396Sgblack@eecs.umich.edu
3707396Sgblack@eecs.umich.edu# import all sim objects so we can populate the all_objects list
3717396Sgblack@eecs.umich.edu# make sure that we're working with a list, then let's sort it
3727396Sgblack@eecs.umich.edufor modname in SimObject.modnames:
3737396Sgblack@eecs.umich.edu    exec('from m5.objects import %s' % modname)
3747396Sgblack@eecs.umich.edu
3757396Sgblack@eecs.umich.edu# we need to unload all of the currently imported modules so that they
3767396Sgblack@eecs.umich.edu# will be re-imported the next time the sconscript is run
3777396Sgblack@eecs.umich.eduimporter.unload()
3787396Sgblack@eecs.umich.edusys.meta_path.remove(importer)
3797396Sgblack@eecs.umich.edu
3807396Sgblack@eecs.umich.edusim_objects = m5.SimObject.allClasses
3817396Sgblack@eecs.umich.eduall_enums = m5.params.allEnums
3827396Sgblack@eecs.umich.edu
3837396Sgblack@eecs.umich.eduall_params = {}
3847396Sgblack@eecs.umich.edufor name,obj in sorted(sim_objects.iteritems()):
3857396Sgblack@eecs.umich.edu    for param in obj._params.local.values():
3867396Sgblack@eecs.umich.edu        # load the ptype attribute now because it depends on the
3877396Sgblack@eecs.umich.edu        # current version of SimObject.allClasses, but when scons
3887396Sgblack@eecs.umich.edu        # actually uses the value, all versions of
3897396Sgblack@eecs.umich.edu        # SimObject.allClasses will have been loaded
3907396Sgblack@eecs.umich.edu        param.ptype
3917396Sgblack@eecs.umich.edu
3927396Sgblack@eecs.umich.edu        if not hasattr(param, 'swig_decl'):
3937396Sgblack@eecs.umich.edu            continue
3947396Sgblack@eecs.umich.edu        pname = param.ptype_str
3957396Sgblack@eecs.umich.edu        if pname not in all_params:
3967396Sgblack@eecs.umich.edu            all_params[pname] = param
3977396Sgblack@eecs.umich.edu
3987396Sgblack@eecs.umich.edu########################################################################
3997398Sgblack@eecs.umich.edu#
4007398Sgblack@eecs.umich.edu# calculate extra dependencies
4017398Sgblack@eecs.umich.edu#
4027398Sgblack@eecs.umich.edumodule_depends = ["m5", "m5.SimObject", "m5.params"]
4037398Sgblack@eecs.umich.edudepends = [ PySource.modules[dep].snode for dep in module_depends ]
4047398Sgblack@eecs.umich.edu
4057398Sgblack@eecs.umich.edu########################################################################
4067398Sgblack@eecs.umich.edu#
4077398Sgblack@eecs.umich.edu# Commands for the basic automatically generated python files
4087398Sgblack@eecs.umich.edu#
4097398Sgblack@eecs.umich.edu
4107398Sgblack@eecs.umich.edu# Generate Python file containing a dict specifying the current
4117398Sgblack@eecs.umich.edu# buildEnv flags.
4127398Sgblack@eecs.umich.edudef makeDefinesPyFile(target, source, env):
4137398Sgblack@eecs.umich.edu    build_env, hg_info = [ x.get_contents() for x in source ]
4147398Sgblack@eecs.umich.edu
4157398Sgblack@eecs.umich.edu    code = code_formatter()
4167398Sgblack@eecs.umich.edu    code("""
4177398Sgblack@eecs.umich.eduimport m5.internal
4187398Sgblack@eecs.umich.eduimport m5.util
4197398Sgblack@eecs.umich.edu
4207398Sgblack@eecs.umich.edubuildEnv = m5.util.SmartDict($build_env)
4217398Sgblack@eecs.umich.eduhgRev = '$hg_info'
4227398Sgblack@eecs.umich.edu
4237398Sgblack@eecs.umich.educompileDate = m5.internal.core.compileDate
4247398Sgblack@eecs.umich.edu_globals = globals()
4257398Sgblack@eecs.umich.edufor key,val in m5.internal.core.__dict__.iteritems():
4267398Sgblack@eecs.umich.edu    if key.startswith('flag_'):
4277398Sgblack@eecs.umich.edu        flag = key[5:]
4287398Sgblack@eecs.umich.edu        _globals[flag] = val
4297398Sgblack@eecs.umich.edudel _globals
4307398Sgblack@eecs.umich.edu""")
4317398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
4327398Sgblack@eecs.umich.edu
4337398Sgblack@eecs.umich.edudefines_info = [ Value(build_env), Value(env['HG_INFO']) ]
4347398Sgblack@eecs.umich.edu# Generate a file with all of the compile options in it
4357398Sgblack@eecs.umich.eduenv.Command('python/m5/defines.py', defines_info,
4367398Sgblack@eecs.umich.edu            MakeAction(makeDefinesPyFile, " [ DEFINES] $STRIP_TARGET"))
4377398Sgblack@eecs.umich.eduPySource('m5', 'python/m5/defines.py')
4387398Sgblack@eecs.umich.edu
4397398Sgblack@eecs.umich.edu# Generate python file containing info about the M5 source code
4407398Sgblack@eecs.umich.edudef makeInfoPyFile(target, source, env):
4417398Sgblack@eecs.umich.edu    code = code_formatter()
4427398Sgblack@eecs.umich.edu    for src in source:
4437398Sgblack@eecs.umich.edu        data = ''.join(file(src.srcnode().abspath, 'r').xreadlines())
4447398Sgblack@eecs.umich.edu        code('$src = ${{repr(data)}}')
4457398Sgblack@eecs.umich.edu    code.write(str(target[0]))
4467398Sgblack@eecs.umich.edu
4477398Sgblack@eecs.umich.edu# Generate a file that wraps the basic top level files
4487398Sgblack@eecs.umich.eduenv.Command('python/m5/info.py',
4497398Sgblack@eecs.umich.edu            [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
4507398Sgblack@eecs.umich.edu            MakeAction(makeInfoPyFile, " [    INFO] $STRIP_TARGET"))
4517398Sgblack@eecs.umich.eduPySource('m5', 'python/m5/info.py')
4527398Sgblack@eecs.umich.edu
4537398Sgblack@eecs.umich.edu########################################################################
4547398Sgblack@eecs.umich.edu#
4557398Sgblack@eecs.umich.edu# Create all of the SimObject param headers and enum headers
4567398Sgblack@eecs.umich.edu#
4577398Sgblack@eecs.umich.edu
4587398Sgblack@eecs.umich.edudef createSimObjectParam(target, source, env):
4597398Sgblack@eecs.umich.edu    assert len(target) == 1 and len(source) == 1
4607398Sgblack@eecs.umich.edu
4617398Sgblack@eecs.umich.edu    name = str(source[0].get_contents())
4627398Sgblack@eecs.umich.edu    obj = sim_objects[name]
4637398Sgblack@eecs.umich.edu
4647398Sgblack@eecs.umich.edu    code = code_formatter()
4657398Sgblack@eecs.umich.edu    obj.cxx_decl(code)
4667398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
4677398Sgblack@eecs.umich.edu
4687398Sgblack@eecs.umich.edudef createSwigParam(target, source, env):
4697398Sgblack@eecs.umich.edu    assert len(target) == 1 and len(source) == 1
4707398Sgblack@eecs.umich.edu
4717398Sgblack@eecs.umich.edu    name = str(source[0].get_contents())
4727398Sgblack@eecs.umich.edu    param = all_params[name]
4737398Sgblack@eecs.umich.edu
4747398Sgblack@eecs.umich.edu    code = code_formatter()
4757398Sgblack@eecs.umich.edu    code('%module(package="m5.internal") $0_${name}', param.file_ext)
4767398Sgblack@eecs.umich.edu    param.swig_decl(code)
4777398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
4787398Sgblack@eecs.umich.edu
4797398Sgblack@eecs.umich.edudef createEnumStrings(target, source, env):
4807398Sgblack@eecs.umich.edu    assert len(target) == 1 and len(source) == 1
4817398Sgblack@eecs.umich.edu
4827398Sgblack@eecs.umich.edu    name = str(source[0].get_contents())
4837398Sgblack@eecs.umich.edu    obj = all_enums[name]
4847398Sgblack@eecs.umich.edu
4857398Sgblack@eecs.umich.edu    code = code_formatter()
4867398Sgblack@eecs.umich.edu    obj.cxx_def(code)
4877398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
4887398Sgblack@eecs.umich.edu
4897398Sgblack@eecs.umich.edudef createEnumParam(target, source, env):
4907398Sgblack@eecs.umich.edu    assert len(target) == 1 and len(source) == 1
4917398Sgblack@eecs.umich.edu
4927398Sgblack@eecs.umich.edu    name = str(source[0].get_contents())
4937398Sgblack@eecs.umich.edu    obj = all_enums[name]
4947398Sgblack@eecs.umich.edu
4957398Sgblack@eecs.umich.edu    code = code_formatter()
4967398Sgblack@eecs.umich.edu    obj.cxx_decl(code)
4977398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
4987398Sgblack@eecs.umich.edu
4997398Sgblack@eecs.umich.edudef createEnumSwig(target, source, env):
5007398Sgblack@eecs.umich.edu    assert len(target) == 1 and len(source) == 1
5017398Sgblack@eecs.umich.edu
5027398Sgblack@eecs.umich.edu    name = str(source[0].get_contents())
5037398Sgblack@eecs.umich.edu    obj = all_enums[name]
5047398Sgblack@eecs.umich.edu
5057398Sgblack@eecs.umich.edu    code = code_formatter()
5067398Sgblack@eecs.umich.edu    code('''\
5077398Sgblack@eecs.umich.edu%module(package="m5.internal") enum_$name
5087398Sgblack@eecs.umich.edu
5097398Sgblack@eecs.umich.edu%{
5107398Sgblack@eecs.umich.edu#include "enums/$name.hh"
5117398Sgblack@eecs.umich.edu%}
5127398Sgblack@eecs.umich.edu
5137398Sgblack@eecs.umich.edu%include "enums/$name.hh"
5147398Sgblack@eecs.umich.edu''')
5157398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
5167398Sgblack@eecs.umich.edu
5177398Sgblack@eecs.umich.edu# Generate all of the SimObject param struct header files
5187398Sgblack@eecs.umich.eduparams_hh_files = []
5197398Sgblack@eecs.umich.edufor name,simobj in sorted(sim_objects.iteritems()):
5207398Sgblack@eecs.umich.edu    py_source = PySource.modules[simobj.__module__]
5217398Sgblack@eecs.umich.edu    extra_deps = [ py_source.tnode ]
5227398Sgblack@eecs.umich.edu
5237398Sgblack@eecs.umich.edu    hh_file = File('params/%s.hh' % name)
5247398Sgblack@eecs.umich.edu    params_hh_files.append(hh_file)
5257398Sgblack@eecs.umich.edu    env.Command(hh_file, Value(name),
5267398Sgblack@eecs.umich.edu                MakeAction(createSimObjectParam, " [SO PARAM] $STRIP_TARGET"))
5277398Sgblack@eecs.umich.edu    env.Depends(hh_file, depends + extra_deps)
5287398Sgblack@eecs.umich.edu
5297398Sgblack@eecs.umich.edu# Generate any parameter header files needed
5307398Sgblack@eecs.umich.eduparams_i_files = []
5317398Sgblack@eecs.umich.edufor name,param in all_params.iteritems():
5327398Sgblack@eecs.umich.edu    i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name))
5337398Sgblack@eecs.umich.edu    params_i_files.append(i_file)
5347398Sgblack@eecs.umich.edu    env.Command(i_file, Value(name),
5357398Sgblack@eecs.umich.edu                MakeAction(createSwigParam, " [SW PARAM] $STRIP_TARGET"))
5367398Sgblack@eecs.umich.edu    env.Depends(i_file, depends)
5377398Sgblack@eecs.umich.edu    SwigSource('m5.internal', i_file)
5387398Sgblack@eecs.umich.edu
5397398Sgblack@eecs.umich.edu# Generate all enum header files
5407398Sgblack@eecs.umich.edufor name,enum in sorted(all_enums.iteritems()):
5417398Sgblack@eecs.umich.edu    py_source = PySource.modules[enum.__module__]
5427398Sgblack@eecs.umich.edu    extra_deps = [ py_source.tnode ]
5437398Sgblack@eecs.umich.edu
5447398Sgblack@eecs.umich.edu    cc_file = File('enums/%s.cc' % name)
5457398Sgblack@eecs.umich.edu    env.Command(cc_file, Value(name),
5467398Sgblack@eecs.umich.edu                MakeAction(createEnumStrings, " [ENUM STR] $STRIP_TARGET"))
5477398Sgblack@eecs.umich.edu    env.Depends(cc_file, depends + extra_deps)
5487398Sgblack@eecs.umich.edu    Source(cc_file)
5497398Sgblack@eecs.umich.edu
5507398Sgblack@eecs.umich.edu    hh_file = File('enums/%s.hh' % name)
5517398Sgblack@eecs.umich.edu    env.Command(hh_file, Value(name),
5527398Sgblack@eecs.umich.edu                MakeAction(createEnumParam, " [EN PARAM] $STRIP_TARGET"))
5537398Sgblack@eecs.umich.edu    env.Depends(hh_file, depends + extra_deps)
5547398Sgblack@eecs.umich.edu
5557398Sgblack@eecs.umich.edu    i_file = File('python/m5/internal/enum_%s.i' % name)
5567398Sgblack@eecs.umich.edu    env.Command(i_file, Value(name),
5577398Sgblack@eecs.umich.edu                MakeAction(createEnumSwig, " [ENUMSWIG] $STRIP_TARGET"))
5587398Sgblack@eecs.umich.edu    env.Depends(i_file, depends + extra_deps)
5597398Sgblack@eecs.umich.edu    SwigSource('m5.internal', i_file)
5607398Sgblack@eecs.umich.edu
5617398Sgblack@eecs.umich.edudef buildParam(target, source, env):
5627398Sgblack@eecs.umich.edu    name = source[0].get_contents()
5637398Sgblack@eecs.umich.edu    obj = sim_objects[name]
5647398Sgblack@eecs.umich.edu    class_path = obj.cxx_class.split('::')
5657398Sgblack@eecs.umich.edu    classname = class_path[-1]
5667398Sgblack@eecs.umich.edu    namespaces = class_path[:-1]
5677398Sgblack@eecs.umich.edu    params = obj._params.local.values()
5687398Sgblack@eecs.umich.edu
5697398Sgblack@eecs.umich.edu    code = code_formatter()
5707398Sgblack@eecs.umich.edu
5717398Sgblack@eecs.umich.edu    code('%module(package="m5.internal") param_$name')
5727398Sgblack@eecs.umich.edu    code()
5737398Sgblack@eecs.umich.edu    code('%{')
5747398Sgblack@eecs.umich.edu    code('#include "params/$obj.hh"')
5757398Sgblack@eecs.umich.edu    for param in params:
5767398Sgblack@eecs.umich.edu        param.cxx_predecls(code)
5777398Sgblack@eecs.umich.edu    code('%}')
5787398Sgblack@eecs.umich.edu    code()
5797398Sgblack@eecs.umich.edu
5807398Sgblack@eecs.umich.edu    for param in params:
5817398Sgblack@eecs.umich.edu        param.swig_predecls(code)
5827398Sgblack@eecs.umich.edu
5837398Sgblack@eecs.umich.edu    code()
5847398Sgblack@eecs.umich.edu    if obj._base:
5857398Sgblack@eecs.umich.edu        code('%import "python/m5/internal/param_${{obj._base}}.i"')
5867398Sgblack@eecs.umich.edu    code()
5877398Sgblack@eecs.umich.edu    obj.swig_objdecls(code)
5887398Sgblack@eecs.umich.edu    code()
5897398Sgblack@eecs.umich.edu
5907398Sgblack@eecs.umich.edu    code('%include "params/$obj.hh"')
5917398Sgblack@eecs.umich.edu
5927398Sgblack@eecs.umich.edu    code.write(target[0].abspath)
5937398Sgblack@eecs.umich.edu
5947398Sgblack@eecs.umich.edufor name in sim_objects.iterkeys():
5957398Sgblack@eecs.umich.edu    params_file = File('python/m5/internal/param_%s.i' % name)
5967398Sgblack@eecs.umich.edu    env.Command(params_file, Value(name),
5977398Sgblack@eecs.umich.edu                MakeAction(buildParam, " [BLDPARAM] $STRIP_TARGET"))
5987398Sgblack@eecs.umich.edu    env.Depends(params_file, depends)
5997398Sgblack@eecs.umich.edu    SwigSource('m5.internal', params_file)
6007398Sgblack@eecs.umich.edu
6017398Sgblack@eecs.umich.edu# Generate the main swig init file
6027398Sgblack@eecs.umich.edudef makeEmbeddedSwigInit(target, source, env):
6037398Sgblack@eecs.umich.edu    code = code_formatter()
6047398Sgblack@eecs.umich.edu    module = source[0].get_contents()
6057398Sgblack@eecs.umich.edu    code('''\
6067398Sgblack@eecs.umich.edu#include "sim/init.hh"
6077398Sgblack@eecs.umich.edu
6087398Sgblack@eecs.umich.eduextern "C" {
6097398Sgblack@eecs.umich.edu    void init_${module}();
6107398Sgblack@eecs.umich.edu}
6117398Sgblack@eecs.umich.edu
6127398Sgblack@eecs.umich.eduEmbeddedSwig embed_swig_${module}(init_${module});
6137398Sgblack@eecs.umich.edu''')
6147398Sgblack@eecs.umich.edu    code.write(str(target[0]))
6157398Sgblack@eecs.umich.edu    
6167396Sgblack@eecs.umich.edu# Build all swig modules
6177396Sgblack@eecs.umich.edufor swig in SwigSource.all:
6187396Sgblack@eecs.umich.edu    env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode,
6197396Sgblack@eecs.umich.edu                MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
6207396Sgblack@eecs.umich.edu                '-o ${TARGETS[0]} $SOURCES', " [    SWIG] $STRIP_TARGET"))
6217396Sgblack@eecs.umich.edu    init_file = 'python/swig/init_%s.cc' % swig.module
6227396Sgblack@eecs.umich.edu    env.Command(init_file, Value(swig.module),
6237396Sgblack@eecs.umich.edu                MakeAction(makeEmbeddedSwigInit, " [EMBED SW] $STRIP_TARGET"))
6247396Sgblack@eecs.umich.edu    Source(init_file)
6257396Sgblack@eecs.umich.edu
6267396Sgblack@eecs.umich.edudef getFlags(source_flags):
6277396Sgblack@eecs.umich.edu    flagsMap = {}
6287396Sgblack@eecs.umich.edu    flagsList = []
6297396Sgblack@eecs.umich.edu    for s in source_flags:
6307396Sgblack@eecs.umich.edu        val = eval(s.get_contents())
6317396Sgblack@eecs.umich.edu        name, compound, desc = val
6327396Sgblack@eecs.umich.edu        flagsList.append(val)
6337396Sgblack@eecs.umich.edu        flagsMap[name] = bool(compound)
6347396Sgblack@eecs.umich.edu    
6357379Sgblack@eecs.umich.edu    for name, compound, desc in flagsList:
6367388Sgblack@eecs.umich.edu        for flag in compound:
6377388Sgblack@eecs.umich.edu            if flag not in flagsMap:
6387379Sgblack@eecs.umich.edu                raise AttributeError, "Trace flag %s not found" % flag
6397396Sgblack@eecs.umich.edu            if flagsMap[flag]:
6407396Sgblack@eecs.umich.edu                raise AttributeError, \
6417388Sgblack@eecs.umich.edu                    "Compound flag can't point to another compound flag"
6427379Sgblack@eecs.umich.edu
6437379Sgblack@eecs.umich.edu    flagsList.sort()
6447396Sgblack@eecs.umich.edu    return flagsList
6457379Sgblack@eecs.umich.edu
6467382Sgblack@eecs.umich.edu
6477382Sgblack@eecs.umich.edu# Generate traceflags.py
6487382Sgblack@eecs.umich.edudef traceFlagsPy(target, source, env):
6497382Sgblack@eecs.umich.edu    assert(len(target) == 1)
6507382Sgblack@eecs.umich.edu    code = code_formatter()
6517382Sgblack@eecs.umich.edu
6527382Sgblack@eecs.umich.edu    allFlags = getFlags(source)
6537382Sgblack@eecs.umich.edu
6547382Sgblack@eecs.umich.edu    code('basic = [')
6557382Sgblack@eecs.umich.edu    code.indent()
6567396Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
6577396Sgblack@eecs.umich.edu        if not compound:
6587396Sgblack@eecs.umich.edu            code("'$flag',")
6597396Sgblack@eecs.umich.edu    code(']')
6607396Sgblack@eecs.umich.edu    code.dedent()
6617396Sgblack@eecs.umich.edu    code()
6627396Sgblack@eecs.umich.edu
6637396Sgblack@eecs.umich.edu    code('compound = [')
6647396Sgblack@eecs.umich.edu    code.indent()
6657396Sgblack@eecs.umich.edu    code("'All',")
6667396Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
6677396Sgblack@eecs.umich.edu        if compound:
6687396Sgblack@eecs.umich.edu            code("'$flag',")
6697396Sgblack@eecs.umich.edu    code("]")
6707396Sgblack@eecs.umich.edu    code.dedent()
6717396Sgblack@eecs.umich.edu    code()
6727382Sgblack@eecs.umich.edu
6737382Sgblack@eecs.umich.edu    code("all = frozenset(basic + compound)")
6747382Sgblack@eecs.umich.edu    code()
6757379Sgblack@eecs.umich.edu
6767379Sgblack@eecs.umich.edu    code('compoundMap = {')
6777381Sgblack@eecs.umich.edu    code.indent()
6787379Sgblack@eecs.umich.edu    all = tuple([flag for flag,compound,desc in allFlags if not compound])
6797382Sgblack@eecs.umich.edu    code("'All' : $all,")
6807379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
6817379Sgblack@eecs.umich.edu        if compound:
6827381Sgblack@eecs.umich.edu            code("'$flag' : $compound,")
6837379Sgblack@eecs.umich.edu    code('}')
6847382Sgblack@eecs.umich.edu    code.dedent()
6857379Sgblack@eecs.umich.edu    code()
6867379Sgblack@eecs.umich.edu
6877379Sgblack@eecs.umich.edu    code('descriptions = {')
6887379Sgblack@eecs.umich.edu    code.indent()
6897381Sgblack@eecs.umich.edu    code("'All' : 'All flags',")
6907379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
6917382Sgblack@eecs.umich.edu        code("'$flag' : '$desc',")
6927379Sgblack@eecs.umich.edu    code("}")
6937379Sgblack@eecs.umich.edu    code.dedent()
6947381Sgblack@eecs.umich.edu
6957379Sgblack@eecs.umich.edu    code.write(str(target[0]))
6967382Sgblack@eecs.umich.edu
6977379Sgblack@eecs.umich.edudef traceFlagsCC(target, source, env):
6987379Sgblack@eecs.umich.edu    assert(len(target) == 1)
6997379Sgblack@eecs.umich.edu
7007379Sgblack@eecs.umich.edu    allFlags = getFlags(source)
7017379Sgblack@eecs.umich.edu    code = code_formatter()
7027379Sgblack@eecs.umich.edu
7037381Sgblack@eecs.umich.edu    # file header
7047379Sgblack@eecs.umich.edu    code('''
7057382Sgblack@eecs.umich.edu/*
7067379Sgblack@eecs.umich.edu * DO NOT EDIT THIS FILE! Automatically generated
7077379Sgblack@eecs.umich.edu */
7087381Sgblack@eecs.umich.edu
7097379Sgblack@eecs.umich.edu#include "base/traceflags.hh"
7107382Sgblack@eecs.umich.edu
7117379Sgblack@eecs.umich.eduusing namespace Trace;
7127379Sgblack@eecs.umich.edu
7137379Sgblack@eecs.umich.educonst char *Trace::flagStrings[] =
7147379Sgblack@eecs.umich.edu{''')
7157381Sgblack@eecs.umich.edu
7167379Sgblack@eecs.umich.edu    code.indent()
7177382Sgblack@eecs.umich.edu    # The string array is used by SimpleEnumParam to map the strings
7187379Sgblack@eecs.umich.edu    # provided by the user to enum values.
7197379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
7207381Sgblack@eecs.umich.edu        if not compound:
7217379Sgblack@eecs.umich.edu            code('"$flag",')
7227382Sgblack@eecs.umich.edu
7237379Sgblack@eecs.umich.edu    code('"All",')
7247379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
7257379Sgblack@eecs.umich.edu        if compound:
7267379Sgblack@eecs.umich.edu            code('"$flag",')
7277379Sgblack@eecs.umich.edu    code.dedent()
7287379Sgblack@eecs.umich.edu
7297379Sgblack@eecs.umich.edu    code('''\
7307379Sgblack@eecs.umich.edu};
7317386Sgblack@eecs.umich.edu
7327379Sgblack@eecs.umich.educonst int Trace::numFlagStrings = ${{len(allFlags) + 1}};
7337379Sgblack@eecs.umich.edu
7347379Sgblack@eecs.umich.edu''')
7357379Sgblack@eecs.umich.edu
7367382Sgblack@eecs.umich.edu    # Now define the individual compound flag arrays.  There is an array
7377382Sgblack@eecs.umich.edu    # for each compound flag listing the component base flags.
7387382Sgblack@eecs.umich.edu    all = tuple([flag for flag,compound,desc in allFlags if not compound])
7397382Sgblack@eecs.umich.edu    code('static const Flags AllMap[] = {')
7407386Sgblack@eecs.umich.edu    code.indent()
7417379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
7427379Sgblack@eecs.umich.edu        if not compound:
7437379Sgblack@eecs.umich.edu            code('$flag,')
7447386Sgblack@eecs.umich.edu    code.dedent()
7457379Sgblack@eecs.umich.edu    code('};')
7467379Sgblack@eecs.umich.edu    code()
7477379Sgblack@eecs.umich.edu
7487379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
7497382Sgblack@eecs.umich.edu        if not compound:
7507382Sgblack@eecs.umich.edu            continue
7517382Sgblack@eecs.umich.edu        code('static const Flags ${flag}Map[] = {')
7527382Sgblack@eecs.umich.edu        code.indent()
7537386Sgblack@eecs.umich.edu        for flag in compound:
7547379Sgblack@eecs.umich.edu            code('$flag,')
7557379Sgblack@eecs.umich.edu        code('(Flags)-1')
7567379Sgblack@eecs.umich.edu        code.dedent()
7577388Sgblack@eecs.umich.edu        code('};')
7587388Sgblack@eecs.umich.edu        code()
7597379Sgblack@eecs.umich.edu
7607396Sgblack@eecs.umich.edu    # Finally the compoundFlags[] array maps the compound flags
7617382Sgblack@eecs.umich.edu    # to their individual arrays/
7627379Sgblack@eecs.umich.edu    code('const Flags *Trace::compoundFlags[] = {')
7637379Sgblack@eecs.umich.edu    code.indent()
7647396Sgblack@eecs.umich.edu    code('AllMap,')
7657379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
7667382Sgblack@eecs.umich.edu        if compound:
7677382Sgblack@eecs.umich.edu            code('${flag}Map,')
7687382Sgblack@eecs.umich.edu    # file trailer
7697382Sgblack@eecs.umich.edu    code.dedent()
7707382Sgblack@eecs.umich.edu    code('};')
7717382Sgblack@eecs.umich.edu
7727382Sgblack@eecs.umich.edu    code.write(str(target[0]))
7737382Sgblack@eecs.umich.edu
7747382Sgblack@eecs.umich.edudef traceFlagsHH(target, source, env):
7757382Sgblack@eecs.umich.edu    assert(len(target) == 1)
7767396Sgblack@eecs.umich.edu
7777396Sgblack@eecs.umich.edu    allFlags = getFlags(source)
7787396Sgblack@eecs.umich.edu    code = code_formatter()
7797396Sgblack@eecs.umich.edu
7807396Sgblack@eecs.umich.edu    # file header boilerplate
7817396Sgblack@eecs.umich.edu    code('''\
7827396Sgblack@eecs.umich.edu/*
7837396Sgblack@eecs.umich.edu * DO NOT EDIT THIS FILE!
7847396Sgblack@eecs.umich.edu *
7857396Sgblack@eecs.umich.edu * Automatically generated from traceflags.py
7867396Sgblack@eecs.umich.edu */
7877396Sgblack@eecs.umich.edu
7887396Sgblack@eecs.umich.edu#ifndef __BASE_TRACE_FLAGS_HH__
7897396Sgblack@eecs.umich.edu#define __BASE_TRACE_FLAGS_HH__
7907396Sgblack@eecs.umich.edu
7917396Sgblack@eecs.umich.edunamespace Trace {
7927382Sgblack@eecs.umich.edu
7937382Sgblack@eecs.umich.eduenum Flags {''')
7947379Sgblack@eecs.umich.edu
7957379Sgblack@eecs.umich.edu    # Generate the enum.  Base flags come first, then compound flags.
7967379Sgblack@eecs.umich.edu    idx = 0
7977379Sgblack@eecs.umich.edu    code.indent()
7987382Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
7997379Sgblack@eecs.umich.edu        if not compound:
8007379Sgblack@eecs.umich.edu            code('$flag = $idx,')
8017379Sgblack@eecs.umich.edu            idx += 1
8027379Sgblack@eecs.umich.edu
8037382Sgblack@eecs.umich.edu    numBaseFlags = idx
8047379Sgblack@eecs.umich.edu    code('NumFlags = $idx,')
8057379Sgblack@eecs.umich.edu    code.dedent()
8067379Sgblack@eecs.umich.edu    code()
8077379Sgblack@eecs.umich.edu
8087379Sgblack@eecs.umich.edu    # put a comment in here to separate base from compound flags
8097379Sgblack@eecs.umich.edu    code('''
8107382Sgblack@eecs.umich.edu// The remaining enum values are *not* valid indices for Trace::flags.
8117379Sgblack@eecs.umich.edu// They are "compound" flags, which correspond to sets of base
8127379Sgblack@eecs.umich.edu// flags, and are used by changeFlag.''')
8137379Sgblack@eecs.umich.edu
8147379Sgblack@eecs.umich.edu    code.indent()
8157382Sgblack@eecs.umich.edu    code('All = $idx,')
8167379Sgblack@eecs.umich.edu    idx += 1
8177379Sgblack@eecs.umich.edu    for flag, compound, desc in allFlags:
8187379Sgblack@eecs.umich.edu        if compound:
8197379Sgblack@eecs.umich.edu            code('$flag = $idx,')
8207379Sgblack@eecs.umich.edu            idx += 1
8217379Sgblack@eecs.umich.edu
8227379Sgblack@eecs.umich.edu    numCompoundFlags = idx - numBaseFlags
8237379Sgblack@eecs.umich.edu    code('NumCompoundFlags = $numCompoundFlags')
8247382Sgblack@eecs.umich.edu    code.dedent()
8257379Sgblack@eecs.umich.edu
8267379Sgblack@eecs.umich.edu    # trailer boilerplate
8277379Sgblack@eecs.umich.edu    code('''\
8287379Sgblack@eecs.umich.edu}; // enum Flags
8297382Sgblack@eecs.umich.edu
8307379Sgblack@eecs.umich.edu// Array of strings for SimpleEnumParam
8317379Sgblack@eecs.umich.eduextern const char *flagStrings[];
8327379Sgblack@eecs.umich.eduextern const int numFlagStrings;
8337379Sgblack@eecs.umich.edu
8347379Sgblack@eecs.umich.edu// Array of arraay pointers: for each compound flag, gives the list of
8357379Sgblack@eecs.umich.edu// base flags to set.  Inidividual flag arrays are terminated by -1.
8367382Sgblack@eecs.umich.eduextern const Flags *compoundFlags[];
8377379Sgblack@eecs.umich.edu
8387379Sgblack@eecs.umich.edu} // namespace Trace
8397379Sgblack@eecs.umich.edu
8407379Sgblack@eecs.umich.edu#endif // __BASE_TRACE_FLAGS_HH__
8417382Sgblack@eecs.umich.edu''')
8427379Sgblack@eecs.umich.edu
8437379Sgblack@eecs.umich.edu    code.write(str(target[0]))
8447379Sgblack@eecs.umich.edu
8457379Sgblack@eecs.umich.eduflags = map(Value, trace_flags.values())
8467379Sgblack@eecs.umich.eduenv.Command('base/traceflags.py', flags, 
8477379Sgblack@eecs.umich.edu            MakeAction(traceFlagsPy, " [ TRACING] $STRIP_TARGET"))
8487379Sgblack@eecs.umich.eduPySource('m5', 'base/traceflags.py')
8497379Sgblack@eecs.umich.edu
8507386Sgblack@eecs.umich.eduenv.Command('base/traceflags.hh', flags,
8517379Sgblack@eecs.umich.edu            MakeAction(traceFlagsHH, " [ TRACING] $STRIP_TARGET"))
8527379Sgblack@eecs.umich.eduenv.Command('base/traceflags.cc', flags, 
8537379Sgblack@eecs.umich.edu            MakeAction(traceFlagsCC, " [ TRACING] $STRIP_TARGET"))
8547379Sgblack@eecs.umich.eduSource('base/traceflags.cc')
8557382Sgblack@eecs.umich.edu
8567382Sgblack@eecs.umich.edu# Embed python files.  All .py files that have been indicated by a
8577382Sgblack@eecs.umich.edu# PySource() call in a SConscript need to be embedded into the M5
8587382Sgblack@eecs.umich.edu# library.  To do that, we compile the file to byte code, marshal the
8597386Sgblack@eecs.umich.edu# byte code, compress it, and then generate a c++ file that
8607379Sgblack@eecs.umich.edu# inserts the result into an array.
8617379Sgblack@eecs.umich.edudef embedPyFile(target, source, env):
8627379Sgblack@eecs.umich.edu    def c_str(string):
8637386Sgblack@eecs.umich.edu        if string is None:
8647379Sgblack@eecs.umich.edu            return "0"
8657379Sgblack@eecs.umich.edu        return '"%s"' % string
8667379Sgblack@eecs.umich.edu
8677379Sgblack@eecs.umich.edu    '''Action function to compile a .py into a code object, marshal
8687382Sgblack@eecs.umich.edu    it, compress it, and stick it into an asm file so the code appears
8697382Sgblack@eecs.umich.edu    as just bytes with a label in the data section'''
8707382Sgblack@eecs.umich.edu
8717382Sgblack@eecs.umich.edu    src = file(str(source[0]), 'r').read()
8727386Sgblack@eecs.umich.edu
8737379Sgblack@eecs.umich.edu    pysource = PySource.tnodes[source[0]]
8747379Sgblack@eecs.umich.edu    compiled = compile(src, pysource.abspath, 'exec')
8757376Sgblack@eecs.umich.edu    marshalled = marshal.dumps(compiled)
8767376Sgblack@eecs.umich.edu    compressed = zlib.compress(marshalled)
8777376Sgblack@eecs.umich.edu    data = compressed
8787376Sgblack@eecs.umich.edu    sym = pysource.symname
8797376Sgblack@eecs.umich.edu
8807376Sgblack@eecs.umich.edu    code = code_formatter()
8817376Sgblack@eecs.umich.edu    code('''\
8827376Sgblack@eecs.umich.edu#include "sim/init.hh"
8837376Sgblack@eecs.umich.edu
8847376Sgblack@eecs.umich.edunamespace {
8857376Sgblack@eecs.umich.edu
8867376Sgblack@eecs.umich.educonst char data_${sym}[] = {
8877376Sgblack@eecs.umich.edu''')
8887376Sgblack@eecs.umich.edu    code.indent()
8897376Sgblack@eecs.umich.edu    step = 16
8907376Sgblack@eecs.umich.edu    for i in xrange(0, len(data), step):
8917376Sgblack@eecs.umich.edu        x = array.array('B', data[i:i+step])
8927376Sgblack@eecs.umich.edu        code(''.join('%d,' % d for d in x))
8937376Sgblack@eecs.umich.edu    code.dedent()
8947376Sgblack@eecs.umich.edu    
8957376Sgblack@eecs.umich.edu    code('''};
8967376Sgblack@eecs.umich.edu
8977376Sgblack@eecs.umich.eduEmbeddedPython embedded_${sym}(
8987376Sgblack@eecs.umich.edu    ${{c_str(pysource.arcname)}},
8997376Sgblack@eecs.umich.edu    ${{c_str(pysource.abspath)}},
9007376Sgblack@eecs.umich.edu    ${{c_str(pysource.modpath)}},
9017376Sgblack@eecs.umich.edu    data_${sym},
9027376Sgblack@eecs.umich.edu    ${{len(data)}},
9037376Sgblack@eecs.umich.edu    ${{len(marshalled)}});
9047376Sgblack@eecs.umich.edu
9057376Sgblack@eecs.umich.edu} // anonymous namespace
9067376Sgblack@eecs.umich.edu''')
9077376Sgblack@eecs.umich.edu    code.write(str(target[0]))
9087376Sgblack@eecs.umich.edu
9097376Sgblack@eecs.umich.edufor source in PySource.all:
9107376Sgblack@eecs.umich.edu    env.Command(source.cpp, source.tnode, 
9117376Sgblack@eecs.umich.edu                MakeAction(embedPyFile, " [EMBED PY] $STRIP_TARGET"))
9127376Sgblack@eecs.umich.edu    Source(source.cpp)
9137376Sgblack@eecs.umich.edu
9147376Sgblack@eecs.umich.edu########################################################################
9157376Sgblack@eecs.umich.edu#
9167376Sgblack@eecs.umich.edu# Define binaries.  Each different build type (debug, opt, etc.) gets
9177376Sgblack@eecs.umich.edu# a slightly different build environment.
9187376Sgblack@eecs.umich.edu#
9197376Sgblack@eecs.umich.edu
9207376Sgblack@eecs.umich.edu# List of constructed environments to pass back to SConstruct
9217376Sgblack@eecs.umich.eduenvList = []
9227376Sgblack@eecs.umich.edu
9237376Sgblack@eecs.umich.edudate_source = Source('base/date.cc', skip_lib=True)
9247376Sgblack@eecs.umich.edu
9257376Sgblack@eecs.umich.edu# Function to create a new build environment as clone of current
9267376Sgblack@eecs.umich.edu# environment 'env' with modified object suffix and optional stripped
9277376Sgblack@eecs.umich.edu# binary.  Additional keyword arguments are appended to corresponding
9287376Sgblack@eecs.umich.edu# build environment vars.
9297376Sgblack@eecs.umich.edudef makeEnv(label, objsfx, strip = False, **kwargs):
9307376Sgblack@eecs.umich.edu    # SCons doesn't know to append a library suffix when there is a '.' in the
9317376Sgblack@eecs.umich.edu    # name.  Use '_' instead.
9327376Sgblack@eecs.umich.edu    libname = 'm5_' + label
9337376Sgblack@eecs.umich.edu    exename = 'm5.' + label
9347376Sgblack@eecs.umich.edu
9357376Sgblack@eecs.umich.edu    new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's')
9367376Sgblack@eecs.umich.edu    new_env.Label = label
9377396Sgblack@eecs.umich.edu    new_env.Append(**kwargs)
9387396Sgblack@eecs.umich.edu
9397396Sgblack@eecs.umich.edu    swig_env = new_env.Clone()
9407396Sgblack@eecs.umich.edu    swig_env.Append(CCFLAGS='-Werror')
9417396Sgblack@eecs.umich.edu    if env['GCC']:
9427396Sgblack@eecs.umich.edu        swig_env.Append(CCFLAGS='-Wno-uninitialized')
9437396Sgblack@eecs.umich.edu        swig_env.Append(CCFLAGS='-Wno-sign-compare')
9447396Sgblack@eecs.umich.edu        swig_env.Append(CCFLAGS='-Wno-parentheses')
9457396Sgblack@eecs.umich.edu
9467396Sgblack@eecs.umich.edu    werror_env = new_env.Clone()
9477396Sgblack@eecs.umich.edu    werror_env.Append(CCFLAGS='-Werror')
9487396Sgblack@eecs.umich.edu
9497396Sgblack@eecs.umich.edu    def make_obj(source, static, extra_deps = None):
9507396Sgblack@eecs.umich.edu        '''This function adds the specified source to the correct
9517396Sgblack@eecs.umich.edu        build environment, and returns the corresponding SCons Object
9527396Sgblack@eecs.umich.edu        nodes'''
9537396Sgblack@eecs.umich.edu
9547396Sgblack@eecs.umich.edu        if source.swig:
9557396Sgblack@eecs.umich.edu            env = swig_env
9567396Sgblack@eecs.umich.edu        elif source.Werror:
9577396Sgblack@eecs.umich.edu            env = werror_env
9587396Sgblack@eecs.umich.edu        else:
9597396Sgblack@eecs.umich.edu            env = new_env
9607396Sgblack@eecs.umich.edu
9617396Sgblack@eecs.umich.edu        if static:
9627396Sgblack@eecs.umich.edu            obj = env.StaticObject(source.tnode)
9637396Sgblack@eecs.umich.edu        else:
9647396Sgblack@eecs.umich.edu            obj = env.SharedObject(source.tnode)
9657396Sgblack@eecs.umich.edu
9667396Sgblack@eecs.umich.edu        if extra_deps:
9677396Sgblack@eecs.umich.edu            env.Depends(obj, extra_deps)
9687396Sgblack@eecs.umich.edu
9697396Sgblack@eecs.umich.edu        return obj
9707396Sgblack@eecs.umich.edu
9717396Sgblack@eecs.umich.edu    static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)]
9727396Sgblack@eecs.umich.edu    shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)]
9737396Sgblack@eecs.umich.edu
9747396Sgblack@eecs.umich.edu    static_date = make_obj(date_source, static=True, extra_deps=static_objs)
9757396Sgblack@eecs.umich.edu    static_objs.append(static_date)
9767396Sgblack@eecs.umich.edu    
9777396Sgblack@eecs.umich.edu    shared_date = make_obj(date_source, static=False, extra_deps=shared_objs)
9787396Sgblack@eecs.umich.edu    shared_objs.append(shared_date)
9797396Sgblack@eecs.umich.edu
9807396Sgblack@eecs.umich.edu    # First make a library of everything but main() so other programs can
9817396Sgblack@eecs.umich.edu    # link against m5.
9827396Sgblack@eecs.umich.edu    static_lib = new_env.StaticLibrary(libname, static_objs)
9837396Sgblack@eecs.umich.edu    shared_lib = new_env.SharedLibrary(libname, shared_objs)
9847396Sgblack@eecs.umich.edu
9857396Sgblack@eecs.umich.edu    for target, sources in unit_tests:
9867375Sgblack@eecs.umich.edu        objs = [ make_obj(s, static=True) for s in sources ]
9877375Sgblack@eecs.umich.edu        new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs)
9887396Sgblack@eecs.umich.edu
9897396Sgblack@eecs.umich.edu    # Now link a stub with main() and the static library.
9907396Sgblack@eecs.umich.edu    bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ]
9917396Sgblack@eecs.umich.edu    progname = exename
9927396Sgblack@eecs.umich.edu    if strip:
9937396Sgblack@eecs.umich.edu        progname += '.unstripped'
9947396Sgblack@eecs.umich.edu
9957396Sgblack@eecs.umich.edu    targets = new_env.Program(progname, bin_objs + static_objs)
9967396Sgblack@eecs.umich.edu
9977396Sgblack@eecs.umich.edu    if strip:
9987396Sgblack@eecs.umich.edu        if sys.platform == 'sunos5':
9997396Sgblack@eecs.umich.edu            cmd = 'cp $SOURCE $TARGET; strip $TARGET'
10007396Sgblack@eecs.umich.edu        else:
10017396Sgblack@eecs.umich.edu            cmd = 'strip $SOURCE -o $TARGET'
10027396Sgblack@eecs.umich.edu        targets = new_env.Command(exename, progname,
10037396Sgblack@eecs.umich.edu                    MakeAction(cmd, " [   STRIP] $STRIP_TARGET"))
10047396Sgblack@eecs.umich.edu            
10057396Sgblack@eecs.umich.edu    new_env.M5Binary = targets[0]
10067396Sgblack@eecs.umich.edu    envList.append(new_env)
10077396Sgblack@eecs.umich.edu
10087396Sgblack@eecs.umich.edu# Debug binary
10097396Sgblack@eecs.umich.educcflags = {}
10107396Sgblack@eecs.umich.eduif env['GCC']:
10117396Sgblack@eecs.umich.edu    if sys.platform == 'sunos5':
10127396Sgblack@eecs.umich.edu        ccflags['debug'] = '-gstabs+'
10137396Sgblack@eecs.umich.edu    else:
10147396Sgblack@eecs.umich.edu        ccflags['debug'] = '-ggdb3'
10157396Sgblack@eecs.umich.edu    ccflags['opt'] = '-g -O3'
10167396Sgblack@eecs.umich.edu    ccflags['fast'] = '-O3'
10177396Sgblack@eecs.umich.edu    ccflags['prof'] = '-O3 -g -pg'
10187396Sgblack@eecs.umich.eduelif env['SUNCC']:
10197396Sgblack@eecs.umich.edu    ccflags['debug'] = '-g0'
10207396Sgblack@eecs.umich.edu    ccflags['opt'] = '-g -O'
10217396Sgblack@eecs.umich.edu    ccflags['fast'] = '-fast'
10227396Sgblack@eecs.umich.edu    ccflags['prof'] = '-fast -g -pg'
10237396Sgblack@eecs.umich.eduelif env['ICC']:
10247396Sgblack@eecs.umich.edu    ccflags['debug'] = '-g -O0'
10257396Sgblack@eecs.umich.edu    ccflags['opt'] = '-g -O'
10267396Sgblack@eecs.umich.edu    ccflags['fast'] = '-fast'
10277396Sgblack@eecs.umich.edu    ccflags['prof'] = '-fast -g -pg'
10287396Sgblack@eecs.umich.eduelse:
10297396Sgblack@eecs.umich.edu    print 'Unknown compiler, please fix compiler options'
10307396Sgblack@eecs.umich.edu    Exit(1)
10317396Sgblack@eecs.umich.edu
10327396Sgblack@eecs.umich.edumakeEnv('debug', '.do',
10337396Sgblack@eecs.umich.edu        CCFLAGS = Split(ccflags['debug']),
10347396Sgblack@eecs.umich.edu        CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])
10357396Sgblack@eecs.umich.edu
10367396Sgblack@eecs.umich.edu# Optimized binary
10377396Sgblack@eecs.umich.edumakeEnv('opt', '.o',
10387396Sgblack@eecs.umich.edu        CCFLAGS = Split(ccflags['opt']),
10397396Sgblack@eecs.umich.edu        CPPDEFINES = ['TRACING_ON=1'])
10407396Sgblack@eecs.umich.edu
10417396Sgblack@eecs.umich.edu# "Fast" binary
10427396Sgblack@eecs.umich.edumakeEnv('fast', '.fo', strip = True,
10437396Sgblack@eecs.umich.edu        CCFLAGS = Split(ccflags['fast']),
10447396Sgblack@eecs.umich.edu        CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])
10457396Sgblack@eecs.umich.edu
10467396Sgblack@eecs.umich.edu# Profiled binary
10477396Sgblack@eecs.umich.edumakeEnv('prof', '.po',
10487396Sgblack@eecs.umich.edu        CCFLAGS = Split(ccflags['prof']),
10497396Sgblack@eecs.umich.edu        CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
10507396Sgblack@eecs.umich.edu        LINKFLAGS = '-pg')
10517396Sgblack@eecs.umich.edu
10527396Sgblack@eecs.umich.eduReturn('envList')
10537396Sgblack@eecs.umich.edu