SConscript revision 10802
16167SN/A# -*- mode:python -*- 26167SN/A 36167SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 410036SAli.Saidi@ARM.com# All rights reserved. 58835SAli.Saidi@ARM.com# 610036SAli.Saidi@ARM.com# Redistribution and use in source and binary forms, with or without 77892SN/A# modification, are permitted provided that the following conditions are 87892SN/A# met: redistributions of source code must retain the above copyright 97892SN/A# notice, this list of conditions and the following disclaimer; 106167SN/A# redistributions in binary form must reproduce the above copyright 116167SN/A# notice, this list of conditions and the following disclaimer in the 126167SN/A# documentation and/or other materials provided with the distribution; 1310526Snilay@cs.wisc.edu# neither the name of the copyright holders nor the names of its 148835SAli.Saidi@ARM.com# contributors may be used to endorse or promote products derived from 159864Snilay@cs.wisc.edu# this software without specific prior written permission. 169864Snilay@cs.wisc.edu# 1710036SAli.Saidi@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 188835SAli.Saidi@ARM.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 198835SAli.Saidi@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2010315Snilay@cs.wisc.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 218835SAli.Saidi@ARM.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2210063Snilay@cs.wisc.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 237077SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 249864Snilay@cs.wisc.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2510526Snilay@cs.wisc.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2610736Snilay@cs.wisc.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2711219Snilay@cs.wisc.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288721SN/A# 298835SAli.Saidi@ARM.com# Authors: Nathan Binkert 308835SAli.Saidi@ARM.com 317935SN/Aimport array 327935SN/Aimport bisect 337935SN/Aimport imp 347935SN/Aimport marshal 357935SN/Aimport os 367935SN/Aimport re 377935SN/Aimport sys 388983Snate@binkert.orgimport zlib 396167SN/A 409864Snilay@cs.wisc.edufrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 419864Snilay@cs.wisc.edu 429864Snilay@cs.wisc.eduimport SCons 4310315Snilay@cs.wisc.edu 4410036SAli.Saidi@ARM.com# This file defines how to build a particular configuration of gem5 4510315Snilay@cs.wisc.edu# based on variable settings in the 'env' build environment. 469864Snilay@cs.wisc.edu 479864Snilay@cs.wisc.eduImport('*') 486167SN/A 496167SN/A# Children need to see the environment 509864Snilay@cs.wisc.eduExport('env') 5110063Snilay@cs.wisc.edu 526167SN/Abuild_env = [(opt, env[opt]) for opt in export_vars] 539864Snilay@cs.wisc.edu 546167SN/Afrom m5.util import code_formatter, compareVersions 556167SN/A 568835SAli.Saidi@ARM.com######################################################################## 576167SN/A# Code for adding source files of various types 586167SN/A# 5910036SAli.Saidi@ARM.com# When specifying a source file of some type, a set of guards can be 606167SN/A# specified for that file. When get() is used to find the files, if 616167SN/A# get specifies a set of filters, only files that match those filters 628835SAli.Saidi@ARM.com# will be accepted (unspecified filters on files are assumed to be 639469Snilay@cs.wisc.edu# false). Current filters are: 646167SN/A# main -- specifies the gem5 main() function 656167SN/A# skip_lib -- do not put this file into the gem5 library 666167SN/A# skip_no_python -- do not put this file into a no_python library 676167SN/A# as it embeds compiled Python 686167SN/A# <unittest> -- unit tests use filters based on the unit test name 696167SN/A# 708835SAli.Saidi@ARM.com# A parent can now be specified for a source file and default filter 716167SN/A# values will be retrieved recursively from parents (children override 729864Snilay@cs.wisc.edu# parents). 7310315Snilay@cs.wisc.edu# 749469Snilay@cs.wisc.educlass SourceMeta(type): 756167SN/A '''Meta class for source files that keeps track of all files of a 766167SN/A particular type and has a get function for finding all functions 776167SN/A of a certain type that match a set of guards''' 789469Snilay@cs.wisc.edu def __init__(cls, name, bases, dict): 799469Snilay@cs.wisc.edu super(SourceMeta, cls).__init__(name, bases, dict) 806167SN/A cls.all = [] 819864Snilay@cs.wisc.edu 829864Snilay@cs.wisc.edu def get(cls, **guards): 839864Snilay@cs.wisc.edu '''Find all files that match the specified guards. If a source 849864Snilay@cs.wisc.edu file does not specify a flag, the default is False''' 8510036SAli.Saidi@ARM.com for src in cls.all: 869864Snilay@cs.wisc.edu for flag,value in guards.iteritems(): 879864Snilay@cs.wisc.edu # if the flag is found and has a different value, skip 889864Snilay@cs.wisc.edu # this file 899864Snilay@cs.wisc.edu if src.all_guards.get(flag, False) != value: 9010315Snilay@cs.wisc.edu break 9110036SAli.Saidi@ARM.com else: 9210315Snilay@cs.wisc.edu yield src 939864Snilay@cs.wisc.edu 949864Snilay@cs.wisc.educlass SourceFile(object): 956167SN/A '''Base object that encapsulates the notion of a source file. 966167SN/A This includes, the source node, target node, various manipulations 978835SAli.Saidi@ARM.com of those. A source file also specifies a set of guards which 9810036SAli.Saidi@ARM.com describing which builds the source file applies to. A parent can 996167SN/A also be specified to get default guards from''' 1008835SAli.Saidi@ARM.com __metaclass__ = SourceMeta 1018835SAli.Saidi@ARM.com def __init__(self, source, parent=None, **guards): 1028835SAli.Saidi@ARM.com self.guards = guards 1038835SAli.Saidi@ARM.com self.parent = parent 1049864Snilay@cs.wisc.edu 10510036SAli.Saidi@ARM.com tnode = source 1069864Snilay@cs.wisc.edu if not isinstance(source, SCons.Node.FS.File): 1078835SAli.Saidi@ARM.com tnode = File(source) 1089469Snilay@cs.wisc.edu 1098835SAli.Saidi@ARM.com self.tnode = tnode 1108835SAli.Saidi@ARM.com self.snode = tnode.srcnode() 1118835SAli.Saidi@ARM.com 1129864Snilay@cs.wisc.edu for base in type(self).__mro__: 11310036SAli.Saidi@ARM.com if issubclass(base, SourceFile): 1148835SAli.Saidi@ARM.com base.all.append(self) 1158835SAli.Saidi@ARM.com 1169213Snilay@cs.wisc.edu @property 1178835SAli.Saidi@ARM.com def filename(self): 1189469Snilay@cs.wisc.edu return str(self.tnode) 1199469Snilay@cs.wisc.edu 1209469Snilay@cs.wisc.edu @property 1219469Snilay@cs.wisc.edu def dirname(self): 1229469Snilay@cs.wisc.edu return dirname(self.filename) 1239469Snilay@cs.wisc.edu 12410036SAli.Saidi@ARM.com @property 1256167SN/A def basename(self): 1266167SN/A return basename(self.filename) 1276167SN/A 1288835SAli.Saidi@ARM.com @property 12910036SAli.Saidi@ARM.com def extname(self): 1306167SN/A index = self.basename.rfind('.') 1318835SAli.Saidi@ARM.com if index <= 0: 1328835SAli.Saidi@ARM.com # dot files aren't extensions 1338835SAli.Saidi@ARM.com return self.basename, None 1348835SAli.Saidi@ARM.com 1359864Snilay@cs.wisc.edu return self.basename[:index], self.basename[index+1:] 13610036SAli.Saidi@ARM.com 1379864Snilay@cs.wisc.edu @property 1388835SAli.Saidi@ARM.com def all_guards(self): 1399469Snilay@cs.wisc.edu '''find all guards for this object getting default values 1406167SN/A recursively from its parents''' 1416167SN/A guards = {} 1426167SN/A if self.parent: 14310036SAli.Saidi@ARM.com guards.update(self.parent.guards) 1446167SN/A guards.update(self.guards) 1456167SN/A return guards 1466167SN/A 1476167SN/A def __lt__(self, other): return self.filename < other.filename 1486167SN/A def __le__(self, other): return self.filename <= other.filename 14910645Snilay@cs.wisc.edu def __gt__(self, other): return self.filename > other.filename 1506167SN/A def __ge__(self, other): return self.filename >= other.filename 1516167SN/A def __eq__(self, other): return self.filename == other.filename 1526167SN/A def __ne__(self, other): return self.filename != other.filename 1536167SN/A 15410036SAli.Saidi@ARM.com @staticmethod 15511268Satgutier@umich.edu def done(): 1566167SN/A def disabled(cls, name, *ignored): 1576167SN/A raise RuntimeError("Additional SourceFile '%s'" % name,\ 15810645Snilay@cs.wisc.edu "declared, but targets deps are already fixed.") 1596167SN/A SourceFile.__init__ = disabled 1606167SN/A 1616167SN/A 1626167SN/Aclass Source(SourceFile): 1636167SN/A '''Add a c/c++ source file to the build''' 1646167SN/A def __init__(self, source, Werror=True, swig=False, **guards): 1656167SN/A '''specify the source file, and any guards''' 16610451Snilay@cs.wisc.edu super(Source, self).__init__(source, **guards) 1676167SN/A 16810315Snilay@cs.wisc.edu self.Werror = Werror 16910315Snilay@cs.wisc.edu self.swig = swig 17010315Snilay@cs.wisc.edu 17110315Snilay@cs.wisc.educlass PySource(SourceFile): 17210315Snilay@cs.wisc.edu '''Add a python source file to the named package''' 17310315Snilay@cs.wisc.edu invalid_sym_char = re.compile('[^A-z0-9_]') 17410315Snilay@cs.wisc.edu modules = {} 17510315Snilay@cs.wisc.edu tnodes = {} 17610526Snilay@cs.wisc.edu symnames = {} 17710526Snilay@cs.wisc.edu 17810526Snilay@cs.wisc.edu def __init__(self, package, source, **guards): 17910526Snilay@cs.wisc.edu '''specify the python package, the source file, and any guards''' 18010526Snilay@cs.wisc.edu super(PySource, self).__init__(source, **guards) 18110526Snilay@cs.wisc.edu 18210526Snilay@cs.wisc.edu modname,ext = self.extname 18310526Snilay@cs.wisc.edu assert ext == 'py' 18410526Snilay@cs.wisc.edu 18510526Snilay@cs.wisc.edu if package: 18610526Snilay@cs.wisc.edu path = package.split('.') 18710526Snilay@cs.wisc.edu else: 18810526Snilay@cs.wisc.edu path = [] 18910526Snilay@cs.wisc.edu 19010526Snilay@cs.wisc.edu modpath = path[:] 19110526Snilay@cs.wisc.edu if modname != '__init__': 19210526Snilay@cs.wisc.edu modpath += [ modname ] 19310526Snilay@cs.wisc.edu modpath = '.'.join(modpath) 19410526Snilay@cs.wisc.edu 19510526Snilay@cs.wisc.edu arcpath = path + [ self.basename ] 19610526Snilay@cs.wisc.edu abspath = self.snode.abspath 19710526Snilay@cs.wisc.edu if not exists(abspath): 19810526Snilay@cs.wisc.edu abspath = self.tnode.abspath 19910526Snilay@cs.wisc.edu 20010526Snilay@cs.wisc.edu self.package = package 20110526Snilay@cs.wisc.edu self.modname = modname 20210526Snilay@cs.wisc.edu self.modpath = modpath 20310736Snilay@cs.wisc.edu self.arcname = joinpath(*arcpath) 20410526Snilay@cs.wisc.edu self.abspath = abspath 20510526Snilay@cs.wisc.edu self.compiled = File(self.filename + 'c') 20610526Snilay@cs.wisc.edu self.cpp = File(self.filename + '.cc') 20710526Snilay@cs.wisc.edu self.symname = PySource.invalid_sym_char.sub('_', modpath) 2089864Snilay@cs.wisc.edu 2099864Snilay@cs.wisc.edu PySource.modules[modpath] = self 21010526Snilay@cs.wisc.edu PySource.tnodes[self.tnode] = self 21110526Snilay@cs.wisc.edu PySource.symnames[self.symname] = self 21210526Snilay@cs.wisc.edu 21310526Snilay@cs.wisc.educlass SimObject(PySource): 21410526Snilay@cs.wisc.edu '''Add a SimObject python file as a python source object and add 21510036SAli.Saidi@ARM.com it to a list of sim object modules''' 2169469Snilay@cs.wisc.edu 21710526Snilay@cs.wisc.edu fixed = False 21810526Snilay@cs.wisc.edu modnames = [] 21910526Snilay@cs.wisc.edu 22010526Snilay@cs.wisc.edu def __init__(self, source, **guards): 22110526Snilay@cs.wisc.edu '''Specify the source file and any guards (automatically in 22210526Snilay@cs.wisc.edu the m5.objects package)''' 22310526Snilay@cs.wisc.edu super(SimObject, self).__init__('m5.objects', source, **guards) 22410526Snilay@cs.wisc.edu if self.fixed: 22510526Snilay@cs.wisc.edu raise AttributeError, "Too late to call SimObject now." 22610526Snilay@cs.wisc.edu 22710526Snilay@cs.wisc.edu bisect.insort_right(SimObject.modnames, self.modname) 22810526Snilay@cs.wisc.edu 22910526Snilay@cs.wisc.educlass SwigSource(SourceFile): 23010526Snilay@cs.wisc.edu '''Add a swig file to build''' 23110526Snilay@cs.wisc.edu 23210526Snilay@cs.wisc.edu def __init__(self, package, source, **guards): 23310526Snilay@cs.wisc.edu '''Specify the python package, the source file, and any guards''' 23410526Snilay@cs.wisc.edu super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 23510526Snilay@cs.wisc.edu 23610526Snilay@cs.wisc.edu modname,ext = self.extname 23710526Snilay@cs.wisc.edu assert ext == 'i' 23810526Snilay@cs.wisc.edu 23910526Snilay@cs.wisc.edu self.module = modname 24010526Snilay@cs.wisc.edu cc_file = joinpath(self.dirname, modname + '_wrap.cc') 24110526Snilay@cs.wisc.edu py_file = joinpath(self.dirname, modname + '.py') 24210526Snilay@cs.wisc.edu 24310526Snilay@cs.wisc.edu self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 24410526Snilay@cs.wisc.edu self.py_source = PySource(package, py_file, parent=self, **guards) 24510526Snilay@cs.wisc.edu 24610526Snilay@cs.wisc.educlass ProtoBuf(SourceFile): 24710526Snilay@cs.wisc.edu '''Add a Protocol Buffer to build''' 24810526Snilay@cs.wisc.edu 24910526Snilay@cs.wisc.edu def __init__(self, source, **guards): 25010526Snilay@cs.wisc.edu '''Specify the source file, and any guards''' 25110526Snilay@cs.wisc.edu super(ProtoBuf, self).__init__(source, **guards) 2529469Snilay@cs.wisc.edu 2539469Snilay@cs.wisc.edu # Get the file name and the extension 2549469Snilay@cs.wisc.edu modname,ext = self.extname 25510036SAli.Saidi@ARM.com assert ext == 'proto' 25610736Snilay@cs.wisc.edu 25710036SAli.Saidi@ARM.com # Currently, we stick to generating the C++ headers, so we 2589469Snilay@cs.wisc.edu # only need to track the source and header. 2599864Snilay@cs.wisc.edu self.cc_file = File(modname + '.pb.cc') 26010036SAli.Saidi@ARM.com self.hh_file = File(modname + '.pb.h') 26110036SAli.Saidi@ARM.com 26210526Snilay@cs.wisc.educlass UnitTest(object): 26310036SAli.Saidi@ARM.com '''Create a UnitTest''' 26411219Snilay@cs.wisc.edu 26510526Snilay@cs.wisc.edu all = [] 2669469Snilay@cs.wisc.edu def __init__(self, target, *sources, **kwargs): 2679469Snilay@cs.wisc.edu '''Specify the target name and any sources. Sources that are 2689864Snilay@cs.wisc.edu not SourceFiles are evalued with Source(). All files are 2699864Snilay@cs.wisc.edu guarded with a guard of the same name as the UnitTest 2709864Snilay@cs.wisc.edu target.''' 27110315Snilay@cs.wisc.edu 27210036SAli.Saidi@ARM.com srcs = [] 27310315Snilay@cs.wisc.edu for src in sources: 2749864Snilay@cs.wisc.edu if not isinstance(src, SourceFile): 2759864Snilay@cs.wisc.edu src = Source(src, skip_lib=True) 2769469Snilay@cs.wisc.edu src.guards[target] = True 2776928SN/A srcs.append(src) 27811023Sjthestness@gmail.com 2796928SN/A self.sources = srcs 2809864Snilay@cs.wisc.edu self.target = target 28110036SAli.Saidi@ARM.com self.main = kwargs.get('main', False) 2829469Snilay@cs.wisc.edu UnitTest.all.append(self) 2836928SN/A 28411023Sjthestness@gmail.com# Children should have access 28511023Sjthestness@gmail.comExport('Source') 28610036SAli.Saidi@ARM.comExport('PySource') 28711023Sjthestness@gmail.comExport('SimObject') 2886928SN/AExport('SwigSource') 2896928SN/AExport('ProtoBuf') 29011023Sjthestness@gmail.comExport('UnitTest') 29111023Sjthestness@gmail.com 29211023Sjthestness@gmail.com######################################################################## 2938673SN/A# 29410526Snilay@cs.wisc.edu# Debug Flags 29510526Snilay@cs.wisc.edu# 2969864Snilay@cs.wisc.edudebug_flags = {} 2976928SN/Adef DebugFlag(name, desc=None): 29810526Snilay@cs.wisc.edu if name in debug_flags: 2996928SN/A raise AttributeError, "Flag %s already specified" % name 3009469Snilay@cs.wisc.edu debug_flags[name] = (name, (), desc) 3016928SN/A 30210036SAli.Saidi@ARM.comdef CompoundFlag(name, flags, desc=None): 3039373Snilay@cs.wisc.edu if name in debug_flags: 3049864Snilay@cs.wisc.edu raise AttributeError, "Flag %s already specified" % name 3056928SN/A 3066928SN/A compound = tuple(flags) 30711023Sjthestness@gmail.com debug_flags[name] = (name, compound, desc) 30811023Sjthestness@gmail.com 30911023Sjthestness@gmail.comExport('DebugFlag') 31011023Sjthestness@gmail.comExport('CompoundFlag') 31111023Sjthestness@gmail.com 31211023Sjthestness@gmail.com######################################################################## 31311023Sjthestness@gmail.com# 31411023Sjthestness@gmail.com# Set some compiler variables 31511023Sjthestness@gmail.com# 31611023Sjthestness@gmail.com 31711023Sjthestness@gmail.com# Include file paths are rooted in this directory. SCons will 31811023Sjthestness@gmail.com# automatically expand '.' to refer to both the source directory and 31911023Sjthestness@gmail.com# the corresponding build directory to pick up generated include 32011023Sjthestness@gmail.com# files. 32111023Sjthestness@gmail.comenv.Append(CPPPATH=Dir('.')) 32211023Sjthestness@gmail.com 32311023Sjthestness@gmail.comfor extra_dir in extras_dir_list: 32411023Sjthestness@gmail.com env.Append(CPPPATH=Dir(extra_dir)) 32511023Sjthestness@gmail.com 32611023Sjthestness@gmail.com# Workaround for bug in SCons version > 0.97d20071212 32711023Sjthestness@gmail.com# Scons bug id: 2006 gem5 Bug id: 308 32811023Sjthestness@gmail.comfor root, dirs, files in os.walk(base_dir, topdown=True): 32911023Sjthestness@gmail.com Dir(root[len(base_dir) + 1:]) 33011023Sjthestness@gmail.com 33111023Sjthestness@gmail.com######################################################################## 33211023Sjthestness@gmail.com# 33311023Sjthestness@gmail.com# Walk the tree and execute all SConscripts in subdirectories 33411023Sjthestness@gmail.com# 33511023Sjthestness@gmail.com 33611023Sjthestness@gmail.comhere = Dir('.').srcnode().abspath 33711023Sjthestness@gmail.comfor root, dirs, files in os.walk(base_dir, topdown=True): 33811023Sjthestness@gmail.com if root == here: 33911023Sjthestness@gmail.com # we don't want to recurse back into this SConscript 34011023Sjthestness@gmail.com continue 34111023Sjthestness@gmail.com 34211023Sjthestness@gmail.com if 'SConscript' in files: 34311023Sjthestness@gmail.com build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 34411023Sjthestness@gmail.com SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 34511023Sjthestness@gmail.com 34611023Sjthestness@gmail.comfor extra_dir in extras_dir_list: 34711023Sjthestness@gmail.com prefix_len = len(dirname(extra_dir)) + 1 34811023Sjthestness@gmail.com 34911023Sjthestness@gmail.com # Also add the corresponding build directory to pick up generated 35011023Sjthestness@gmail.com # include files. 35111023Sjthestness@gmail.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 35211023Sjthestness@gmail.com 35311023Sjthestness@gmail.com for root, dirs, files in os.walk(extra_dir, topdown=True): 3549469Snilay@cs.wisc.edu # if build lives in the extras directory, don't walk down it 3557892SN/A if 'build' in dirs: 35611023Sjthestness@gmail.com dirs.remove('build') 3577892SN/A 3589469Snilay@cs.wisc.edu if 'SConscript' in files: 3597892SN/A build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 36010315Snilay@cs.wisc.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 36110036SAli.Saidi@ARM.com 36210036SAli.Saidi@ARM.comfor opt in export_vars: 36311023Sjthestness@gmail.com env.ConfigFile(opt) 3647892SN/A 36511023Sjthestness@gmail.comdef makeTheISA(source, target, env): 3667892SN/A isas = [ src.get_contents() for src in source ] 3677892SN/A target_isa = env['TARGET_ISA'] 36811023Sjthestness@gmail.com def define(isa): 36911023Sjthestness@gmail.com return isa.upper() + '_ISA' 37011023Sjthestness@gmail.com 3718673SN/A def namespace(isa): 37210645Snilay@cs.wisc.edu return isa[0].upper() + isa[1:].lower() + 'ISA' 3739469Snilay@cs.wisc.edu 37410526Snilay@cs.wisc.edu 3759864Snilay@cs.wisc.edu code = code_formatter() 3767892SN/A code('''\ 3777892SN/A#ifndef __CONFIG_THE_ISA_HH__ 3789469Snilay@cs.wisc.edu#define __CONFIG_THE_ISA_HH__ 3798673SN/A 38011023Sjthestness@gmail.com''') 3818673SN/A 3829113SBrad.Beckmann@amd.com # create defines for the preprocessing and compile-time determination 3839113SBrad.Beckmann@amd.com for i,isa in enumerate(isas): 38410036SAli.Saidi@ARM.com code('#define $0 $1', define(isa), i + 1) 3858673SN/A code() 38611023Sjthestness@gmail.com 3879113SBrad.Beckmann@amd.com # create an enum for any run-time determination of the ISA, we 38811023Sjthestness@gmail.com # reuse the same name as the namespaces 3898673SN/A code('enum class Arch {') 3908673SN/A for i,isa in enumerate(isas): 3919113SBrad.Beckmann@amd.com if i + 1 == len(isas): 3929113SBrad.Beckmann@amd.com code(' $0 = $1', namespace(isa), define(isa)) 3938673SN/A else: 39411023Sjthestness@gmail.com code(' $0 = $1,', namespace(isa), define(isa)) 39511023Sjthestness@gmail.com code('};') 39611023Sjthestness@gmail.com 39711023Sjthestness@gmail.com code(''' 39811023Sjthestness@gmail.com 39911023Sjthestness@gmail.com#define THE_ISA ${{define(target_isa)}} 40011023Sjthestness@gmail.com#define TheISA ${{namespace(target_isa)}} 40111023Sjthestness@gmail.com#define THE_ISA_STR "${{target_isa}}" 40211023Sjthestness@gmail.com 40311023Sjthestness@gmail.com#endif // __CONFIG_THE_ISA_HH__''') 40411023Sjthestness@gmail.com 40511023Sjthestness@gmail.com code.write(str(target[0])) 40611023Sjthestness@gmail.com 40711023Sjthestness@gmail.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 40811023Sjthestness@gmail.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 40911023Sjthestness@gmail.com 41011023Sjthestness@gmail.com######################################################################## 41111023Sjthestness@gmail.com# 41211023Sjthestness@gmail.com# Prevent any SimObjects from being added after this point, they 41311023Sjthestness@gmail.com# should all have been added in the SConscripts above 41411023Sjthestness@gmail.com# 41511023Sjthestness@gmail.comSimObject.fixed = True 41611023Sjthestness@gmail.com 41711023Sjthestness@gmail.comclass DictImporter(object): 41811023Sjthestness@gmail.com '''This importer takes a dictionary of arbitrary module names that 41911023Sjthestness@gmail.com map to arbitrary filenames.''' 42011023Sjthestness@gmail.com def __init__(self, modules): 42111023Sjthestness@gmail.com self.modules = modules 42211023Sjthestness@gmail.com self.installed = set() 42311023Sjthestness@gmail.com 42411023Sjthestness@gmail.com def __del__(self): 42511023Sjthestness@gmail.com self.unload() 42611023Sjthestness@gmail.com 42711023Sjthestness@gmail.com def unload(self): 42811023Sjthestness@gmail.com import sys 42911023Sjthestness@gmail.com for module in self.installed: 43011023Sjthestness@gmail.com del sys.modules[module] 43111023Sjthestness@gmail.com self.installed = set() 43211023Sjthestness@gmail.com 43311023Sjthestness@gmail.com def find_module(self, fullname, path): 43411023Sjthestness@gmail.com if fullname == 'm5.defines': 43511023Sjthestness@gmail.com return self 43611023Sjthestness@gmail.com 43711023Sjthestness@gmail.com if fullname == 'm5.objects': 43811023Sjthestness@gmail.com return self 43911023Sjthestness@gmail.com 4409469Snilay@cs.wisc.edu if fullname.startswith('m5.internal'): 4418673SN/A return None 44210315Snilay@cs.wisc.edu 4439469Snilay@cs.wisc.edu source = self.modules.get(fullname, None) 44411023Sjthestness@gmail.com if source is not None and fullname.startswith('m5.objects'): 4458673SN/A return self 44610036SAli.Saidi@ARM.com 4479469Snilay@cs.wisc.edu return None 44811023Sjthestness@gmail.com 4498673SN/A def load_module(self, fullname): 45011268Satgutier@umich.edu mod = imp.new_module(fullname) 4518673SN/A sys.modules[fullname] = mod 4528983Snate@binkert.org self.installed.add(fullname) 4538983Snate@binkert.org 4548983Snate@binkert.org mod.__loader__ = self 4558673SN/A if fullname == 'm5.objects': 4568673SN/A mod.__path__ = fullname.split('.') 4578673SN/A return mod 4588983Snate@binkert.org 4598983Snate@binkert.org if fullname == 'm5.defines': 4608673SN/A mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 4619864Snilay@cs.wisc.edu return mod 4629864Snilay@cs.wisc.edu 4639864Snilay@cs.wisc.edu source = self.modules[fullname] 4649864Snilay@cs.wisc.edu if source.modname == '__init__': 46510036SAli.Saidi@ARM.com mod.__path__ = source.modpath 4669864Snilay@cs.wisc.edu mod.__file__ = source.abspath 4677892SN/A 4687892SN/A exec file(source.abspath, 'r') in mod.__dict__ 46911066Snilay@cs.wisc.edu 4707892SN/A return mod 4717892SN/A 4729864Snilay@cs.wisc.eduimport m5.SimObject 4737892SN/Aimport m5.params 4748673SN/Afrom m5.util import code_formatter 47510036SAli.Saidi@ARM.com 4769605Snilay@cs.wisc.edum5.SimObject.clear() 47711066Snilay@cs.wisc.edum5.params.clear() 4789605Snilay@cs.wisc.edu 47910315Snilay@cs.wisc.edu# install the python importer so we can grab stuff from the source 48011066Snilay@cs.wisc.edu# tree itself. We can't have SimObjects added after this point or 4819864Snilay@cs.wisc.edu# else we won't know about them for the rest of the stuff. 4828673SN/Aimporter = DictImporter(PySource.modules) 4839605Snilay@cs.wisc.edusys.meta_path[0:0] = [ importer ] 48411023Sjthestness@gmail.com 48511023Sjthestness@gmail.com# import all sim objects so we can populate the all_objects list 4867892SN/A# make sure that we're working with a list, then let's sort it 4879605Snilay@cs.wisc.edufor modname in SimObject.modnames: 4888673SN/A exec('from m5.objects import %s' % modname) 4898673SN/A 49010036SAli.Saidi@ARM.com# we need to unload all of the currently imported modules so that they 4919469Snilay@cs.wisc.edu# will be re-imported the next time the sconscript is run 4929864Snilay@cs.wisc.eduimporter.unload() 4937892SN/Asys.meta_path.remove(importer) 4948673SN/A 4957892SN/Asim_objects = m5.SimObject.allClasses 4967892SN/Aall_enums = m5.params.allEnums 4979605Snilay@cs.wisc.edu 4988673SN/Aif m5.SimObject.noCxxHeader: 4998673SN/A print >> sys.stderr, \ 50010036SAli.Saidi@ARM.com "warning: At least one SimObject lacks a header specification. " \ 5019469Snilay@cs.wisc.edu "This can cause unexpected results in the generated SWIG " \ 5029864Snilay@cs.wisc.edu "wrappers." 5037892SN/A 5048673SN/A# Find param types that need to be explicitly wrapped with swig. 5057892SN/A# These will be recognized because the ParamDesc will have a 5067892SN/A# swig_decl() method. Most param types are based on types that don't 50711023Sjthestness@gmail.com# need this, either because they're based on native types (like Int) 50811023Sjthestness@gmail.com# or because they're SimObjects (which get swigged independently). 50911023Sjthestness@gmail.com# For now the only things handled here are VectorParam types. 51011023Sjthestness@gmail.comparams_to_swig = {} 51111023Sjthestness@gmail.comfor name,obj in sorted(sim_objects.iteritems()): 51211023Sjthestness@gmail.com for param in obj._params.local.values(): 51311023Sjthestness@gmail.com # load the ptype attribute now because it depends on the 51411023Sjthestness@gmail.com # current version of SimObject.allClasses, but when scons 51511023Sjthestness@gmail.com # actually uses the value, all versions of 51611023Sjthestness@gmail.com # SimObject.allClasses will have been loaded 51711023Sjthestness@gmail.com param.ptype 51811023Sjthestness@gmail.com 51911023Sjthestness@gmail.com if not hasattr(param, 'swig_decl'): 52011023Sjthestness@gmail.com continue 52111023Sjthestness@gmail.com pname = param.ptype_str 52211023Sjthestness@gmail.com if pname not in params_to_swig: 52311023Sjthestness@gmail.com params_to_swig[pname] = param 52411023Sjthestness@gmail.com 52511023Sjthestness@gmail.com######################################################################## 52611023Sjthestness@gmail.com# 52711023Sjthestness@gmail.com# calculate extra dependencies 52811023Sjthestness@gmail.com# 52911023Sjthestness@gmail.commodule_depends = ["m5", "m5.SimObject", "m5.params"] 53011023Sjthestness@gmail.comdepends = [ PySource.modules[dep].snode for dep in module_depends ] 53111023Sjthestness@gmail.comdepends.sort(key = lambda x: x.name) 53211023Sjthestness@gmail.com 53311023Sjthestness@gmail.com######################################################################## 53411023Sjthestness@gmail.com# 53511023Sjthestness@gmail.com# Commands for the basic automatically generated python files 53611023Sjthestness@gmail.com# 53711023Sjthestness@gmail.com 53811023Sjthestness@gmail.com# Generate Python file containing a dict specifying the current 53911023Sjthestness@gmail.com# buildEnv flags. 54011023Sjthestness@gmail.comdef makeDefinesPyFile(target, source, env): 54111023Sjthestness@gmail.com build_env = source[0].get_contents() 54211023Sjthestness@gmail.com 54311023Sjthestness@gmail.com code = code_formatter() 54411023Sjthestness@gmail.com code(""" 54511023Sjthestness@gmail.comimport m5.internal 54611023Sjthestness@gmail.comimport m5.util 54711023Sjthestness@gmail.com 54811023Sjthestness@gmail.combuildEnv = m5.util.SmartDict($build_env) 54911023Sjthestness@gmail.com 55011023Sjthestness@gmail.comcompileDate = m5.internal.core.compileDate 55111023Sjthestness@gmail.com_globals = globals() 55211023Sjthestness@gmail.comfor key,val in m5.internal.core.__dict__.iteritems(): 55311023Sjthestness@gmail.com if key.startswith('flag_'): 55411023Sjthestness@gmail.com flag = key[5:] 55511023Sjthestness@gmail.com _globals[flag] = val 55611023Sjthestness@gmail.comdel _globals 55711023Sjthestness@gmail.com""") 55811023Sjthestness@gmail.com code.write(target[0].abspath) 55911023Sjthestness@gmail.com 56011023Sjthestness@gmail.comdefines_info = Value(build_env) 56111023Sjthestness@gmail.com# Generate a file with all of the compile options in it 56211023Sjthestness@gmail.comenv.Command('python/m5/defines.py', defines_info, 56311023Sjthestness@gmail.com MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 56411023Sjthestness@gmail.comPySource('m5', 'python/m5/defines.py') 56511023Sjthestness@gmail.com 56611023Sjthestness@gmail.com# Generate python file containing info about the M5 source code 56711023Sjthestness@gmail.comdef makeInfoPyFile(target, source, env): 56811023Sjthestness@gmail.com code = code_formatter() 56911023Sjthestness@gmail.com for src in source: 57011023Sjthestness@gmail.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 57111023Sjthestness@gmail.com code('$src = ${{repr(data)}}') 57211023Sjthestness@gmail.com code.write(str(target[0])) 57311023Sjthestness@gmail.com 57411023Sjthestness@gmail.com# Generate a file that wraps the basic top level files 57511023Sjthestness@gmail.comenv.Command('python/m5/info.py', 57611023Sjthestness@gmail.com [ '#/COPYING', '#/LICENSE', '#/README', ], 57711023Sjthestness@gmail.com MakeAction(makeInfoPyFile, Transform("INFO"))) 57811023Sjthestness@gmail.comPySource('m5', 'python/m5/info.py') 57911023Sjthestness@gmail.com 58011023Sjthestness@gmail.com######################################################################## 58111023Sjthestness@gmail.com# 58211023Sjthestness@gmail.com# Create all of the SimObject param headers and enum headers 58311023Sjthestness@gmail.com# 58411023Sjthestness@gmail.com 58511023Sjthestness@gmail.comdef createSimObjectParamStruct(target, source, env): 58611023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 58711023Sjthestness@gmail.com 58811023Sjthestness@gmail.com name = str(source[0].get_contents()) 58911023Sjthestness@gmail.com obj = sim_objects[name] 59011023Sjthestness@gmail.com 59111023Sjthestness@gmail.com code = code_formatter() 59211023Sjthestness@gmail.com obj.cxx_param_decl(code) 59311023Sjthestness@gmail.com code.write(target[0].abspath) 59411023Sjthestness@gmail.com 59511023Sjthestness@gmail.comdef createSimObjectCxxConfig(is_header): 59611023Sjthestness@gmail.com def body(target, source, env): 59711023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 59811023Sjthestness@gmail.com 59911023Sjthestness@gmail.com name = str(source[0].get_contents()) 60011023Sjthestness@gmail.com obj = sim_objects[name] 60111023Sjthestness@gmail.com 60211023Sjthestness@gmail.com code = code_formatter() 60311023Sjthestness@gmail.com obj.cxx_config_param_file(code, is_header) 60411023Sjthestness@gmail.com code.write(target[0].abspath) 60511023Sjthestness@gmail.com return body 60611023Sjthestness@gmail.com 60711023Sjthestness@gmail.comdef createParamSwigWrapper(target, source, env): 60811023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 60911023Sjthestness@gmail.com 61011023Sjthestness@gmail.com name = str(source[0].get_contents()) 61111023Sjthestness@gmail.com param = params_to_swig[name] 61211023Sjthestness@gmail.com 61311023Sjthestness@gmail.com code = code_formatter() 61411023Sjthestness@gmail.com param.swig_decl(code) 61511023Sjthestness@gmail.com code.write(target[0].abspath) 61611023Sjthestness@gmail.com 61711023Sjthestness@gmail.comdef createEnumStrings(target, source, env): 61811023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 61911023Sjthestness@gmail.com 62011023Sjthestness@gmail.com name = str(source[0].get_contents()) 62111023Sjthestness@gmail.com obj = all_enums[name] 62211023Sjthestness@gmail.com 62311023Sjthestness@gmail.com code = code_formatter() 62411023Sjthestness@gmail.com obj.cxx_def(code) 62511023Sjthestness@gmail.com code.write(target[0].abspath) 62611023Sjthestness@gmail.com 62711023Sjthestness@gmail.comdef createEnumDecls(target, source, env): 62811023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 62911023Sjthestness@gmail.com 63011023Sjthestness@gmail.com name = str(source[0].get_contents()) 63111023Sjthestness@gmail.com obj = all_enums[name] 63211023Sjthestness@gmail.com 63311023Sjthestness@gmail.com code = code_formatter() 63411023Sjthestness@gmail.com obj.cxx_decl(code) 63511023Sjthestness@gmail.com code.write(target[0].abspath) 63611023Sjthestness@gmail.com 63711023Sjthestness@gmail.comdef createEnumSwigWrapper(target, source, env): 63811023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 63911023Sjthestness@gmail.com 64011023Sjthestness@gmail.com name = str(source[0].get_contents()) 64111023Sjthestness@gmail.com obj = all_enums[name] 64211023Sjthestness@gmail.com 64311023Sjthestness@gmail.com code = code_formatter() 64411023Sjthestness@gmail.com obj.swig_decl(code) 64511023Sjthestness@gmail.com code.write(target[0].abspath) 64611023Sjthestness@gmail.com 6479605Snilay@cs.wisc.edudef createSimObjectSwigWrapper(target, source, env): 6488673SN/A name = source[0].get_contents() 6498673SN/A obj = sim_objects[name] 65010036SAli.Saidi@ARM.com 6516928SN/A code = code_formatter() 6528673SN/A obj.swig_decl(code) 6539864Snilay@cs.wisc.edu code.write(target[0].abspath) 6549864Snilay@cs.wisc.edu 6556928SN/A# dummy target for generated code 6566928SN/A# we start out with all the Source files so they get copied to build/*/ also. 6579605Snilay@cs.wisc.eduSWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 6588673SN/A 6598673SN/A# Generate all of the SimObject param C++ struct header files 66010036SAli.Saidi@ARM.comparams_hh_files = [] 6616928SN/Afor name,simobj in sorted(sim_objects.iteritems()): 6628673SN/A py_source = PySource.modules[simobj.__module__] 6639864Snilay@cs.wisc.edu extra_deps = [ py_source.tnode ] 6649864Snilay@cs.wisc.edu 6656928SN/A hh_file = File('params/%s.hh' % name) 6666928SN/A params_hh_files.append(hh_file) 6679864Snilay@cs.wisc.edu env.Command(hh_file, Value(name), 6689864Snilay@cs.wisc.edu MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 66911066Snilay@cs.wisc.edu env.Depends(hh_file, depends + extra_deps) 6709864Snilay@cs.wisc.edu env.Depends(SWIG, hh_file) 67110036SAli.Saidi@ARM.com 67211066Snilay@cs.wisc.edu# C++ parameter description files 6739864Snilay@cs.wisc.eduif GetOption('with_cxx_config'): 67411066Snilay@cs.wisc.edu for name,simobj in sorted(sim_objects.iteritems()): 6759864Snilay@cs.wisc.edu py_source = PySource.modules[simobj.__module__] 67611023Sjthestness@gmail.com extra_deps = [ py_source.tnode ] 67711023Sjthestness@gmail.com 67811023Sjthestness@gmail.com cxx_config_hh_file = File('cxx_config/%s.hh' % name) 67911023Sjthestness@gmail.com cxx_config_cc_file = File('cxx_config/%s.cc' % name) 68011023Sjthestness@gmail.com env.Command(cxx_config_hh_file, Value(name), 68111023Sjthestness@gmail.com MakeAction(createSimObjectCxxConfig(True), 68211023Sjthestness@gmail.com Transform("CXXCPRHH"))) 68311023Sjthestness@gmail.com env.Command(cxx_config_cc_file, Value(name), 68411023Sjthestness@gmail.com MakeAction(createSimObjectCxxConfig(False), 68511023Sjthestness@gmail.com Transform("CXXCPRCC"))) 68611023Sjthestness@gmail.com env.Depends(cxx_config_hh_file, depends + extra_deps + 68711023Sjthestness@gmail.com [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 68811023Sjthestness@gmail.com env.Depends(cxx_config_cc_file, depends + extra_deps + 68911023Sjthestness@gmail.com [cxx_config_hh_file]) 69011023Sjthestness@gmail.com Source(cxx_config_cc_file) 69111023Sjthestness@gmail.com 69211023Sjthestness@gmail.com cxx_config_init_cc_file = File('cxx_config/init.cc') 69311023Sjthestness@gmail.com 69411023Sjthestness@gmail.com def createCxxConfigInitCC(target, source, env): 69511023Sjthestness@gmail.com assert len(target) == 1 and len(source) == 1 69611023Sjthestness@gmail.com 69711023Sjthestness@gmail.com code = code_formatter() 69811023Sjthestness@gmail.com 69911023Sjthestness@gmail.com for name,simobj in sorted(sim_objects.iteritems()): 70011023Sjthestness@gmail.com if not hasattr(simobj, 'abstract') or not simobj.abstract: 70111023Sjthestness@gmail.com code('#include "cxx_config/${name}.hh"') 70211023Sjthestness@gmail.com code() 70311023Sjthestness@gmail.com code('void cxxConfigInit()') 70411023Sjthestness@gmail.com code('{') 70511023Sjthestness@gmail.com code.indent() 70611023Sjthestness@gmail.com for name,simobj in sorted(sim_objects.iteritems()): 70711023Sjthestness@gmail.com not_abstract = not hasattr(simobj, 'abstract') or \ 70811023Sjthestness@gmail.com not simobj.abstract 70911023Sjthestness@gmail.com if not_abstract and 'type' in simobj.__dict__: 71011023Sjthestness@gmail.com code('cxx_config_directory["${name}"] = ' 71111023Sjthestness@gmail.com '${name}CxxConfigParams::makeDirectoryEntry();') 71211023Sjthestness@gmail.com code.dedent() 71311023Sjthestness@gmail.com code('}') 71411023Sjthestness@gmail.com code.write(target[0].abspath) 71511023Sjthestness@gmail.com 71611023Sjthestness@gmail.com py_source = PySource.modules[simobj.__module__] 71711023Sjthestness@gmail.com extra_deps = [ py_source.tnode ] 71811023Sjthestness@gmail.com env.Command(cxx_config_init_cc_file, Value(name), 71911023Sjthestness@gmail.com MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 72011023Sjthestness@gmail.com cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 72111023Sjthestness@gmail.com for name,simobj in sorted(sim_objects.iteritems()) 72211023Sjthestness@gmail.com if not hasattr(simobj, 'abstract') or not simobj.abstract] 72311023Sjthestness@gmail.com Depends(cxx_config_init_cc_file, cxx_param_hh_files + 72411023Sjthestness@gmail.com [File('sim/cxx_config.hh')]) 72511023Sjthestness@gmail.com Source(cxx_config_init_cc_file) 72611023Sjthestness@gmail.com 72711023Sjthestness@gmail.com# Generate any needed param SWIG wrapper files 72811023Sjthestness@gmail.comparams_i_files = [] 72911023Sjthestness@gmail.comfor name,param in sorted(params_to_swig.iteritems()): 73011023Sjthestness@gmail.com i_file = File('python/m5/internal/%s.i' % (param.swig_module_name())) 73111023Sjthestness@gmail.com params_i_files.append(i_file) 73211023Sjthestness@gmail.com env.Command(i_file, Value(name), 73311023Sjthestness@gmail.com MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 73411023Sjthestness@gmail.com env.Depends(i_file, depends) 73511023Sjthestness@gmail.com env.Depends(SWIG, i_file) 73611023Sjthestness@gmail.com SwigSource('m5.internal', i_file) 73711023Sjthestness@gmail.com 73811023Sjthestness@gmail.com# Generate all enum header files 73911023Sjthestness@gmail.comfor name,enum in sorted(all_enums.iteritems()): 74011023Sjthestness@gmail.com py_source = PySource.modules[enum.__module__] 74111023Sjthestness@gmail.com extra_deps = [ py_source.tnode ] 74211023Sjthestness@gmail.com 74311023Sjthestness@gmail.com cc_file = File('enums/%s.cc' % name) 74411023Sjthestness@gmail.com env.Command(cc_file, Value(name), 74511023Sjthestness@gmail.com MakeAction(createEnumStrings, Transform("ENUM STR"))) 74611023Sjthestness@gmail.com env.Depends(cc_file, depends + extra_deps) 74711023Sjthestness@gmail.com env.Depends(SWIG, cc_file) 74811023Sjthestness@gmail.com Source(cc_file) 74911023Sjthestness@gmail.com 75011023Sjthestness@gmail.com hh_file = File('enums/%s.hh' % name) 75111023Sjthestness@gmail.com env.Command(hh_file, Value(name), 75211023Sjthestness@gmail.com MakeAction(createEnumDecls, Transform("ENUMDECL"))) 75311023Sjthestness@gmail.com env.Depends(hh_file, depends + extra_deps) 75411023Sjthestness@gmail.com env.Depends(SWIG, hh_file) 75511023Sjthestness@gmail.com 75611023Sjthestness@gmail.com i_file = File('python/m5/internal/enum_%s.i' % name) 75711023Sjthestness@gmail.com env.Command(i_file, Value(name), 75811023Sjthestness@gmail.com MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 75911023Sjthestness@gmail.com env.Depends(i_file, depends + extra_deps) 76011023Sjthestness@gmail.com env.Depends(SWIG, i_file) 76111023Sjthestness@gmail.com SwigSource('m5.internal', i_file) 76211023Sjthestness@gmail.com 76311023Sjthestness@gmail.com# Generate SimObject SWIG wrapper files 76411023Sjthestness@gmail.comfor name,simobj in sorted(sim_objects.iteritems()): 76511023Sjthestness@gmail.com py_source = PySource.modules[simobj.__module__] 76611023Sjthestness@gmail.com extra_deps = [ py_source.tnode ] 76711023Sjthestness@gmail.com i_file = File('python/m5/internal/param_%s.i' % name) 76811023Sjthestness@gmail.com env.Command(i_file, Value(name), 76911023Sjthestness@gmail.com MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 77011023Sjthestness@gmail.com env.Depends(i_file, depends + extra_deps) 77111023Sjthestness@gmail.com SwigSource('m5.internal', i_file) 77211023Sjthestness@gmail.com 77311023Sjthestness@gmail.com# Generate the main swig init file 77411023Sjthestness@gmail.comdef makeEmbeddedSwigInit(target, source, env): 77511023Sjthestness@gmail.com code = code_formatter() 77611023Sjthestness@gmail.com module = source[0].get_contents() 77711023Sjthestness@gmail.com code('''\ 77811023Sjthestness@gmail.com#include "sim/init.hh" 77911023Sjthestness@gmail.com 78011023Sjthestness@gmail.comextern "C" { 7819864Snilay@cs.wisc.edu void init_${module}(); 7829864Snilay@cs.wisc.edu} 78311066Snilay@cs.wisc.edu 7849864Snilay@cs.wisc.eduEmbeddedSwig embed_swig_${module}(init_${module}); 78510036SAli.Saidi@ARM.com''') 78611066Snilay@cs.wisc.edu code.write(str(target[0])) 7879864Snilay@cs.wisc.edu 78811066Snilay@cs.wisc.edu# Build all swig modules 7899864Snilay@cs.wisc.edufor swig in SwigSource.all: 79011023Sjthestness@gmail.com env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 79111023Sjthestness@gmail.com MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 79211023Sjthestness@gmail.com '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 79311023Sjthestness@gmail.com cc_file = str(swig.tnode) 79411023Sjthestness@gmail.com init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 79511023Sjthestness@gmail.com env.Command(init_file, Value(swig.module), 79611023Sjthestness@gmail.com MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) 79711023Sjthestness@gmail.com env.Depends(SWIG, init_file) 79811023Sjthestness@gmail.com Source(init_file, **swig.guards) 79911023Sjthestness@gmail.com 80011023Sjthestness@gmail.com# Build all protocol buffers if we have got protoc and protobuf available 80111023Sjthestness@gmail.comif env['HAVE_PROTOBUF']: 80211023Sjthestness@gmail.com for proto in ProtoBuf.all: 80311023Sjthestness@gmail.com # Use both the source and header as the target, and the .proto 80411023Sjthestness@gmail.com # file as the source. When executing the protoc compiler, also 80511023Sjthestness@gmail.com # specify the proto_path to avoid having the generated files 80611023Sjthestness@gmail.com # include the path. 80711023Sjthestness@gmail.com env.Command([proto.cc_file, proto.hh_file], proto.tnode, 80811023Sjthestness@gmail.com MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 80911023Sjthestness@gmail.com '--proto_path ${SOURCE.dir} $SOURCE', 81011023Sjthestness@gmail.com Transform("PROTOC"))) 81111023Sjthestness@gmail.com 81211023Sjthestness@gmail.com env.Depends(SWIG, [proto.cc_file, proto.hh_file]) 81311023Sjthestness@gmail.com # Add the C++ source file 81411023Sjthestness@gmail.com Source(proto.cc_file, **proto.guards) 81511023Sjthestness@gmail.comelif ProtoBuf.all: 81611023Sjthestness@gmail.com print 'Got protobuf to build, but lacks support!' 81711023Sjthestness@gmail.com Exit(1) 81811023Sjthestness@gmail.com 81911023Sjthestness@gmail.com# 82011023Sjthestness@gmail.com# Handle debug flags 82111023Sjthestness@gmail.com# 82211023Sjthestness@gmail.comdef makeDebugFlagCC(target, source, env): 82311023Sjthestness@gmail.com assert(len(target) == 1 and len(source) == 1) 82411023Sjthestness@gmail.com 82511023Sjthestness@gmail.com code = code_formatter() 82611023Sjthestness@gmail.com 82711023Sjthestness@gmail.com # delay definition of CompoundFlags until after all the definition 82811023Sjthestness@gmail.com # of all constituent SimpleFlags 82911023Sjthestness@gmail.com comp_code = code_formatter() 83011023Sjthestness@gmail.com 83111023Sjthestness@gmail.com # file header 83211023Sjthestness@gmail.com code(''' 83311023Sjthestness@gmail.com/* 83411023Sjthestness@gmail.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 83511023Sjthestness@gmail.com */ 83611023Sjthestness@gmail.com 83711023Sjthestness@gmail.com#include "base/debug.hh" 83811023Sjthestness@gmail.com 83911023Sjthestness@gmail.comnamespace Debug { 84011023Sjthestness@gmail.com 84111023Sjthestness@gmail.com''') 84211023Sjthestness@gmail.com 84311023Sjthestness@gmail.com for name, flag in sorted(source[0].read().iteritems()): 84411023Sjthestness@gmail.com n, compound, desc = flag 84511023Sjthestness@gmail.com assert n == name 84611023Sjthestness@gmail.com 84711023Sjthestness@gmail.com if not compound: 84811023Sjthestness@gmail.com code('SimpleFlag $name("$name", "$desc");') 84911023Sjthestness@gmail.com else: 85011023Sjthestness@gmail.com comp_code('CompoundFlag $name("$name", "$desc",') 85111023Sjthestness@gmail.com comp_code.indent() 85211023Sjthestness@gmail.com last = len(compound) - 1 85311023Sjthestness@gmail.com for i,flag in enumerate(compound): 85411023Sjthestness@gmail.com if i != last: 85511023Sjthestness@gmail.com comp_code('&$flag,') 85611023Sjthestness@gmail.com else: 85711023Sjthestness@gmail.com comp_code('&$flag);') 85811023Sjthestness@gmail.com comp_code.dedent() 85911023Sjthestness@gmail.com 86011023Sjthestness@gmail.com code.append(comp_code) 86111023Sjthestness@gmail.com code() 86211023Sjthestness@gmail.com code('} // namespace Debug') 86311023Sjthestness@gmail.com 86411023Sjthestness@gmail.com code.write(str(target[0])) 86511023Sjthestness@gmail.com 86611023Sjthestness@gmail.comdef makeDebugFlagHH(target, source, env): 86711023Sjthestness@gmail.com assert(len(target) == 1 and len(source) == 1) 86811023Sjthestness@gmail.com 86911023Sjthestness@gmail.com val = eval(source[0].get_contents()) 87011023Sjthestness@gmail.com name, compound, desc = val 87111023Sjthestness@gmail.com 87211023Sjthestness@gmail.com code = code_formatter() 87311023Sjthestness@gmail.com 87411023Sjthestness@gmail.com # file header boilerplate 87511023Sjthestness@gmail.com code('''\ 87611023Sjthestness@gmail.com/* 87711023Sjthestness@gmail.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 87811023Sjthestness@gmail.com */ 87911023Sjthestness@gmail.com 88011023Sjthestness@gmail.com#ifndef __DEBUG_${name}_HH__ 88111023Sjthestness@gmail.com#define __DEBUG_${name}_HH__ 88211023Sjthestness@gmail.com 88311023Sjthestness@gmail.comnamespace Debug { 88411023Sjthestness@gmail.com''') 88511023Sjthestness@gmail.com 88611023Sjthestness@gmail.com if compound: 88711023Sjthestness@gmail.com code('class CompoundFlag;') 88811023Sjthestness@gmail.com code('class SimpleFlag;') 88911023Sjthestness@gmail.com 89011023Sjthestness@gmail.com if compound: 89111023Sjthestness@gmail.com code('extern CompoundFlag $name;') 89211023Sjthestness@gmail.com for flag in compound: 89311023Sjthestness@gmail.com code('extern SimpleFlag $flag;') 89411023Sjthestness@gmail.com else: 8959864Snilay@cs.wisc.edu code('extern SimpleFlag $name;') 8969864Snilay@cs.wisc.edu 89711066Snilay@cs.wisc.edu code(''' 8989864Snilay@cs.wisc.edu} 89910036SAli.Saidi@ARM.com 90011066Snilay@cs.wisc.edu#endif // __DEBUG_${name}_HH__ 9019864Snilay@cs.wisc.edu''') 90211066Snilay@cs.wisc.edu 9039864Snilay@cs.wisc.edu code.write(str(target[0])) 90411023Sjthestness@gmail.com 90511023Sjthestness@gmail.comfor name,flag in sorted(debug_flags.iteritems()): 90611023Sjthestness@gmail.com n, compound, desc = flag 90711023Sjthestness@gmail.com assert n == name 90811023Sjthestness@gmail.com 90911023Sjthestness@gmail.com hh_file = 'debug/%s.hh' % name 91011023Sjthestness@gmail.com env.Command(hh_file, Value(flag), 91111023Sjthestness@gmail.com MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 91211023Sjthestness@gmail.com env.Depends(SWIG, hh_file) 91311023Sjthestness@gmail.com 91411023Sjthestness@gmail.comenv.Command('debug/flags.cc', Value(debug_flags), 91511023Sjthestness@gmail.com MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 91611023Sjthestness@gmail.comenv.Depends(SWIG, 'debug/flags.cc') 91711023Sjthestness@gmail.comSource('debug/flags.cc') 91811023Sjthestness@gmail.com 91911023Sjthestness@gmail.com# Embed python files. All .py files that have been indicated by a 92011023Sjthestness@gmail.com# PySource() call in a SConscript need to be embedded into the M5 92111023Sjthestness@gmail.com# library. To do that, we compile the file to byte code, marshal the 92211023Sjthestness@gmail.com# byte code, compress it, and then generate a c++ file that 92311023Sjthestness@gmail.com# inserts the result into an array. 92411023Sjthestness@gmail.comdef embedPyFile(target, source, env): 92511023Sjthestness@gmail.com def c_str(string): 92611023Sjthestness@gmail.com if string is None: 92711023Sjthestness@gmail.com return "0" 92811023Sjthestness@gmail.com return '"%s"' % string 92911023Sjthestness@gmail.com 93011023Sjthestness@gmail.com '''Action function to compile a .py into a code object, marshal 93111023Sjthestness@gmail.com it, compress it, and stick it into an asm file so the code appears 93211023Sjthestness@gmail.com as just bytes with a label in the data section''' 93311023Sjthestness@gmail.com 93411023Sjthestness@gmail.com src = file(str(source[0]), 'r').read() 93511023Sjthestness@gmail.com 93611023Sjthestness@gmail.com pysource = PySource.tnodes[source[0]] 93711023Sjthestness@gmail.com compiled = compile(src, pysource.abspath, 'exec') 93811023Sjthestness@gmail.com marshalled = marshal.dumps(compiled) 93911023Sjthestness@gmail.com compressed = zlib.compress(marshalled) 94011023Sjthestness@gmail.com data = compressed 94111023Sjthestness@gmail.com sym = pysource.symname 94211023Sjthestness@gmail.com 94311023Sjthestness@gmail.com code = code_formatter() 94411023Sjthestness@gmail.com code('''\ 94511023Sjthestness@gmail.com#include "sim/init.hh" 94611023Sjthestness@gmail.com 94711023Sjthestness@gmail.comnamespace { 94811023Sjthestness@gmail.com 94911023Sjthestness@gmail.comconst uint8_t data_${sym}[] = { 95011023Sjthestness@gmail.com''') 95111023Sjthestness@gmail.com code.indent() 95211023Sjthestness@gmail.com step = 16 95311023Sjthestness@gmail.com for i in xrange(0, len(data), step): 95411023Sjthestness@gmail.com x = array.array('B', data[i:i+step]) 95511023Sjthestness@gmail.com code(''.join('%d,' % d for d in x)) 95611023Sjthestness@gmail.com code.dedent() 95711023Sjthestness@gmail.com 95811023Sjthestness@gmail.com code('''}; 95911023Sjthestness@gmail.com 96011023Sjthestness@gmail.comEmbeddedPython embedded_${sym}( 96111023Sjthestness@gmail.com ${{c_str(pysource.arcname)}}, 96211023Sjthestness@gmail.com ${{c_str(pysource.abspath)}}, 96311023Sjthestness@gmail.com ${{c_str(pysource.modpath)}}, 96411023Sjthestness@gmail.com data_${sym}, 96511023Sjthestness@gmail.com ${{len(data)}}, 96611023Sjthestness@gmail.com ${{len(marshalled)}}); 96711023Sjthestness@gmail.com 96811023Sjthestness@gmail.com} // anonymous namespace 96911023Sjthestness@gmail.com''') 97011023Sjthestness@gmail.com code.write(str(target[0])) 97111023Sjthestness@gmail.com 97211023Sjthestness@gmail.comfor source in PySource.all: 97311023Sjthestness@gmail.com env.Command(source.cpp, source.tnode, 97411023Sjthestness@gmail.com MakeAction(embedPyFile, Transform("EMBED PY"))) 97511023Sjthestness@gmail.com env.Depends(SWIG, source.cpp) 97611023Sjthestness@gmail.com Source(source.cpp, skip_no_python=True) 97711023Sjthestness@gmail.com 97811023Sjthestness@gmail.com######################################################################## 97911023Sjthestness@gmail.com# 98011023Sjthestness@gmail.com# Define binaries. Each different build type (debug, opt, etc.) gets 98111023Sjthestness@gmail.com# a slightly different build environment. 98211023Sjthestness@gmail.com# 98311023Sjthestness@gmail.com 98411023Sjthestness@gmail.com# List of constructed environments to pass back to SConstruct 98511023Sjthestness@gmail.comdate_source = Source('base/date.cc', skip_lib=True) 98611023Sjthestness@gmail.com 98711023Sjthestness@gmail.com# Capture this directory for the closure makeEnv, otherwise when it is 98811023Sjthestness@gmail.com# called, it won't know what directory it should use. 98911023Sjthestness@gmail.comvariant_dir = Dir('.').path 99011023Sjthestness@gmail.comdef variant(*path): 99111023Sjthestness@gmail.com return os.path.join(variant_dir, *path) 99211023Sjthestness@gmail.comdef variantd(*path): 99311023Sjthestness@gmail.com return variant(*path)+'/' 99411023Sjthestness@gmail.com 99511023Sjthestness@gmail.com# Function to create a new build environment as clone of current 99611023Sjthestness@gmail.com# environment 'env' with modified object suffix and optional stripped 99711023Sjthestness@gmail.com# binary. Additional keyword arguments are appended to corresponding 99811023Sjthestness@gmail.com# build environment vars. 99911023Sjthestness@gmail.comdef makeEnv(env, label, objsfx, strip = False, **kwargs): 100011023Sjthestness@gmail.com # SCons doesn't know to append a library suffix when there is a '.' in the 100111023Sjthestness@gmail.com # name. Use '_' instead. 100211023Sjthestness@gmail.com libname = variant('gem5_' + label) 100311023Sjthestness@gmail.com exename = variant('gem5.' + label) 100411023Sjthestness@gmail.com secondary_exename = variant('m5.' + label) 100511023Sjthestness@gmail.com 100611023Sjthestness@gmail.com new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 100711023Sjthestness@gmail.com new_env.Label = label 100811023Sjthestness@gmail.com new_env.Append(**kwargs) 100911023Sjthestness@gmail.com 101011023Sjthestness@gmail.com swig_env = new_env.Clone() 101111023Sjthestness@gmail.com 101211023Sjthestness@gmail.com # Both gcc and clang have issues with unused labels and values in 101311023Sjthestness@gmail.com # the SWIG generated code 101411023Sjthestness@gmail.com swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 101511023Sjthestness@gmail.com 101611023Sjthestness@gmail.com # Add additional warnings here that should not be applied to 101711023Sjthestness@gmail.com # the SWIG generated code 101811023Sjthestness@gmail.com new_env.Append(CXXFLAGS='-Wmissing-declarations') 101911023Sjthestness@gmail.com 102011023Sjthestness@gmail.com if env['GCC']: 102111023Sjthestness@gmail.com # Depending on the SWIG version, we also need to supress 102211023Sjthestness@gmail.com # warnings about uninitialized variables and missing field 102311023Sjthestness@gmail.com # initializers. 102411023Sjthestness@gmail.com swig_env.Append(CCFLAGS=['-Wno-uninitialized', 102511023Sjthestness@gmail.com '-Wno-missing-field-initializers', 102611023Sjthestness@gmail.com '-Wno-unused-but-set-variable']) 102711023Sjthestness@gmail.com 102811023Sjthestness@gmail.com # If gcc supports it, also warn for deletion of derived 102911023Sjthestness@gmail.com # classes with non-virtual desctructors. For gcc >= 4.7 we 103011023Sjthestness@gmail.com # also have to disable warnings about the SWIG code having 103111023Sjthestness@gmail.com # potentially uninitialized variables. 103211023Sjthestness@gmail.com if compareVersions(env['GCC_VERSION'], '4.7') >= 0: 103311023Sjthestness@gmail.com new_env.Append(CXXFLAGS='-Wdelete-non-virtual-dtor') 103411023Sjthestness@gmail.com swig_env.Append(CCFLAGS='-Wno-maybe-uninitialized') 103511023Sjthestness@gmail.com 103611023Sjthestness@gmail.com # Only gcc >= 4.9 supports UBSan, so check both the version 103711023Sjthestness@gmail.com # and the command-line option before adding the compiler and 103811023Sjthestness@gmail.com # linker flags. 103911023Sjthestness@gmail.com if GetOption('with_ubsan') and \ 104011023Sjthestness@gmail.com compareVersions(env['GCC_VERSION'], '4.9') >= 0: 104111023Sjthestness@gmail.com new_env.Append(CCFLAGS='-fsanitize=undefined') 104211023Sjthestness@gmail.com new_env.Append(LINKFLAGS='-fsanitize=undefined') 104311023Sjthestness@gmail.com 10448721SN/A if env['CLANG']: 10458721SN/A # Always enable the warning for deletion of derived classes 10469864Snilay@cs.wisc.edu # with non-virtual destructors 104710036SAli.Saidi@ARM.com new_env.Append(CXXFLAGS=['-Wdelete-non-virtual-dtor']) 104811268Satgutier@umich.edu 10498673SN/A swig_env.Append(CCFLAGS=[ 10508983Snate@binkert.org # Some versions of SWIG can return uninitialized values 10518983Snate@binkert.org '-Wno-sometimes-uninitialized', 10528983Snate@binkert.org # Register storage is requested in a lot of places in 10538721SN/A # SWIG-generated code. 10548721SN/A '-Wno-deprecated-register', 10558983Snate@binkert.org ]) 10566928SN/A 10579864Snilay@cs.wisc.edu # All supported clang versions have support for UBSan, so if 10589864Snilay@cs.wisc.edu # asked to use it, append the compiler and linker flags. 105910036SAli.Saidi@ARM.com if GetOption('with_ubsan'): 10609864Snilay@cs.wisc.edu new_env.Append(CCFLAGS='-fsanitize=undefined') 10619864Snilay@cs.wisc.edu new_env.Append(LINKFLAGS='-fsanitize=undefined') 1062 1063 werror_env = new_env.Clone() 1064 # Treat warnings as errors but white list some warnings that we 1065 # want to allow (e.g., deprecation warnings). 1066 werror_env.Append(CCFLAGS=['-Werror', 1067 '-Wno-error=deprecated-declarations', 1068 '-Wno-error=deprecated', 1069 ]) 1070 1071 def make_obj(source, static, extra_deps = None): 1072 '''This function adds the specified source to the correct 1073 build environment, and returns the corresponding SCons Object 1074 nodes''' 1075 1076 if source.swig: 1077 env = swig_env 1078 elif source.Werror: 1079 env = werror_env 1080 else: 1081 env = new_env 1082 1083 if static: 1084 obj = env.StaticObject(source.tnode) 1085 else: 1086 obj = env.SharedObject(source.tnode) 1087 1088 if extra_deps: 1089 env.Depends(obj, extra_deps) 1090 1091 return obj 1092 1093 lib_guards = {'main': False, 'skip_lib': False} 1094 1095 # Without Python, leave out all SWIG and Python content from the 1096 # library builds. The option doesn't affect gem5 built as a program 1097 if GetOption('without_python'): 1098 lib_guards['skip_no_python'] = False 1099 1100 static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] 1101 shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] 1102 1103 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 1104 static_objs.append(static_date) 1105 1106 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 1107 shared_objs.append(shared_date) 1108 1109 # First make a library of everything but main() so other programs can 1110 # link against m5. 1111 static_lib = new_env.StaticLibrary(libname, static_objs) 1112 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1113 1114 # Now link a stub with main() and the static library. 1115 main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 1116 1117 for test in UnitTest.all: 1118 flags = { test.target : True } 1119 test_sources = Source.get(**flags) 1120 test_objs = [ make_obj(s, static=True) for s in test_sources ] 1121 if test.main: 1122 test_objs += main_objs 1123 path = variant('unittest/%s.%s' % (test.target, label)) 1124 new_env.Program(path, test_objs + static_objs) 1125 1126 progname = exename 1127 if strip: 1128 progname += '.unstripped' 1129 1130 targets = new_env.Program(progname, main_objs + static_objs) 1131 1132 if strip: 1133 if sys.platform == 'sunos5': 1134 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1135 else: 1136 cmd = 'strip $SOURCE -o $TARGET' 1137 targets = new_env.Command(exename, progname, 1138 MakeAction(cmd, Transform("STRIP"))) 1139 1140 new_env.Command(secondary_exename, exename, 1141 MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 1142 1143 new_env.M5Binary = targets[0] 1144 return new_env 1145 1146# Start out with the compiler flags common to all compilers, 1147# i.e. they all use -g for opt and -g -pg for prof 1148ccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 1149 'perf' : ['-g']} 1150 1151# Start out with the linker flags common to all linkers, i.e. -pg for 1152# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 1153# no-as-needed and as-needed as the binutils linker is too clever and 1154# simply doesn't link to the library otherwise. 1155ldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 1156 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 1157 1158# For Link Time Optimization, the optimisation flags used to compile 1159# individual files are decoupled from those used at link time 1160# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 1161# to also update the linker flags based on the target. 1162if env['GCC']: 1163 if sys.platform == 'sunos5': 1164 ccflags['debug'] += ['-gstabs+'] 1165 else: 1166 ccflags['debug'] += ['-ggdb3'] 1167 ldflags['debug'] += ['-O0'] 1168 # opt, fast, prof and perf all share the same cc flags, also add 1169 # the optimization to the ldflags as LTO defers the optimization 1170 # to link time 1171 for target in ['opt', 'fast', 'prof', 'perf']: 1172 ccflags[target] += ['-O3'] 1173 ldflags[target] += ['-O3'] 1174 1175 ccflags['fast'] += env['LTO_CCFLAGS'] 1176 ldflags['fast'] += env['LTO_LDFLAGS'] 1177elif env['CLANG']: 1178 ccflags['debug'] += ['-g', '-O0'] 1179 # opt, fast, prof and perf all share the same cc flags 1180 for target in ['opt', 'fast', 'prof', 'perf']: 1181 ccflags[target] += ['-O3'] 1182else: 1183 print 'Unknown compiler, please fix compiler options' 1184 Exit(1) 1185 1186 1187# To speed things up, we only instantiate the build environments we 1188# need. We try to identify the needed environment for each target; if 1189# we can't, we fall back on instantiating all the environments just to 1190# be safe. 1191target_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 1192obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 1193 'gpo' : 'perf'} 1194 1195def identifyTarget(t): 1196 ext = t.split('.')[-1] 1197 if ext in target_types: 1198 return ext 1199 if obj2target.has_key(ext): 1200 return obj2target[ext] 1201 match = re.search(r'/tests/([^/]+)/', t) 1202 if match and match.group(1) in target_types: 1203 return match.group(1) 1204 return 'all' 1205 1206needed_envs = [identifyTarget(target) for target in BUILD_TARGETS] 1207if 'all' in needed_envs: 1208 needed_envs += target_types 1209 1210gem5_root = Dir('.').up().up().abspath 1211def makeEnvirons(target, source, env): 1212 # cause any later Source() calls to be fatal, as a diagnostic. 1213 Source.done() 1214 1215 envList = [] 1216 1217 # Debug binary 1218 if 'debug' in needed_envs: 1219 envList.append( 1220 makeEnv(env, 'debug', '.do', 1221 CCFLAGS = Split(ccflags['debug']), 1222 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 1223 LINKFLAGS = Split(ldflags['debug']))) 1224 1225 # Optimized binary 1226 if 'opt' in needed_envs: 1227 envList.append( 1228 makeEnv(env, 'opt', '.o', 1229 CCFLAGS = Split(ccflags['opt']), 1230 CPPDEFINES = ['TRACING_ON=1'], 1231 LINKFLAGS = Split(ldflags['opt']))) 1232 1233 # "Fast" binary 1234 if 'fast' in needed_envs: 1235 envList.append( 1236 makeEnv(env, 'fast', '.fo', strip = True, 1237 CCFLAGS = Split(ccflags['fast']), 1238 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1239 LINKFLAGS = Split(ldflags['fast']))) 1240 1241 # Profiled binary using gprof 1242 if 'prof' in needed_envs: 1243 envList.append( 1244 makeEnv(env, 'prof', '.po', 1245 CCFLAGS = Split(ccflags['prof']), 1246 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1247 LINKFLAGS = Split(ldflags['prof']))) 1248 1249 # Profiled binary using google-pprof 1250 if 'perf' in needed_envs: 1251 envList.append( 1252 makeEnv(env, 'perf', '.gpo', 1253 CCFLAGS = Split(ccflags['perf']), 1254 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1255 LINKFLAGS = Split(ldflags['perf']))) 1256 1257 # Set up the regression tests for each build. 1258 for e in envList: 1259 SConscript(os.path.join(gem5_root, 'tests', 'SConscript'), 1260 variant_dir = variantd('tests', e.Label), 1261 exports = { 'env' : e }, duplicate = False) 1262 1263# The MakeEnvirons Builder defers the full dependency collection until 1264# after processing the ISA definition (due to dynamically generated 1265# source files). Add this dependency to all targets so they will wait 1266# until the environments are completely set up. Otherwise, a second 1267# process (e.g. -j2 or higher) will try to compile the requested target, 1268# not know how, and fail. 1269env.Append(BUILDERS = {'MakeEnvirons' : 1270 Builder(action=MakeAction(makeEnvirons, 1271 Transform("ENVIRONS", 1)))}) 1272 1273isa_target = env['PHONY_BASE'] + '-deps' 1274environs = env['PHONY_BASE'] + '-environs' 1275env.Depends('#all-deps', isa_target) 1276env.Depends('#all-environs', environs) 1277env.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 1278envSetup = env.MakeEnvirons(environs, isa_target) 1279 1280# make sure no -deps targets occur before all ISAs are complete 1281env.Depends(isa_target, '#all-isas') 1282# likewise for -environs targets and all the -deps targets 1283env.Depends(environs, '#all-deps') 1284