SConscript revision 6108:66014cd0dc61
1955SN/A# -*- mode:python -*-
2955SN/A
37816Ssteve.reinhardt@amd.com# Copyright (c) 2004-2005 The Regents of The University of Michigan
45871Snate@binkert.org# All rights reserved.
51762SN/A#
6955SN/A# Redistribution and use in source and binary forms, with or without
7955SN/A# modification, are permitted provided that the following conditions are
8955SN/A# met: redistributions of source code must retain the above copyright
9955SN/A# notice, this list of conditions and the following disclaimer;
10955SN/A# redistributions in binary form must reproduce the above copyright
11955SN/A# notice, this list of conditions and the following disclaimer in the
12955SN/A# documentation and/or other materials provided with the distribution;
13955SN/A# neither the name of the copyright holders nor the names of its
14955SN/A# contributors may be used to endorse or promote products derived from
15955SN/A# this software without specific prior written permission.
16955SN/A#
17955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28955SN/A#
29955SN/A# Authors: Nathan Binkert
302665Ssaidi@eecs.umich.edu
312665Ssaidi@eecs.umich.eduimport array
325863Snate@binkert.orgimport imp
33955SN/Aimport marshal
34955SN/Aimport os
35955SN/Aimport re
36955SN/Aimport sys
37955SN/Aimport zlib
388878Ssteve.reinhardt@amd.com
392632Sstever@eecs.umich.edufrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath
408878Ssteve.reinhardt@amd.com
412632Sstever@eecs.umich.eduimport SCons
42955SN/A
438878Ssteve.reinhardt@amd.com# This file defines how to build a particular configuration of M5
442632Sstever@eecs.umich.edu# based on variable settings in the 'env' build environment.
452761Sstever@eecs.umich.edu
462632Sstever@eecs.umich.eduImport('*')
472632Sstever@eecs.umich.edu
482632Sstever@eecs.umich.edu# Children need to see the environment
492761Sstever@eecs.umich.eduExport('env')
502761Sstever@eecs.umich.edu
512761Sstever@eecs.umich.edubuild_env = dict([(opt, env[opt]) for opt in export_vars])
528878Ssteve.reinhardt@amd.com
538878Ssteve.reinhardt@amd.comdef sort_list(_list):
542761Sstever@eecs.umich.edu    """return a sorted copy of '_list'"""
552761Sstever@eecs.umich.edu    if isinstance(_list, list):
562761Sstever@eecs.umich.edu        _list = _list[:]
572761Sstever@eecs.umich.edu    else:
582761Sstever@eecs.umich.edu        _list = list(_list)
598878Ssteve.reinhardt@amd.com    _list.sort()
608878Ssteve.reinhardt@amd.com    return _list
612632Sstever@eecs.umich.edu
622632Sstever@eecs.umich.educlass PySourceFile(object):
638878Ssteve.reinhardt@amd.com    invalid_sym_char = re.compile('[^A-z0-9_]')
648878Ssteve.reinhardt@amd.com    def __init__(self, package, tnode):
652632Sstever@eecs.umich.edu        snode = tnode.srcnode()
66955SN/A        filename = str(tnode)
67955SN/A        pyname = basename(filename)
68955SN/A        assert pyname.endswith('.py')
695863Snate@binkert.org        name = pyname[:-3]
705863Snate@binkert.org        if package:
715863Snate@binkert.org            path = package.split('.')
725863Snate@binkert.org        else:
735863Snate@binkert.org            path = []
745863Snate@binkert.org
755863Snate@binkert.org        modpath = path[:]
765863Snate@binkert.org        if name != '__init__':
775863Snate@binkert.org            modpath += [name]
785863Snate@binkert.org        modpath = '.'.join(modpath)
795863Snate@binkert.org
808878Ssteve.reinhardt@amd.com        arcpath = path + [ pyname ]
815863Snate@binkert.org        arcname = joinpath(*arcpath)
825863Snate@binkert.org
835863Snate@binkert.org        debugname = snode.abspath
845863Snate@binkert.org        if not exists(debugname):
855863Snate@binkert.org            debugname = tnode.abspath
865863Snate@binkert.org
875863Snate@binkert.org        self.tnode = tnode
885863Snate@binkert.org        self.snode = snode
895863Snate@binkert.org        self.pyname = pyname
905863Snate@binkert.org        self.package = package
915863Snate@binkert.org        self.modpath = modpath
925863Snate@binkert.org        self.arcname = arcname
935863Snate@binkert.org        self.debugname = debugname
945863Snate@binkert.org        self.compiled = File(filename + 'c')
955863Snate@binkert.org        self.assembly = File(filename + '.s')
968878Ssteve.reinhardt@amd.com        self.symname = "PyEMB_" + self.invalid_sym_char.sub('_', modpath)
975863Snate@binkert.org        
985863Snate@binkert.org
995863Snate@binkert.org########################################################################
1006654Snate@binkert.org# Code for adding source files of various types
101955SN/A#
1025396Ssaidi@eecs.umich.educc_lib_sources = []
1035863Snate@binkert.orgdef Source(source):
1045863Snate@binkert.org    '''Add a source file to the libm5 build'''
1054202Sbinkertn@umich.edu    if not isinstance(source, SCons.Node.FS.File):
1065863Snate@binkert.org        source = File(source)
1075863Snate@binkert.org
1085863Snate@binkert.org    cc_lib_sources.append(source)
1095863Snate@binkert.org
110955SN/Acc_bin_sources = []
1116654Snate@binkert.orgdef BinSource(source):
1125273Sstever@gmail.com    '''Add a source file to the m5 binary build'''
1135871Snate@binkert.org    if not isinstance(source, SCons.Node.FS.File):
1145273Sstever@gmail.com        source = File(source)
1156655Snate@binkert.org
1168878Ssteve.reinhardt@amd.com    cc_bin_sources.append(source)
1176655Snate@binkert.org
1186655Snate@binkert.orgpy_sources = []
1199219Spower.jg@gmail.comdef PySource(package, source):
1206655Snate@binkert.org    '''Add a python source file to the named package'''
1215871Snate@binkert.org    if not isinstance(source, SCons.Node.FS.File):
1226654Snate@binkert.org        source = File(source)
1238947Sandreas.hansson@arm.com
1245396Ssaidi@eecs.umich.edu    source = PySourceFile(package, source)
1258120Sgblack@eecs.umich.edu    py_sources.append(source)
1268120Sgblack@eecs.umich.edu
1278120Sgblack@eecs.umich.edusim_objects_fixed = False
1288120Sgblack@eecs.umich.edusim_object_modfiles = set()
1298120Sgblack@eecs.umich.edudef SimObject(source):
1308120Sgblack@eecs.umich.edu    '''Add a SimObject python file as a python source object and add
1318120Sgblack@eecs.umich.edu    it to a list of sim object modules'''
1328120Sgblack@eecs.umich.edu
1338879Ssteve.reinhardt@amd.com    if sim_objects_fixed:
1348879Ssteve.reinhardt@amd.com        raise AttributeError, "Too late to call SimObject now."
1358879Ssteve.reinhardt@amd.com
1368879Ssteve.reinhardt@amd.com    if not isinstance(source, SCons.Node.FS.File):
1378879Ssteve.reinhardt@amd.com        source = File(source)
1388879Ssteve.reinhardt@amd.com
1398879Ssteve.reinhardt@amd.com    PySource('m5.objects', source)
1408879Ssteve.reinhardt@amd.com    modfile = basename(str(source))
1418879Ssteve.reinhardt@amd.com    assert modfile.endswith('.py')
1428879Ssteve.reinhardt@amd.com    modname = modfile[:-3]
1438879Ssteve.reinhardt@amd.com    sim_object_modfiles.add(modname)
1448879Ssteve.reinhardt@amd.com
1458879Ssteve.reinhardt@amd.comswig_sources = []
1468120Sgblack@eecs.umich.edudef SwigSource(package, source):
1478120Sgblack@eecs.umich.edu    '''Add a swig file to build'''
1488120Sgblack@eecs.umich.edu    if not isinstance(source, SCons.Node.FS.File):
1498120Sgblack@eecs.umich.edu        source = File(source)
1508120Sgblack@eecs.umich.edu    val = source,package
1518120Sgblack@eecs.umich.edu    swig_sources.append(val)
1528120Sgblack@eecs.umich.edu
1538120Sgblack@eecs.umich.eduunit_tests = []
1548120Sgblack@eecs.umich.edudef UnitTest(target, sources):
1558120Sgblack@eecs.umich.edu    if not isinstance(sources, (list, tuple)):
1568120Sgblack@eecs.umich.edu        sources = [ sources ]
1578120Sgblack@eecs.umich.edu    
1588120Sgblack@eecs.umich.edu    srcs = []
1598120Sgblack@eecs.umich.edu    for source in sources:
1608879Ssteve.reinhardt@amd.com        if not isinstance(source, SCons.Node.FS.File):
1618879Ssteve.reinhardt@amd.com            source = File(source)
1628879Ssteve.reinhardt@amd.com        srcs.append(source)
1638879Ssteve.reinhardt@amd.com            
1648879Ssteve.reinhardt@amd.com    unit_tests.append((target, srcs))
1658879Ssteve.reinhardt@amd.com
1668879Ssteve.reinhardt@amd.com# Children should have access
1678879Ssteve.reinhardt@amd.comExport('Source')
1689227Sandreas.hansson@arm.comExport('BinSource')
1699227Sandreas.hansson@arm.comExport('PySource')
1708879Ssteve.reinhardt@amd.comExport('SimObject')
1718879Ssteve.reinhardt@amd.comExport('SwigSource')
1728879Ssteve.reinhardt@amd.comExport('UnitTest')
1738879Ssteve.reinhardt@amd.com
1748120Sgblack@eecs.umich.edu########################################################################
1758947Sandreas.hansson@arm.com#
1767816Ssteve.reinhardt@amd.com# Trace Flags
1775871Snate@binkert.org#
1785871Snate@binkert.orgtrace_flags = {}
1796121Snate@binkert.orgdef TraceFlag(name, desc=None):
1805871Snate@binkert.org    if name in trace_flags:
1815871Snate@binkert.org        raise AttributeError, "Flag %s already specified" % name
1829119Sandreas.hansson@arm.com    trace_flags[name] = (name, (), desc)
1839119Sandreas.hansson@arm.com
184955SN/Adef CompoundFlag(name, flags, desc=None):
1855871Snate@binkert.org    if name in trace_flags:
1865871Snate@binkert.org        raise AttributeError, "Flag %s already specified" % name
1875871Snate@binkert.org
1885871Snate@binkert.org    compound = tuple(flags)
189955SN/A    for flag in compound:
1906121Snate@binkert.org        if flag not in trace_flags:
1918881Smarc.orr@gmail.com            raise AttributeError, "Trace flag %s not found" % flag
1926121Snate@binkert.org        if trace_flags[flag][1]:
1936121Snate@binkert.org            raise AttributeError, \
1941533SN/A                "Compound flag can't point to another compound flag"
1959239Sandreas.hansson@arm.com
1969239Sandreas.hansson@arm.com    trace_flags[name] = (name, compound, desc)
1979239Sandreas.hansson@arm.com
1989239Sandreas.hansson@arm.comExport('TraceFlag')
1999239Sandreas.hansson@arm.comExport('CompoundFlag')
2009239Sandreas.hansson@arm.com
2019239Sandreas.hansson@arm.com########################################################################
2029239Sandreas.hansson@arm.com#
2039239Sandreas.hansson@arm.com# Set some compiler variables
2049239Sandreas.hansson@arm.com#
2059239Sandreas.hansson@arm.com
2069239Sandreas.hansson@arm.com# Include file paths are rooted in this directory.  SCons will
2076655Snate@binkert.org# automatically expand '.' to refer to both the source directory and
2086655Snate@binkert.org# the corresponding build directory to pick up generated include
2096655Snate@binkert.org# files.
2106655Snate@binkert.orgenv.Append(CPPPATH=Dir('.'))
2115871Snate@binkert.org
2125871Snate@binkert.orgfor extra_dir in extras_dir_list:
2135863Snate@binkert.org    env.Append(CPPPATH=Dir(extra_dir))
2145871Snate@binkert.org
2158878Ssteve.reinhardt@amd.com# Add a flag defining what THE_ISA should be for all compilation
2165871Snate@binkert.orgenv.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
2175871Snate@binkert.org
2185871Snate@binkert.org# Workaround for bug in SCons version > 0.97d20071212
2195863Snate@binkert.org# Scons bug id: 2006 M5 Bug id: 308 
2206121Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True):
2215863Snate@binkert.org    Dir(root[len(base_dir) + 1:])
2225871Snate@binkert.org
2238336Ssteve.reinhardt@amd.com########################################################################
2248336Ssteve.reinhardt@amd.com#
2258336Ssteve.reinhardt@amd.com# Walk the tree and execute all SConscripts in subdirectories
2268336Ssteve.reinhardt@amd.com#
2274678Snate@binkert.org
2288336Ssteve.reinhardt@amd.comhere = Dir('.').srcnode().abspath
2298336Ssteve.reinhardt@amd.comfor root, dirs, files in os.walk(base_dir, topdown=True):
2308336Ssteve.reinhardt@amd.com    if root == here:
2314678Snate@binkert.org        # we don't want to recurse back into this SConscript
2324678Snate@binkert.org        continue
2334678Snate@binkert.org
2344678Snate@binkert.org    if 'SConscript' in files:
2357827Snate@binkert.org        build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:])
2367827Snate@binkert.org        SConscript(joinpath(root, 'SConscript'), build_dir=build_dir)
2378336Ssteve.reinhardt@amd.com
2384678Snate@binkert.orgfor extra_dir in extras_dir_list:
2398336Ssteve.reinhardt@amd.com    prefix_len = len(dirname(extra_dir)) + 1
2408336Ssteve.reinhardt@amd.com    for root, dirs, files in os.walk(extra_dir, topdown=True):
2418336Ssteve.reinhardt@amd.com        if 'SConscript' in files:
2428336Ssteve.reinhardt@amd.com            build_dir = joinpath(env['BUILDDIR'], root[prefix_len:])
2438336Ssteve.reinhardt@amd.com            SConscript(joinpath(root, 'SConscript'), build_dir=build_dir)
2448336Ssteve.reinhardt@amd.com
2455871Snate@binkert.orgfor opt in export_vars:
2465871Snate@binkert.org    env.ConfigFile(opt)
2478336Ssteve.reinhardt@amd.com
2488336Ssteve.reinhardt@amd.com########################################################################
2498336Ssteve.reinhardt@amd.com#
2508336Ssteve.reinhardt@amd.com# Prevent any SimObjects from being added after this point, they
2518336Ssteve.reinhardt@amd.com# should all have been added in the SConscripts above
2525871Snate@binkert.org#
2538336Ssteve.reinhardt@amd.comclass DictImporter(object):
2548336Ssteve.reinhardt@amd.com    '''This importer takes a dictionary of arbitrary module names that
2558336Ssteve.reinhardt@amd.com    map to arbitrary filenames.'''
2568336Ssteve.reinhardt@amd.com    def __init__(self, modules):
2578336Ssteve.reinhardt@amd.com        self.modules = modules
2584678Snate@binkert.org        self.installed = set()
2595871Snate@binkert.org
2604678Snate@binkert.org    def __del__(self):
2618336Ssteve.reinhardt@amd.com        self.unload()
2628336Ssteve.reinhardt@amd.com
2638336Ssteve.reinhardt@amd.com    def unload(self):
2648336Ssteve.reinhardt@amd.com        import sys
2658336Ssteve.reinhardt@amd.com        for module in self.installed:
2668336Ssteve.reinhardt@amd.com            del sys.modules[module]
2678336Ssteve.reinhardt@amd.com        self.installed = set()
2688336Ssteve.reinhardt@amd.com
2698336Ssteve.reinhardt@amd.com    def find_module(self, fullname, path):
2708336Ssteve.reinhardt@amd.com        if fullname == 'defines':
2718336Ssteve.reinhardt@amd.com            return self
2728336Ssteve.reinhardt@amd.com
2738336Ssteve.reinhardt@amd.com        if fullname == 'm5.objects':
2748336Ssteve.reinhardt@amd.com            return self
2758336Ssteve.reinhardt@amd.com
2768336Ssteve.reinhardt@amd.com        if fullname.startswith('m5.internal'):
2778336Ssteve.reinhardt@amd.com            return None
2785871Snate@binkert.org
2796121Snate@binkert.org        if fullname in self.modules and exists(self.modules[fullname]):
280955SN/A            return self
281955SN/A
2822632Sstever@eecs.umich.edu        return None
2832632Sstever@eecs.umich.edu
284955SN/A    def load_module(self, fullname):
285955SN/A        mod = imp.new_module(fullname)
286955SN/A        sys.modules[fullname] = mod
287955SN/A        self.installed.add(fullname)
2888878Ssteve.reinhardt@amd.com
289955SN/A        mod.__loader__ = self
2902632Sstever@eecs.umich.edu        if fullname == 'm5.objects':
2912632Sstever@eecs.umich.edu            mod.__path__ = fullname.split('.')
2922632Sstever@eecs.umich.edu            return mod
2932632Sstever@eecs.umich.edu
2942632Sstever@eecs.umich.edu        if fullname == 'defines':
2952632Sstever@eecs.umich.edu            mod.__dict__['buildEnv'] = build_env
2962632Sstever@eecs.umich.edu            return mod
2978268Ssteve.reinhardt@amd.com
2988268Ssteve.reinhardt@amd.com        srcfile = self.modules[fullname]
2998268Ssteve.reinhardt@amd.com        if basename(srcfile) == '__init__.py':
3008268Ssteve.reinhardt@amd.com            mod.__path__ = fullname.split('.')
3018268Ssteve.reinhardt@amd.com        mod.__file__ = srcfile
3028268Ssteve.reinhardt@amd.com
3038268Ssteve.reinhardt@amd.com        exec file(srcfile, 'r') in mod.__dict__
3042632Sstever@eecs.umich.edu
3052632Sstever@eecs.umich.edu        return mod
3062632Sstever@eecs.umich.edu
3072632Sstever@eecs.umich.edupy_modules = {}
3088268Ssteve.reinhardt@amd.comfor source in py_sources:
3092632Sstever@eecs.umich.edu    py_modules[source.modpath] = source.snode.abspath
3108268Ssteve.reinhardt@amd.com
3118268Ssteve.reinhardt@amd.com# install the python importer so we can grab stuff from the source
3128268Ssteve.reinhardt@amd.com# tree itself.  We can't have SimObjects added after this point or
3138268Ssteve.reinhardt@amd.com# else we won't know about them for the rest of the stuff.
3143718Sstever@eecs.umich.edusim_objects_fixed = True
3152634Sstever@eecs.umich.eduimporter = DictImporter(py_modules)
3162634Sstever@eecs.umich.edusys.meta_path[0:0] = [ importer ]
3175863Snate@binkert.org
3182638Sstever@eecs.umich.eduimport m5
3198268Ssteve.reinhardt@amd.com
3202632Sstever@eecs.umich.edu# import all sim objects so we can populate the all_objects list
3212632Sstever@eecs.umich.edu# make sure that we're working with a list, then let's sort it
3222632Sstever@eecs.umich.edusim_objects = list(sim_object_modfiles)
3232632Sstever@eecs.umich.edusim_objects.sort()
3242632Sstever@eecs.umich.edufor simobj in sim_objects:
3251858SN/A    exec('from m5.objects import %s' % simobj)
3263716Sstever@eecs.umich.edu
3272638Sstever@eecs.umich.edu# we need to unload all of the currently imported modules so that they
3282638Sstever@eecs.umich.edu# will be re-imported the next time the sconscript is run
3292638Sstever@eecs.umich.eduimporter.unload()
3302638Sstever@eecs.umich.edusys.meta_path.remove(importer)
3312638Sstever@eecs.umich.edu
3322638Sstever@eecs.umich.edusim_objects = m5.SimObject.allClasses
3332638Sstever@eecs.umich.eduall_enums = m5.params.allEnums
3345863Snate@binkert.org
3355863Snate@binkert.orgall_params = {}
3365863Snate@binkert.orgfor name,obj in sim_objects.iteritems():
337955SN/A    for param in obj._params.local.values():
3385341Sstever@gmail.com        if not hasattr(param, 'swig_decl'):
3395341Sstever@gmail.com            continue
3405863Snate@binkert.org        pname = param.ptype_str
3417756SAli.Saidi@ARM.com        if pname not in all_params:
3425341Sstever@gmail.com            all_params[pname] = param
3436121Snate@binkert.org
3444494Ssaidi@eecs.umich.edu########################################################################
3456121Snate@binkert.org#
3461105SN/A# calculate extra dependencies
3472667Sstever@eecs.umich.edu#
3482667Sstever@eecs.umich.edumodule_depends = ["m5", "m5.SimObject", "m5.params"]
3492667Sstever@eecs.umich.edudepends = [ File(py_modules[dep]) for dep in module_depends ]
3502667Sstever@eecs.umich.edu
3516121Snate@binkert.org########################################################################
3522667Sstever@eecs.umich.edu#
3535341Sstever@gmail.com# Commands for the basic automatically generated python files
3545863Snate@binkert.org#
3555341Sstever@gmail.com
3565341Sstever@gmail.com# Generate Python file containing a dict specifying the current
3575341Sstever@gmail.com# build_env flags.
3588120Sgblack@eecs.umich.edudef makeDefinesPyFile(target, source, env):
3595341Sstever@gmail.com    f = file(str(target[0]), 'w')
3608120Sgblack@eecs.umich.edu    build_env, hg_info = [ x.get_contents() for x in source ]
3615341Sstever@gmail.com    print >>f, "buildEnv = %s" % build_env
3628120Sgblack@eecs.umich.edu    print >>f, "hgRev = '%s'" % hg_info
3636121Snate@binkert.org    f.close()
3646121Snate@binkert.org
3658980Ssteve.reinhardt@amd.comdefines_info = [ Value(build_env), Value(env['HG_INFO']) ]
3665397Ssaidi@eecs.umich.edu# Generate a file with all of the compile options in it
3675397Ssaidi@eecs.umich.eduenv.Command('python/m5/defines.py', defines_info, makeDefinesPyFile)
3687727SAli.Saidi@ARM.comPySource('m5', 'python/m5/defines.py')
3698268Ssteve.reinhardt@amd.com
3706168Snate@binkert.org# Generate python file containing info about the M5 source code
3715341Sstever@gmail.comdef makeInfoPyFile(target, source, env):
3728120Sgblack@eecs.umich.edu    f = file(str(target[0]), 'w')
3738120Sgblack@eecs.umich.edu    for src in source:
3748120Sgblack@eecs.umich.edu        data = ''.join(file(src.srcnode().abspath, 'r').xreadlines())
3756814Sgblack@eecs.umich.edu        print >>f, "%s = %s" % (src, repr(data))
3765863Snate@binkert.org    f.close()
3778120Sgblack@eecs.umich.edu
3785341Sstever@gmail.com# Generate a file that wraps the basic top level files
3795863Snate@binkert.orgenv.Command('python/m5/info.py',
3808268Ssteve.reinhardt@amd.com            [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
3816121Snate@binkert.org            makeInfoPyFile)
3826121Snate@binkert.orgPySource('m5', 'python/m5/info.py')
3838268Ssteve.reinhardt@amd.com
3845742Snate@binkert.org# Generate the __init__.py file for m5.objects
3855742Snate@binkert.orgdef makeObjectsInitFile(target, source, env):
3865341Sstever@gmail.com    f = file(str(target[0]), 'w')
3875742Snate@binkert.org    print >>f, 'from params import *'
3885742Snate@binkert.org    print >>f, 'from m5.SimObject import *'
3895341Sstever@gmail.com    for module in source:
3906017Snate@binkert.org        print >>f, 'from %s import *' % module.get_contents()
3916121Snate@binkert.org    f.close()
3926017Snate@binkert.org
3937816Ssteve.reinhardt@amd.com# Generate an __init__.py file for the objects package
3947756SAli.Saidi@ARM.comenv.Command('python/m5/objects/__init__.py',
3957756SAli.Saidi@ARM.com            [ Value(o) for o in sort_list(sim_object_modfiles) ],
3967756SAli.Saidi@ARM.com            makeObjectsInitFile)
3977756SAli.Saidi@ARM.comPySource('m5.objects', 'python/m5/objects/__init__.py')
3987756SAli.Saidi@ARM.com
3997756SAli.Saidi@ARM.com########################################################################
4007756SAli.Saidi@ARM.com#
4017756SAli.Saidi@ARM.com# Create all of the SimObject param headers and enum headers
4027816Ssteve.reinhardt@amd.com#
4037816Ssteve.reinhardt@amd.com
4047816Ssteve.reinhardt@amd.comdef createSimObjectParam(target, source, env):
4057816Ssteve.reinhardt@amd.com    assert len(target) == 1 and len(source) == 1
4067816Ssteve.reinhardt@amd.com
4077816Ssteve.reinhardt@amd.com    hh_file = file(target[0].abspath, 'w')
4087816Ssteve.reinhardt@amd.com    name = str(source[0].get_contents())
4097816Ssteve.reinhardt@amd.com    obj = sim_objects[name]
4107816Ssteve.reinhardt@amd.com
4117816Ssteve.reinhardt@amd.com    print >>hh_file, obj.cxx_decl()
4127756SAli.Saidi@ARM.com
4137816Ssteve.reinhardt@amd.comdef createSwigParam(target, source, env):
4147816Ssteve.reinhardt@amd.com    assert len(target) == 1 and len(source) == 1
4157816Ssteve.reinhardt@amd.com
4167816Ssteve.reinhardt@amd.com    i_file = file(target[0].abspath, 'w')
4177816Ssteve.reinhardt@amd.com    name = str(source[0].get_contents())
4187816Ssteve.reinhardt@amd.com    param = all_params[name]
4197816Ssteve.reinhardt@amd.com
4207816Ssteve.reinhardt@amd.com    for line in param.swig_decl():
4217816Ssteve.reinhardt@amd.com        print >>i_file, line
4227816Ssteve.reinhardt@amd.com
4237816Ssteve.reinhardt@amd.comdef createEnumStrings(target, source, env):
4247816Ssteve.reinhardt@amd.com    assert len(target) == 1 and len(source) == 1
4257816Ssteve.reinhardt@amd.com
4267816Ssteve.reinhardt@amd.com    cc_file = file(target[0].abspath, 'w')
4277816Ssteve.reinhardt@amd.com    name = str(source[0].get_contents())
4287816Ssteve.reinhardt@amd.com    obj = all_enums[name]
4297816Ssteve.reinhardt@amd.com
4307816Ssteve.reinhardt@amd.com    print >>cc_file, obj.cxx_def()
4317816Ssteve.reinhardt@amd.com    cc_file.close()
4327816Ssteve.reinhardt@amd.com
4337816Ssteve.reinhardt@amd.comdef createEnumParam(target, source, env):
4347816Ssteve.reinhardt@amd.com    assert len(target) == 1 and len(source) == 1
4357816Ssteve.reinhardt@amd.com
4367816Ssteve.reinhardt@amd.com    hh_file = file(target[0].abspath, 'w')
4377816Ssteve.reinhardt@amd.com    name = str(source[0].get_contents())
4387816Ssteve.reinhardt@amd.com    obj = all_enums[name]
4397816Ssteve.reinhardt@amd.com
4407816Ssteve.reinhardt@amd.com    print >>hh_file, obj.cxx_decl()
4417816Ssteve.reinhardt@amd.com
4427816Ssteve.reinhardt@amd.com# Generate all of the SimObject param struct header files
4437816Ssteve.reinhardt@amd.comparams_hh_files = []
4447816Ssteve.reinhardt@amd.comfor name,simobj in sim_objects.iteritems():
4457816Ssteve.reinhardt@amd.com    extra_deps = [ File(py_modules[simobj.__module__]) ]
4467816Ssteve.reinhardt@amd.com
4477816Ssteve.reinhardt@amd.com    hh_file = File('params/%s.hh' % name)
4487816Ssteve.reinhardt@amd.com    params_hh_files.append(hh_file)
4497816Ssteve.reinhardt@amd.com    env.Command(hh_file, Value(name), createSimObjectParam)
4507816Ssteve.reinhardt@amd.com    env.Depends(hh_file, depends + extra_deps)
4517816Ssteve.reinhardt@amd.com
4527816Ssteve.reinhardt@amd.com# Generate any parameter header files needed
4537816Ssteve.reinhardt@amd.comparams_i_files = []
4547816Ssteve.reinhardt@amd.comfor name,param in all_params.iteritems():
4557816Ssteve.reinhardt@amd.com    if isinstance(param, m5.params.VectorParamDesc):
4567816Ssteve.reinhardt@amd.com        ext = 'vptype'
4577816Ssteve.reinhardt@amd.com    else:
4587816Ssteve.reinhardt@amd.com        ext = 'ptype'
4597816Ssteve.reinhardt@amd.com
4607816Ssteve.reinhardt@amd.com    i_file = File('params/%s_%s.i' % (name, ext))
4617816Ssteve.reinhardt@amd.com    params_i_files.append(i_file)
4627816Ssteve.reinhardt@amd.com    env.Command(i_file, Value(name), createSwigParam)
4637816Ssteve.reinhardt@amd.com    env.Depends(i_file, depends)
4647816Ssteve.reinhardt@amd.com
4657816Ssteve.reinhardt@amd.com# Generate all enum header files
4667816Ssteve.reinhardt@amd.comfor name,enum in all_enums.iteritems():
4677816Ssteve.reinhardt@amd.com    extra_deps = [ File(py_modules[enum.__module__]) ]
4687816Ssteve.reinhardt@amd.com
4697816Ssteve.reinhardt@amd.com    cc_file = File('enums/%s.cc' % name)
4707816Ssteve.reinhardt@amd.com    env.Command(cc_file, Value(name), createEnumStrings)
4717816Ssteve.reinhardt@amd.com    env.Depends(cc_file, depends + extra_deps)
4727816Ssteve.reinhardt@amd.com    Source(cc_file)
4737816Ssteve.reinhardt@amd.com
4748947Sandreas.hansson@arm.com    hh_file = File('enums/%s.hh' % name)
4758947Sandreas.hansson@arm.com    env.Command(hh_file, Value(name), createEnumParam)
4767756SAli.Saidi@ARM.com    env.Depends(hh_file, depends + extra_deps)
4778120Sgblack@eecs.umich.edu
4787756SAli.Saidi@ARM.com# Build the big monolithic swigged params module (wraps all SimObject
4797756SAli.Saidi@ARM.com# param structs and enum structs)
4807756SAli.Saidi@ARM.comdef buildParams(target, source, env):
4817756SAli.Saidi@ARM.com    names = [ s.get_contents() for s in source ]
4827816Ssteve.reinhardt@amd.com    objs = [ sim_objects[name] for name in names ]
4837816Ssteve.reinhardt@amd.com    out = file(target[0].abspath, 'w')
4847816Ssteve.reinhardt@amd.com
4857816Ssteve.reinhardt@amd.com    ordered_objs = []
4867816Ssteve.reinhardt@amd.com    obj_seen = set()
4877816Ssteve.reinhardt@amd.com    def order_obj(obj):
4887816Ssteve.reinhardt@amd.com        name = str(obj)
4897816Ssteve.reinhardt@amd.com        if name in obj_seen:
4907816Ssteve.reinhardt@amd.com            return
4917816Ssteve.reinhardt@amd.com
4927756SAli.Saidi@ARM.com        obj_seen.add(name)
4937756SAli.Saidi@ARM.com        if str(obj) != 'SimObject':
4949227Sandreas.hansson@arm.com            order_obj(obj.__bases__[0])
4959227Sandreas.hansson@arm.com
4969227Sandreas.hansson@arm.com        ordered_objs.append(obj)
4979227Sandreas.hansson@arm.com
4986654Snate@binkert.org    for obj in objs:
4996654Snate@binkert.org        order_obj(obj)
5005871Snate@binkert.org
5016121Snate@binkert.org    enums = set()
5026121Snate@binkert.org    predecls = []
5036121Snate@binkert.org    pd_seen = set()
5048946Sandreas.hansson@arm.com
5058737Skoansin.tan@gmail.com    def add_pds(*pds):
5063940Ssaidi@eecs.umich.edu        for pd in pds:
5073918Ssaidi@eecs.umich.edu            if pd not in pd_seen:
5083918Ssaidi@eecs.umich.edu                predecls.append(pd)
5091858SN/A                pd_seen.add(pd)
5106121Snate@binkert.org
5117739Sgblack@eecs.umich.edu    for obj in ordered_objs:
5127739Sgblack@eecs.umich.edu        params = obj._params.local.values()
5136143Snate@binkert.org        for param in params:
5147618SAli.Saidi@arm.com            ptype = param.ptype
5157618SAli.Saidi@arm.com            if issubclass(ptype, m5.params.Enum):
5167618SAli.Saidi@arm.com                if ptype not in enums:
5177618SAli.Saidi@arm.com                    enums.add(ptype)
5188614Sgblack@eecs.umich.edu            pds = param.swig_predecls()
5197618SAli.Saidi@arm.com            if isinstance(pds, (list, tuple)):
5207618SAli.Saidi@arm.com                add_pds(*pds)
5217618SAli.Saidi@arm.com            else:
5227739Sgblack@eecs.umich.edu                add_pds(pds)
5239224Sandreas.hansson@arm.com
5249224Sandreas.hansson@arm.com    print >>out, '%module params'
5259224Sandreas.hansson@arm.com
5268946Sandreas.hansson@arm.com    print >>out, '%{'
5279227Sandreas.hansson@arm.com    for obj in ordered_objs:
5289227Sandreas.hansson@arm.com        print >>out, '#include "params/%s.hh"' % obj
5299227Sandreas.hansson@arm.com    print >>out, '%}'
5309227Sandreas.hansson@arm.com
5319227Sandreas.hansson@arm.com    for pd in predecls:
5329227Sandreas.hansson@arm.com        print >>out, pd
5339227Sandreas.hansson@arm.com
5349227Sandreas.hansson@arm.com    enums = list(enums)
5359227Sandreas.hansson@arm.com    enums.sort()
5369227Sandreas.hansson@arm.com    for enum in enums:
5379227Sandreas.hansson@arm.com        print >>out, '%%include "enums/%s.hh"' % enum.__name__
5389227Sandreas.hansson@arm.com    print >>out
5399227Sandreas.hansson@arm.com
5409227Sandreas.hansson@arm.com    for obj in ordered_objs:
5419227Sandreas.hansson@arm.com        if obj.swig_objdecls:
5429227Sandreas.hansson@arm.com            for decl in obj.swig_objdecls:
5439227Sandreas.hansson@arm.com                print >>out, decl
5449227Sandreas.hansson@arm.com            continue
5456121Snate@binkert.org
5463940Ssaidi@eecs.umich.edu        class_path = obj.cxx_class.split('::')
5476121Snate@binkert.org        classname = class_path[-1]
5487739Sgblack@eecs.umich.edu        namespaces = class_path[:-1]
5497739Sgblack@eecs.umich.edu        namespaces.reverse()
5507739Sgblack@eecs.umich.edu
5517739Sgblack@eecs.umich.edu        code = ''
5527739Sgblack@eecs.umich.edu
5537739Sgblack@eecs.umich.edu        if namespaces:
5548737Skoansin.tan@gmail.com            code += '// avoid name conflicts\n'
5558737Skoansin.tan@gmail.com            sep_string = '_COLONS_'
5568737Skoansin.tan@gmail.com            flat_name = sep_string.join(class_path)
5578737Skoansin.tan@gmail.com            code += '%%rename(%s) %s;\n' % (flat_name, classname)
5588737Skoansin.tan@gmail.com
5598737Skoansin.tan@gmail.com        code += '// stop swig from creating/wrapping default ctor/dtor\n'
5608737Skoansin.tan@gmail.com        code += '%%nodefault %s;\n' % classname
5618737Skoansin.tan@gmail.com        code += 'class %s ' % classname
5628737Skoansin.tan@gmail.com        if obj._base:
5638737Skoansin.tan@gmail.com            code += ': public %s' % obj._base.cxx_class
5648737Skoansin.tan@gmail.com        code += ' {};\n'
5658737Skoansin.tan@gmail.com
5668737Skoansin.tan@gmail.com        for ns in namespaces:
5678737Skoansin.tan@gmail.com            new_code = 'namespace %s {\n' % ns
5688737Skoansin.tan@gmail.com            new_code += code
5698737Skoansin.tan@gmail.com            new_code += '}\n'
5708737Skoansin.tan@gmail.com            code = new_code
5718737Skoansin.tan@gmail.com
5728946Sandreas.hansson@arm.com        print >>out, code
5738946Sandreas.hansson@arm.com
5748946Sandreas.hansson@arm.com    print >>out, '%%include "src/sim/sim_object_params.hh"' % obj
5758946Sandreas.hansson@arm.com    for obj in ordered_objs:
5769224Sandreas.hansson@arm.com        print >>out, '%%include "params/%s.hh"' % obj
5779224Sandreas.hansson@arm.com
5788946Sandreas.hansson@arm.comparams_file = File('params/params.i')
5798946Sandreas.hansson@arm.comnames = sort_list(sim_objects.keys())
5803918Ssaidi@eecs.umich.eduenv.Command(params_file, [ Value(v) for v in names ], buildParams)
5819068SAli.Saidi@ARM.comenv.Depends(params_file, params_hh_files + params_i_files + depends)
5829068SAli.Saidi@ARM.comSwigSource('m5.objects', params_file)
5839068SAli.Saidi@ARM.com
5849068SAli.Saidi@ARM.com# Build all swig modules
5859068SAli.Saidi@ARM.comswig_modules = []
5869068SAli.Saidi@ARM.comcc_swig_sources = []
5879068SAli.Saidi@ARM.comfor source,package in swig_sources:
5889068SAli.Saidi@ARM.com    filename = str(source)
5899068SAli.Saidi@ARM.com    assert filename.endswith('.i')
5909068SAli.Saidi@ARM.com
5919068SAli.Saidi@ARM.com    base = '.'.join(filename.split('.')[:-1])
5929068SAli.Saidi@ARM.com    module = basename(base)
5939068SAli.Saidi@ARM.com    cc_file = base + '_wrap.cc'
5949068SAli.Saidi@ARM.com    py_file = base + '.py'
5959068SAli.Saidi@ARM.com
5969068SAli.Saidi@ARM.com    env.Command([cc_file, py_file], source,
5973918Ssaidi@eecs.umich.edu                '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
5983918Ssaidi@eecs.umich.edu                '-o ${TARGETS[0]} $SOURCES')
5996157Snate@binkert.org    env.Depends(py_file, source)
6006157Snate@binkert.org    env.Depends(cc_file, source)
6016157Snate@binkert.org
6026157Snate@binkert.org    swig_modules.append(Value(module))
6035397Ssaidi@eecs.umich.edu    cc_swig_sources.append(File(cc_file))
6045397Ssaidi@eecs.umich.edu    PySource(package, py_file)
6056121Snate@binkert.org
6066121Snate@binkert.org# Generate the main swig init file
6076121Snate@binkert.orgdef makeSwigInit(target, source, env):
6086121Snate@binkert.org    f = file(str(target[0]), 'w')
6096121Snate@binkert.org    print >>f, 'extern "C" {'
6106121Snate@binkert.org    for module in source:
6115397Ssaidi@eecs.umich.edu        print >>f, '    void init_%s();' % module.get_contents()
6121851SN/A    print >>f, '}'
6131851SN/A    print >>f, 'void initSwig() {'
6147739Sgblack@eecs.umich.edu    for module in source:
615955SN/A        print >>f, '    init_%s();' % module.get_contents()
6163053Sstever@eecs.umich.edu    print >>f, '}'
6176121Snate@binkert.org    f.close()
6183053Sstever@eecs.umich.edu
6193053Sstever@eecs.umich.eduenv.Command('python/swig/init.cc', swig_modules, makeSwigInit)
6203053Sstever@eecs.umich.eduSource('python/swig/init.cc')
6213053Sstever@eecs.umich.edu
6223053Sstever@eecs.umich.edu# Generate traceflags.py
6239072Sandreas.hansson@arm.comdef traceFlagsPy(target, source, env):
6243053Sstever@eecs.umich.edu    assert(len(target) == 1)
6254742Sstever@eecs.umich.edu
6264742Sstever@eecs.umich.edu    f = file(str(target[0]), 'w')
6273053Sstever@eecs.umich.edu
6283053Sstever@eecs.umich.edu    allFlags = []
6293053Sstever@eecs.umich.edu    for s in source:
6308960Ssteve.reinhardt@amd.com        val = eval(s.get_contents())
6316654Snate@binkert.org        allFlags.append(val)
6323053Sstever@eecs.umich.edu
6333053Sstever@eecs.umich.edu    allFlags.sort()
6343053Sstever@eecs.umich.edu
6353053Sstever@eecs.umich.edu    print >>f, 'basic = ['
6362667Sstever@eecs.umich.edu    for flag, compound, desc in allFlags:
6374554Sbinkertn@umich.edu        if not compound:
6386121Snate@binkert.org            print >>f, "    '%s'," % flag
6392667Sstever@eecs.umich.edu    print >>f, "    ]"
6404554Sbinkertn@umich.edu    print >>f
6414554Sbinkertn@umich.edu
6424554Sbinkertn@umich.edu    print >>f, 'compound = ['
6436121Snate@binkert.org    print >>f, "    'All',"
6444554Sbinkertn@umich.edu    for flag, compound, desc in allFlags:
6454554Sbinkertn@umich.edu        if compound:
6464554Sbinkertn@umich.edu            print >>f, "    '%s'," % flag
6474781Snate@binkert.org    print >>f, "    ]"
6484554Sbinkertn@umich.edu    print >>f
6494554Sbinkertn@umich.edu
6502667Sstever@eecs.umich.edu    print >>f, "all = frozenset(basic + compound)"
6514554Sbinkertn@umich.edu    print >>f
6524554Sbinkertn@umich.edu
6534554Sbinkertn@umich.edu    print >>f, 'compoundMap = {'
6544554Sbinkertn@umich.edu    all = tuple([flag for flag,compound,desc in allFlags if not compound])
6552667Sstever@eecs.umich.edu    print >>f, "    'All' : %s," % (all, )
6564554Sbinkertn@umich.edu    for flag, compound, desc in allFlags:
6572667Sstever@eecs.umich.edu        if compound:
6584554Sbinkertn@umich.edu            print >>f, "    '%s' : %s," % (flag, compound)
6596121Snate@binkert.org    print >>f, "    }"
6602667Sstever@eecs.umich.edu    print >>f
6615522Snate@binkert.org
6625522Snate@binkert.org    print >>f, 'descriptions = {'
6635522Snate@binkert.org    print >>f, "    'All' : 'All flags',"
6645522Snate@binkert.org    for flag, compound, desc in allFlags:
6655522Snate@binkert.org        print >>f, "    '%s' : '%s'," % (flag, desc)
6665522Snate@binkert.org    print >>f, "    }"
6675522Snate@binkert.org
6685522Snate@binkert.org    f.close()
6695522Snate@binkert.org
6705522Snate@binkert.orgdef traceFlagsCC(target, source, env):
6715522Snate@binkert.org    assert(len(target) == 1)
6725522Snate@binkert.org
6735522Snate@binkert.org    f = file(str(target[0]), 'w')
6745522Snate@binkert.org
6755522Snate@binkert.org    allFlags = []
6765522Snate@binkert.org    for s in source:
6775522Snate@binkert.org        val = eval(s.get_contents())
6785522Snate@binkert.org        allFlags.append(val)
6795522Snate@binkert.org
6805522Snate@binkert.org    # file header
6815522Snate@binkert.org    print >>f, '''
6825522Snate@binkert.org/*
6835522Snate@binkert.org * DO NOT EDIT THIS FILE! Automatically generated
6845522Snate@binkert.org */
6855522Snate@binkert.org
6865522Snate@binkert.org#include "base/traceflags.hh"
6879255SAndreas.Sandberg@arm.com
6889255SAndreas.Sandberg@arm.comusing namespace Trace;
6899255SAndreas.Sandberg@arm.com
6909255SAndreas.Sandberg@arm.comconst char *Trace::flagStrings[] =
6919255SAndreas.Sandberg@arm.com{'''
6929255SAndreas.Sandberg@arm.com
6939255SAndreas.Sandberg@arm.com    # The string array is used by SimpleEnumParam to map the strings
6949255SAndreas.Sandberg@arm.com    # provided by the user to enum values.
6959255SAndreas.Sandberg@arm.com    for flag, compound, desc in allFlags:
6969255SAndreas.Sandberg@arm.com        if not compound:
6979255SAndreas.Sandberg@arm.com            print >>f, '    "%s",' % flag
6989255SAndreas.Sandberg@arm.com
6992638Sstever@eecs.umich.edu    print >>f, '    "All",'
7002638Sstever@eecs.umich.edu    for flag, compound, desc in allFlags:
7016121Snate@binkert.org        if compound:
7023716Sstever@eecs.umich.edu            print >>f, '    "%s",' % flag
7035522Snate@binkert.org
7049255SAndreas.Sandberg@arm.com    print >>f, '};'
7059255SAndreas.Sandberg@arm.com    print >>f
7069255SAndreas.Sandberg@arm.com    print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1)
7075522Snate@binkert.org    print >>f
7085522Snate@binkert.org
7095522Snate@binkert.org    #
7105522Snate@binkert.org    # Now define the individual compound flag arrays.  There is an array
7111858SN/A    # for each compound flag listing the component base flags.
7129255SAndreas.Sandberg@arm.com    #
7139255SAndreas.Sandberg@arm.com    all = tuple([flag for flag,compound,desc in allFlags if not compound])
7149255SAndreas.Sandberg@arm.com    print >>f, 'static const Flags AllMap[] = {'
7155227Ssaidi@eecs.umich.edu    for flag, compound, desc in allFlags:
7165227Ssaidi@eecs.umich.edu        if not compound:
7175227Ssaidi@eecs.umich.edu            print >>f, "    %s," % flag
7185227Ssaidi@eecs.umich.edu    print >>f, '};'
7196654Snate@binkert.org    print >>f
7206654Snate@binkert.org
7217769SAli.Saidi@ARM.com    for flag, compound, desc in allFlags:
7227769SAli.Saidi@ARM.com        if not compound:
7237769SAli.Saidi@ARM.com            continue
7247769SAli.Saidi@ARM.com        print >>f, 'static const Flags %sMap[] = {' % flag
7255227Ssaidi@eecs.umich.edu        for flag in compound:
7265227Ssaidi@eecs.umich.edu            print >>f, "    %s," % flag
7275227Ssaidi@eecs.umich.edu        print >>f, "    (Flags)-1"
7285204Sstever@gmail.com        print >>f, '};'
7295204Sstever@gmail.com        print >>f
7305204Sstever@gmail.com
7315204Sstever@gmail.com    #
7325204Sstever@gmail.com    # Finally the compoundFlags[] array maps the compound flags
7335204Sstever@gmail.com    # to their individual arrays/
7345204Sstever@gmail.com    #
7355204Sstever@gmail.com    print >>f, 'const Flags *Trace::compoundFlags[] ='
7365204Sstever@gmail.com    print >>f, '{'
7375204Sstever@gmail.com    print >>f, '    AllMap,'
7385204Sstever@gmail.com    for flag, compound, desc in allFlags:
7395204Sstever@gmail.com        if compound:
7405204Sstever@gmail.com            print >>f, '    %sMap,' % flag
7415204Sstever@gmail.com    # file trailer
7425204Sstever@gmail.com    print >>f, '};'
7435204Sstever@gmail.com
7445204Sstever@gmail.com    f.close()
7456121Snate@binkert.org
7465204Sstever@gmail.comdef traceFlagsHH(target, source, env):
7473118Sstever@eecs.umich.edu    assert(len(target) == 1)
7483118Sstever@eecs.umich.edu
7493118Sstever@eecs.umich.edu    f = file(str(target[0]), 'w')
7503118Sstever@eecs.umich.edu
7513118Sstever@eecs.umich.edu    allFlags = []
7525863Snate@binkert.org    for s in source:
7533118Sstever@eecs.umich.edu        val = eval(s.get_contents())
7545863Snate@binkert.org        allFlags.append(val)
7553118Sstever@eecs.umich.edu
7567457Snate@binkert.org    # file header boilerplate
7577457Snate@binkert.org    print >>f, '''
7585863Snate@binkert.org/*
7595863Snate@binkert.org * DO NOT EDIT THIS FILE!
7605863Snate@binkert.org *
7615863Snate@binkert.org * Automatically generated from traceflags.py
7625863Snate@binkert.org */
7635863Snate@binkert.org
7645863Snate@binkert.org#ifndef __BASE_TRACE_FLAGS_HH__
7656003Snate@binkert.org#define __BASE_TRACE_FLAGS_HH__
7665863Snate@binkert.org
7675863Snate@binkert.orgnamespace Trace {
7685863Snate@binkert.org
7696120Snate@binkert.orgenum Flags {'''
7705863Snate@binkert.org
7715863Snate@binkert.org    # Generate the enum.  Base flags come first, then compound flags.
7725863Snate@binkert.org    idx = 0
7738655Sandreas.hansson@arm.com    for flag, compound, desc in allFlags:
7748655Sandreas.hansson@arm.com        if not compound:
7758655Sandreas.hansson@arm.com            print >>f, '    %s = %d,' % (flag, idx)
7768655Sandreas.hansson@arm.com            idx += 1
7778655Sandreas.hansson@arm.com
7788655Sandreas.hansson@arm.com    numBaseFlags = idx
7798655Sandreas.hansson@arm.com    print >>f, '    NumFlags = %d,' % idx
7808655Sandreas.hansson@arm.com
7816120Snate@binkert.org    # put a comment in here to separate base from compound flags
7825863Snate@binkert.org    print >>f, '''
7836121Snate@binkert.org// The remaining enum values are *not* valid indices for Trace::flags.
7846121Snate@binkert.org// They are "compound" flags, which correspond to sets of base
7855863Snate@binkert.org// flags, and are used by changeFlag.'''
7867727SAli.Saidi@ARM.com
7877727SAli.Saidi@ARM.com    print >>f, '    All = %d,' % idx
7887727SAli.Saidi@ARM.com    idx += 1
7897727SAli.Saidi@ARM.com    for flag, compound, desc in allFlags:
7907727SAli.Saidi@ARM.com        if compound:
7917727SAli.Saidi@ARM.com            print >>f, '    %s = %d,' % (flag, idx)
7925863Snate@binkert.org            idx += 1
7933118Sstever@eecs.umich.edu
7945863Snate@binkert.org    numCompoundFlags = idx - numBaseFlags
7959239Sandreas.hansson@arm.com    print >>f, '    NumCompoundFlags = %d' % numCompoundFlags
7963118Sstever@eecs.umich.edu
7973118Sstever@eecs.umich.edu    # trailer boilerplate
7985863Snate@binkert.org    print >>f, '''\
7995863Snate@binkert.org}; // enum Flags
8005863Snate@binkert.org
8015863Snate@binkert.org// Array of strings for SimpleEnumParam
8023118Sstever@eecs.umich.eduextern const char *flagStrings[];
8033483Ssaidi@eecs.umich.eduextern const int numFlagStrings;
8043494Ssaidi@eecs.umich.edu
8053494Ssaidi@eecs.umich.edu// Array of arraay pointers: for each compound flag, gives the list of
8063483Ssaidi@eecs.umich.edu// base flags to set.  Inidividual flag arrays are terminated by -1.
8073483Ssaidi@eecs.umich.eduextern const Flags *compoundFlags[];
8083483Ssaidi@eecs.umich.edu
8093053Sstever@eecs.umich.edu/* namespace Trace */ }
8103053Sstever@eecs.umich.edu
8113918Ssaidi@eecs.umich.edu#endif // __BASE_TRACE_FLAGS_HH__
8123053Sstever@eecs.umich.edu'''
8133053Sstever@eecs.umich.edu
8143053Sstever@eecs.umich.edu    f.close()
8153053Sstever@eecs.umich.edu
8163053Sstever@eecs.umich.eduflags = [ Value(f) for f in trace_flags.values() ]
8177840Snate@binkert.orgenv.Command('base/traceflags.py', flags, traceFlagsPy)
8187865Sgblack@eecs.umich.eduPySource('m5', 'base/traceflags.py')
8197865Sgblack@eecs.umich.edu
8207865Sgblack@eecs.umich.eduenv.Command('base/traceflags.hh', flags, traceFlagsHH)
8217865Sgblack@eecs.umich.eduenv.Command('base/traceflags.cc', flags, traceFlagsCC)
8227865Sgblack@eecs.umich.eduSource('base/traceflags.cc')
8237840Snate@binkert.org
8249045SAli.Saidi@ARM.com# embed python files.  All .py files that have been indicated by a
8259045SAli.Saidi@ARM.com# PySource() call in a SConscript need to be embedded into the M5
8269045SAli.Saidi@ARM.com# library.  To do that, we compile the file to byte code, marshal the
8279045SAli.Saidi@ARM.com# byte code, compress it, and then generate an assembly file that
8289045SAli.Saidi@ARM.com# inserts the result into the data section with symbols indicating the
8299045SAli.Saidi@ARM.com# beginning, and end (and with the size at the end)
8309071Sandreas.hansson@arm.compy_sources_tnodes = {}
8319071Sandreas.hansson@arm.comfor pysource in py_sources:
8329045SAli.Saidi@ARM.com    py_sources_tnodes[pysource.tnode] = pysource
8337840Snate@binkert.org
8347840Snate@binkert.orgdef objectifyPyFile(target, source, env):
8357840Snate@binkert.org    '''Action function to compile a .py into a code object, marshal
8361858SN/A    it, compress it, and stick it into an asm file so the code appears
8371858SN/A    as just bytes with a label in the data section'''
8381858SN/A
8391858SN/A    src = file(str(source[0]), 'r').read()
8401858SN/A    dst = file(str(target[0]), 'w')
8411858SN/A
8425863Snate@binkert.org    pysource = py_sources_tnodes[source[0]]
8435863Snate@binkert.org    compiled = compile(src, pysource.debugname, 'exec')
8445863Snate@binkert.org    marshalled = marshal.dumps(compiled)
8455863Snate@binkert.org    compressed = zlib.compress(marshalled)
8466121Snate@binkert.org    data = compressed
8471858SN/A
8485863Snate@binkert.org    # Some C/C++ compilers prepend an underscore to global symbol
8495863Snate@binkert.org    # names, so if they're going to do that, we need to prepend that
8505863Snate@binkert.org    # leading underscore to globals in the assembly file.
8515863Snate@binkert.org    if env['LEADING_UNDERSCORE']:
8525863Snate@binkert.org        sym = '_' + pysource.symname
8532139SN/A    else:
8544202Sbinkertn@umich.edu        sym = pysource.symname
8554202Sbinkertn@umich.edu
8562139SN/A    step = 16
8576994Snate@binkert.org    print >>dst, ".data"
8586994Snate@binkert.org    print >>dst, ".globl %s_beg" % sym
8596994Snate@binkert.org    print >>dst, ".globl %s_end" % sym
8606994Snate@binkert.org    print >>dst, "%s_beg:" % sym
8616994Snate@binkert.org    for i in xrange(0, len(data), step):
8626994Snate@binkert.org        x = array.array('B', data[i:i+step])
8636994Snate@binkert.org        print >>dst, ".byte", ','.join([str(d) for d in x])
8646994Snate@binkert.org    print >>dst, "%s_end:" % sym
8656994Snate@binkert.org    print >>dst, ".long %d" % len(marshalled)
8666994Snate@binkert.org
8676994Snate@binkert.orgfor source in py_sources:
8686994Snate@binkert.org    env.Command(source.assembly, source.tnode, objectifyPyFile)
8696994Snate@binkert.org    Source(source.assembly)
8706994Snate@binkert.org
8716994Snate@binkert.org# Generate init_python.cc which creates a bunch of EmbeddedPyModule
8726994Snate@binkert.org# structs that describe the embedded python code.  One such struct
8736994Snate@binkert.org# contains information about the importer that python uses to get at
8746994Snate@binkert.org# the embedded files, and then there's a list of all of the rest that
8756994Snate@binkert.org# the importer uses to load the rest on demand.
8766994Snate@binkert.orgpy_sources_symbols = {}
8776994Snate@binkert.orgfor pysource in py_sources:
8786994Snate@binkert.org    py_sources_symbols[pysource.symname] = pysource
8796994Snate@binkert.orgdef pythonInit(target, source, env):
8806994Snate@binkert.org    dst = file(str(target[0]), 'w')
8816994Snate@binkert.org
8826994Snate@binkert.org    def dump_mod(sym, endchar=','):
8836994Snate@binkert.org        pysource = py_sources_symbols[sym]
8846994Snate@binkert.org        print >>dst, '    { "%s",' % pysource.arcname
8852155SN/A        print >>dst, '      "%s",' % pysource.modpath
8865863Snate@binkert.org        print >>dst, '       %s_beg, %s_end,' % (sym, sym)
8871869SN/A        print >>dst, '       %s_end - %s_beg,' % (sym, sym)
8881869SN/A        print >>dst, '       *(int *)%s_end }%s'  % (sym, endchar)
8895863Snate@binkert.org    
8905863Snate@binkert.org    print >>dst, '#include "sim/init.hh"'
8914202Sbinkertn@umich.edu
8926108Snate@binkert.org    for sym in source:
8936108Snate@binkert.org        sym = sym.get_contents()
8946108Snate@binkert.org        print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym)
8956108Snate@binkert.org
8969219Spower.jg@gmail.com    print >>dst, "const EmbeddedPyModule embeddedPyImporter = "
8979219Spower.jg@gmail.com    dump_mod("PyEMB_importer", endchar=';');
8989219Spower.jg@gmail.com    print >>dst
8999219Spower.jg@gmail.com
9009219Spower.jg@gmail.com    print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {"
9019219Spower.jg@gmail.com    for i,sym in enumerate(source):
9029219Spower.jg@gmail.com        sym = sym.get_contents()
9039219Spower.jg@gmail.com        if sym == "PyEMB_importer":
9044202Sbinkertn@umich.edu            # Skip the importer since we've already exported it
9055863Snate@binkert.org            continue
9068474Sgblack@eecs.umich.edu        dump_mod(sym)
9078474Sgblack@eecs.umich.edu    print >>dst, "    { 0, 0, 0, 0, 0, 0 }"
9085742Snate@binkert.org    print >>dst, "};"
9098268Ssteve.reinhardt@amd.com
9108268Ssteve.reinhardt@amd.comsymbols = [Value(s.symname) for s in py_sources]
9118268Ssteve.reinhardt@amd.comenv.Command('sim/init_python.cc', symbols, pythonInit)
9125742Snate@binkert.orgSource('sim/init_python.cc')
9135341Sstever@gmail.com
9148474Sgblack@eecs.umich.edu########################################################################
9158474Sgblack@eecs.umich.edu#
9165342Sstever@gmail.com# Define binaries.  Each different build type (debug, opt, etc.) gets
9174202Sbinkertn@umich.edu# a slightly different build environment.
9184202Sbinkertn@umich.edu#
9194202Sbinkertn@umich.edu
9205863Snate@binkert.org# List of constructed environments to pass back to SConstruct
9215863Snate@binkert.orgenvList = []
9226994Snate@binkert.org
9236994Snate@binkert.org# This function adds the specified sources to the given build
9246994Snate@binkert.org# environment, and returns a list of all the corresponding SCons
9255863Snate@binkert.org# Object nodes (including an extra one for date.cc).  We explicitly
9265863Snate@binkert.org# add the Object nodes so we can set up special dependencies for
9275863Snate@binkert.org# date.cc.
9285863Snate@binkert.orgdef make_objs(sources, env, static):
9295863Snate@binkert.org    if static:
9305863Snate@binkert.org        XObject = env.StaticObject
9315863Snate@binkert.org    else:
9325863Snate@binkert.org        XObject = env.SharedObject
9337840Snate@binkert.org
9345863Snate@binkert.org    objs = [ XObject(s) for s in sources ]
9355952Ssaidi@eecs.umich.edu  
9369219Spower.jg@gmail.com    # make date.cc depend on all other objects so it always gets
9379219Spower.jg@gmail.com    # recompiled whenever anything else does
9381869SN/A    date_obj = XObject('base/date.cc')
9391858SN/A
9405863Snate@binkert.org    env.Depends(date_obj, objs)
9419044SAli.Saidi@ARM.com    objs.append(date_obj)
9429219Spower.jg@gmail.com    return objs
9439255SAndreas.Sandberg@arm.com
9441858SN/A# Function to create a new build environment as clone of current
945955SN/A# environment 'env' with modified object suffix and optional stripped
946955SN/A# binary.  Additional keyword arguments are appended to corresponding
9471869SN/A# build environment vars.
9481869SN/Adef makeEnv(label, objsfx, strip = False, **kwargs):
9491869SN/A    # SCons doesn't know to append a library suffix when there is a '.' in the
9501869SN/A    # name.  Use '_' instead.
9511869SN/A    libname = 'm5_' + label
9525863Snate@binkert.org    exename = 'm5.' + label
9535863Snate@binkert.org
9545863Snate@binkert.org    new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's')
9551869SN/A    new_env.Label = label
9565863Snate@binkert.org    new_env.Append(**kwargs)
9571869SN/A
9585863Snate@binkert.org    swig_env = new_env.Clone()
9591869SN/A    if env['GCC']:
9601869SN/A        swig_env.Append(CCFLAGS='-Wno-uninitialized')
9611869SN/A        swig_env.Append(CCFLAGS='-Wno-sign-compare')
9621869SN/A        swig_env.Append(CCFLAGS='-Wno-parentheses')
9638483Sgblack@eecs.umich.edu
9641869SN/A    static_objs = make_objs(cc_lib_sources, new_env, static=True)
9651869SN/A    shared_objs = make_objs(cc_lib_sources, new_env, static=False)
9661869SN/A    static_objs += [ swig_env.StaticObject(s) for s in cc_swig_sources ]
9671869SN/A    shared_objs += [ swig_env.SharedObject(s) for s in cc_swig_sources ]
9685863Snate@binkert.org
9695863Snate@binkert.org    # First make a library of everything but main() so other programs can
9701869SN/A    # link against m5.
9715863Snate@binkert.org    static_lib = new_env.StaticLibrary(libname, static_objs)
9725863Snate@binkert.org    shared_lib = new_env.SharedLibrary(libname, shared_objs)
9733356Sbinkertn@umich.edu
9743356Sbinkertn@umich.edu    for target, sources in unit_tests:
9753356Sbinkertn@umich.edu        objs = [ new_env.StaticObject(s) for s in sources ]
9763356Sbinkertn@umich.edu        new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs)
9773356Sbinkertn@umich.edu
9784781Snate@binkert.org    # Now link a stub with main() and the static library.
9795863Snate@binkert.org    objects = [new_env.Object(s) for s in cc_bin_sources] + static_objs
9805863Snate@binkert.org    if strip:
9811869SN/A        unstripped_exe = exename + '.unstripped'
9821869SN/A        new_env.Program(unstripped_exe, objects)
9831869SN/A        if sys.platform == 'sunos5':
9846121Snate@binkert.org            cmd = 'cp $SOURCE $TARGET; strip $TARGET'
9851869SN/A        else:
9862638Sstever@eecs.umich.edu            cmd = 'strip $SOURCE -o $TARGET'
9876121Snate@binkert.org        targets = new_env.Command(exename, unstripped_exe, cmd)
9886121Snate@binkert.org    else:
9892638Sstever@eecs.umich.edu        targets = new_env.Program(exename, objects)
9905749Scws3k@cs.virginia.edu            
9916121Snate@binkert.org    new_env.M5Binary = targets[0]
9926121Snate@binkert.org    envList.append(new_env)
9935749Scws3k@cs.virginia.edu
9941869SN/A# Debug binary
9951869SN/Accflags = {}
9963546Sgblack@eecs.umich.eduif env['GCC']:
9973546Sgblack@eecs.umich.edu    if sys.platform == 'sunos5':
9983546Sgblack@eecs.umich.edu        ccflags['debug'] = '-gstabs+'
9993546Sgblack@eecs.umich.edu    else:
10006121Snate@binkert.org        ccflags['debug'] = '-ggdb3'
10015863Snate@binkert.org    ccflags['opt'] = '-g -O3'
10023546Sgblack@eecs.umich.edu    ccflags['fast'] = '-O3'
10033546Sgblack@eecs.umich.edu    ccflags['prof'] = '-O3 -g -pg'
10043546Sgblack@eecs.umich.eduelif env['SUNCC']:
10053546Sgblack@eecs.umich.edu    ccflags['debug'] = '-g0'
10064781Snate@binkert.org    ccflags['opt'] = '-g -O'
10074781Snate@binkert.org    ccflags['fast'] = '-fast'
10086658Snate@binkert.org    ccflags['prof'] = '-fast -g -pg'
10096658Snate@binkert.orgelif env['ICC']:
10104781Snate@binkert.org    ccflags['debug'] = '-g -O0'
10113546Sgblack@eecs.umich.edu    ccflags['opt'] = '-g -O'
10123546Sgblack@eecs.umich.edu    ccflags['fast'] = '-fast'
10133546Sgblack@eecs.umich.edu    ccflags['prof'] = '-fast -g -pg'
10143546Sgblack@eecs.umich.eduelse:
10157756SAli.Saidi@ARM.com    print 'Unknown compiler, please fix compiler options'
10167816Ssteve.reinhardt@amd.com    Exit(1)
10173546Sgblack@eecs.umich.edu
10183546Sgblack@eecs.umich.edumakeEnv('debug', '.do',
10193546Sgblack@eecs.umich.edu        CCFLAGS = Split(ccflags['debug']),
10203546Sgblack@eecs.umich.edu        CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])
10214202Sbinkertn@umich.edu
10223546Sgblack@eecs.umich.edu# Optimized binary
10233546Sgblack@eecs.umich.edumakeEnv('opt', '.o',
10243546Sgblack@eecs.umich.edu        CCFLAGS = Split(ccflags['opt']),
1025955SN/A        CPPDEFINES = ['TRACING_ON=1'])
1026955SN/A
1027955SN/A# "Fast" binary
1028955SN/AmakeEnv('fast', '.fo', strip = True,
10295863Snate@binkert.org        CCFLAGS = Split(ccflags['fast']),
10305863Snate@binkert.org        CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])
10315343Sstever@gmail.com
10325343Sstever@gmail.com# Profiled binary
10336121Snate@binkert.orgmakeEnv('prof', '.po',
10345863Snate@binkert.org        CCFLAGS = Split(ccflags['prof']),
10354773Snate@binkert.org        CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
10365863Snate@binkert.org        LINKFLAGS = '-pg')
10372632Sstever@eecs.umich.edu
10385863Snate@binkert.orgReturn('envList')
10392023SN/A