SConscript revision 11974:006d830b4a4e
114153Sgiacomo.travaglini@arm.com# -*- mode:python -*- 27090SN/A 37090SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 47090SN/A# All rights reserved. 57090SN/A# 67090SN/A# Redistribution and use in source and binary forms, with or without 77090SN/A# modification, are permitted provided that the following conditions are 87090SN/A# met: redistributions of source code must retain the above copyright 97090SN/A# notice, this list of conditions and the following disclaimer; 107090SN/A# redistributions in binary form must reproduce the above copyright 117090SN/A# notice, this list of conditions and the following disclaimer in the 127090SN/A# documentation and/or other materials provided with the distribution; 134486SN/A# neither the name of the copyright holders nor the names of its 144486SN/A# contributors may be used to endorse or promote products derived from 154486SN/A# this software without specific prior written permission. 164486SN/A# 174486SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 184486SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 194486SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 204486SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 214486SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 224486SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 234486SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 244486SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 254486SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 264486SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 274486SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 284486SN/A# 294486SN/A# Authors: Nathan Binkert 304486SN/A 314486SN/Aimport array 324486SN/Aimport bisect 334486SN/Aimport imp 344486SN/Aimport marshal 354486SN/Aimport os 364486SN/Aimport re 374486SN/Aimport subprocess 384486SN/Aimport sys 397584SAli.Saidi@arm.comimport zlib 407584SAli.Saidi@arm.com 417754SWilliam.Wang@arm.comfrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 4212472Sglenn.bergmans@arm.com 434486SN/Aimport SCons 4412472Sglenn.bergmans@arm.com 453630SN/A# This file defines how to build a particular configuration of gem5 463630SN/A# based on variable settings in the 'env' build environment. 4712472Sglenn.bergmans@arm.com 4813665Sandreas.sandberg@arm.comImport('*') 4913665Sandreas.sandberg@arm.com 5013665Sandreas.sandberg@arm.com# Children need to see the environment 5113665Sandreas.sandberg@arm.comExport('env') 5213665Sandreas.sandberg@arm.com 5313665Sandreas.sandberg@arm.combuild_env = [(opt, env[opt]) for opt in export_vars] 5413665Sandreas.sandberg@arm.com 5513665Sandreas.sandberg@arm.comfrom m5.util import code_formatter, compareVersions 5613665Sandreas.sandberg@arm.com 5713665Sandreas.sandberg@arm.com######################################################################## 5813665Sandreas.sandberg@arm.com# Code for adding source files of various types 5913665Sandreas.sandberg@arm.com# 6013665Sandreas.sandberg@arm.com# When specifying a source file of some type, a set of guards can be 6113665Sandreas.sandberg@arm.com# specified for that file. When get() is used to find the files, if 6213665Sandreas.sandberg@arm.com# get specifies a set of filters, only files that match those filters 6313665Sandreas.sandberg@arm.com# will be accepted (unspecified filters on files are assumed to be 6413665Sandreas.sandberg@arm.com# false). Current filters are: 6513665Sandreas.sandberg@arm.com# main -- specifies the gem5 main() function 6613665Sandreas.sandberg@arm.com# skip_lib -- do not put this file into the gem5 library 6713665Sandreas.sandberg@arm.com# skip_no_python -- do not put this file into a no_python library 683630SN/A# as it embeds compiled Python 6911841Sandreas.sandberg@arm.com# <unittest> -- unit tests use filters based on the unit test name 7011841Sandreas.sandberg@arm.com# 7111841Sandreas.sandberg@arm.com# A parent can now be specified for a source file and default filter 7211841Sandreas.sandberg@arm.com# values will be retrieved recursively from parents (children override 7313665Sandreas.sandberg@arm.com# parents). 7411841Sandreas.sandberg@arm.com# 7511841Sandreas.sandberg@arm.comclass SourceMeta(type): 7611841Sandreas.sandberg@arm.com '''Meta class for source files that keeps track of all files of a 7711841Sandreas.sandberg@arm.com particular type and has a get function for finding all functions 7813505Sgiacomo.travaglini@arm.com of a certain type that match a set of guards''' 7911841Sandreas.sandberg@arm.com def __init__(cls, name, bases, dict): 8011841Sandreas.sandberg@arm.com super(SourceMeta, cls).__init__(name, bases, dict) 819806Sstever@gmail.com cls.all = [] 829806Sstever@gmail.com 837584SAli.Saidi@arm.com def get(cls, **guards): 849338SAndreas.Sandberg@arm.com '''Find all files that match the specified guards. If a source 857584SAli.Saidi@arm.com file does not specify a flag, the default is False''' 863898SN/A for src in cls.all: 879806Sstever@gmail.com for flag,value in guards.iteritems(): 887950SAli.Saidi@ARM.com # if the flag is found and has a different value, skip 897950SAli.Saidi@ARM.com # this file 909338SAndreas.Sandberg@arm.com if src.all_guards.get(flag, False) != value: 919525SAndreas.Sandberg@ARM.com break 927950SAli.Saidi@ARM.com else: 937950SAli.Saidi@ARM.com yield src 947950SAli.Saidi@ARM.com 957950SAli.Saidi@ARM.comclass SourceFile(object): 967587SAli.Saidi@arm.com '''Base object that encapsulates the notion of a source file. 977587SAli.Saidi@arm.com This includes, the source node, target node, various manipulations 987587SAli.Saidi@arm.com of those. A source file also specifies a set of guards which 999338SAndreas.Sandberg@arm.com describing which builds the source file applies to. A parent can 1007753SWilliam.Wang@arm.com also be specified to get default guards from''' 1017753SWilliam.Wang@arm.com __metaclass__ = SourceMeta 1029525SAndreas.Sandberg@ARM.com def __init__(self, source, parent=None, **guards): 1037753SWilliam.Wang@arm.com self.guards = guards 1047587SAli.Saidi@arm.com self.parent = parent 1057587SAli.Saidi@arm.com 1068282SAli.Saidi@ARM.com tnode = source 1078282SAli.Saidi@ARM.com if not isinstance(source, SCons.Node.FS.File): 1089338SAndreas.Sandberg@arm.com tnode = File(source) 1098282SAli.Saidi@ARM.com 11011296Sandreas.sandberg@arm.com self.tnode = tnode 11111296Sandreas.sandberg@arm.com self.snode = tnode.srcnode() 11211296Sandreas.sandberg@arm.com 11311296Sandreas.sandberg@arm.com for base in type(self).__mro__: 11411296Sandreas.sandberg@arm.com if issubclass(base, SourceFile): 11511296Sandreas.sandberg@arm.com base.all.append(self) 11611296Sandreas.sandberg@arm.com 11711296Sandreas.sandberg@arm.com @property 11811296Sandreas.sandberg@arm.com def filename(self): 11911296Sandreas.sandberg@arm.com return str(self.tnode) 12011296Sandreas.sandberg@arm.com 12111296Sandreas.sandberg@arm.com @property 12211296Sandreas.sandberg@arm.com def dirname(self): 12311296Sandreas.sandberg@arm.com return dirname(self.filename) 12413805Sgiacomo.travaglini@arm.com 12513805Sgiacomo.travaglini@arm.com @property 12613805Sgiacomo.travaglini@arm.com def basename(self): 12713805Sgiacomo.travaglini@arm.com return basename(self.filename) 12812474Sglenn.bergmans@arm.com 12914153Sgiacomo.travaglini@arm.com @property 13014153Sgiacomo.travaglini@arm.com def extname(self): 13114153Sgiacomo.travaglini@arm.com index = self.basename.rfind('.') 13212474Sglenn.bergmans@arm.com if index <= 0: 13312474Sglenn.bergmans@arm.com # dot files aren't extensions 13412474Sglenn.bergmans@arm.com return self.basename, None 13512474Sglenn.bergmans@arm.com 13612474Sglenn.bergmans@arm.com return self.basename[:index], self.basename[index+1:] 13712474Sglenn.bergmans@arm.com 13812474Sglenn.bergmans@arm.com @property 13912474Sglenn.bergmans@arm.com def all_guards(self): 14012474Sglenn.bergmans@arm.com '''find all guards for this object getting default values 14112474Sglenn.bergmans@arm.com recursively from its parents''' 14212474Sglenn.bergmans@arm.com guards = {} 14312474Sglenn.bergmans@arm.com if self.parent: 14412474Sglenn.bergmans@arm.com guards.update(self.parent.guards) 14512474Sglenn.bergmans@arm.com guards.update(self.guards) 14612474Sglenn.bergmans@arm.com return guards 14714153Sgiacomo.travaglini@arm.com 14812474Sglenn.bergmans@arm.com def __lt__(self, other): return self.filename < other.filename 14912474Sglenn.bergmans@arm.com def __le__(self, other): return self.filename <= other.filename 15012474Sglenn.bergmans@arm.com def __gt__(self, other): return self.filename > other.filename 15112474Sglenn.bergmans@arm.com def __ge__(self, other): return self.filename >= other.filename 15212474Sglenn.bergmans@arm.com def __eq__(self, other): return self.filename == other.filename 15312474Sglenn.bergmans@arm.com def __ne__(self, other): return self.filename != other.filename 15412474Sglenn.bergmans@arm.com 15512474Sglenn.bergmans@arm.com @staticmethod 15612474Sglenn.bergmans@arm.com def done(): 15712474Sglenn.bergmans@arm.com def disabled(cls, name, *ignored): 15812474Sglenn.bergmans@arm.com raise RuntimeError("Additional SourceFile '%s'" % name,\ 15912474Sglenn.bergmans@arm.com "declared, but targets deps are already fixed.") 16012474Sglenn.bergmans@arm.com SourceFile.__init__ = disabled 16112474Sglenn.bergmans@arm.com 16212474Sglenn.bergmans@arm.com 16312474Sglenn.bergmans@arm.comclass Source(SourceFile): 16412474Sglenn.bergmans@arm.com '''Add a c/c++ source file to the build''' 16512474Sglenn.bergmans@arm.com def __init__(self, source, Werror=True, swig=False, **guards): 16612474Sglenn.bergmans@arm.com '''specify the source file, and any guards''' 16712474Sglenn.bergmans@arm.com super(Source, self).__init__(source, **guards) 16812474Sglenn.bergmans@arm.com 16912474Sglenn.bergmans@arm.com self.Werror = Werror 17012474Sglenn.bergmans@arm.com self.swig = swig 17114153Sgiacomo.travaglini@arm.com 17214153Sgiacomo.travaglini@arm.comclass PySource(SourceFile): 17312474Sglenn.bergmans@arm.com '''Add a python source file to the named package''' 17412474Sglenn.bergmans@arm.com invalid_sym_char = re.compile('[^A-z0-9_]') 17514153Sgiacomo.travaglini@arm.com modules = {} 17614153Sgiacomo.travaglini@arm.com tnodes = {} 17714153Sgiacomo.travaglini@arm.com symnames = {} 17814153Sgiacomo.travaglini@arm.com 17914153Sgiacomo.travaglini@arm.com def __init__(self, package, source, **guards): 18014153Sgiacomo.travaglini@arm.com '''specify the python package, the source file, and any guards''' 18114153Sgiacomo.travaglini@arm.com super(PySource, self).__init__(source, **guards) 18212474Sglenn.bergmans@arm.com 18314153Sgiacomo.travaglini@arm.com modname,ext = self.extname 18414153Sgiacomo.travaglini@arm.com assert ext == 'py' 18514153Sgiacomo.travaglini@arm.com 18612474Sglenn.bergmans@arm.com if package: 18714153Sgiacomo.travaglini@arm.com path = package.split('.') 18814153Sgiacomo.travaglini@arm.com else: 18912474Sglenn.bergmans@arm.com path = [] 19012474Sglenn.bergmans@arm.com 19112474Sglenn.bergmans@arm.com modpath = path[:] 19212474Sglenn.bergmans@arm.com if modname != '__init__': 19312474Sglenn.bergmans@arm.com modpath += [ modname ] 19412474Sglenn.bergmans@arm.com modpath = '.'.join(modpath) 19512474Sglenn.bergmans@arm.com 19612474Sglenn.bergmans@arm.com arcpath = path + [ self.basename ] 19712474Sglenn.bergmans@arm.com abspath = self.snode.abspath 19812474Sglenn.bergmans@arm.com if not exists(abspath): 19912474Sglenn.bergmans@arm.com abspath = self.tnode.abspath 20012474Sglenn.bergmans@arm.com 20112474Sglenn.bergmans@arm.com self.package = package 20213805Sgiacomo.travaglini@arm.com self.modname = modname 20313805Sgiacomo.travaglini@arm.com self.modpath = modpath 20412474Sglenn.bergmans@arm.com self.arcname = joinpath(*arcpath) 20512474Sglenn.bergmans@arm.com self.abspath = abspath 20612474Sglenn.bergmans@arm.com self.compiled = File(self.filename + 'c') 2077584SAli.Saidi@arm.com self.cpp = File(self.filename + '.cc') 2087584SAli.Saidi@arm.com self.symname = PySource.invalid_sym_char.sub('_', modpath) 2099338SAndreas.Sandberg@arm.com 2108524SAli.Saidi@ARM.com PySource.modules[modpath] = self 2118524SAli.Saidi@ARM.com PySource.tnodes[self.tnode] = self 2128299Schander.sudanthi@arm.com PySource.symnames[self.symname] = self 2137584SAli.Saidi@arm.com 21412472Sglenn.bergmans@arm.comclass SimObject(PySource): 21512472Sglenn.bergmans@arm.com '''Add a SimObject python file as a python source object and add 21612472Sglenn.bergmans@arm.com it to a list of sim object modules''' 21712472Sglenn.bergmans@arm.com 21812472Sglenn.bergmans@arm.com fixed = False 21912472Sglenn.bergmans@arm.com modnames = [] 22012472Sglenn.bergmans@arm.com 22112472Sglenn.bergmans@arm.com def __init__(self, source, **guards): 22212472Sglenn.bergmans@arm.com '''Specify the source file and any guards (automatically in 22312472Sglenn.bergmans@arm.com the m5.objects package)''' 22412472Sglenn.bergmans@arm.com super(SimObject, self).__init__('m5.objects', source, **guards) 22512472Sglenn.bergmans@arm.com if self.fixed: 22611011SAndreas.Sandberg@ARM.com raise AttributeError, "Too late to call SimObject now." 22711011SAndreas.Sandberg@ARM.com 22811011SAndreas.Sandberg@ARM.com bisect.insort_right(SimObject.modnames, self.modname) 22911011SAndreas.Sandberg@ARM.com 23011011SAndreas.Sandberg@ARM.comclass SwigSource(SourceFile): 23111011SAndreas.Sandberg@ARM.com '''Add a swig file to build''' 23211011SAndreas.Sandberg@ARM.com 23311011SAndreas.Sandberg@ARM.com def __init__(self, package, source, **guards): 23411011SAndreas.Sandberg@ARM.com '''Specify the python package, the source file, and any guards''' 23511011SAndreas.Sandberg@ARM.com super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 23611011SAndreas.Sandberg@ARM.com 23711011SAndreas.Sandberg@ARM.com modname,ext = self.extname 23811011SAndreas.Sandberg@ARM.com assert ext == 'i' 23911011SAndreas.Sandberg@ARM.com 24011011SAndreas.Sandberg@ARM.com self.package = package 24111011SAndreas.Sandberg@ARM.com self.module = modname 24211011SAndreas.Sandberg@ARM.com cc_file = joinpath(self.dirname, modname + '_wrap.cc') 24311011SAndreas.Sandberg@ARM.com py_file = joinpath(self.dirname, modname + '.py') 24411011SAndreas.Sandberg@ARM.com 24511011SAndreas.Sandberg@ARM.com self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 24611011SAndreas.Sandberg@ARM.com self.py_source = PySource(package, py_file, parent=self, **guards) 24711011SAndreas.Sandberg@ARM.com 24812472Sglenn.bergmans@arm.comclass ProtoBuf(SourceFile): 24912472Sglenn.bergmans@arm.com '''Add a Protocol Buffer to build''' 25012472Sglenn.bergmans@arm.com 25112472Sglenn.bergmans@arm.com def __init__(self, source, **guards): 25212472Sglenn.bergmans@arm.com '''Specify the source file, and any guards''' 25312472Sglenn.bergmans@arm.com super(ProtoBuf, self).__init__(source, **guards) 25412472Sglenn.bergmans@arm.com 25512472Sglenn.bergmans@arm.com # Get the file name and the extension 25612472Sglenn.bergmans@arm.com modname,ext = self.extname 25712472Sglenn.bergmans@arm.com assert ext == 'proto' 25812472Sglenn.bergmans@arm.com 25912472Sglenn.bergmans@arm.com # Currently, we stick to generating the C++ headers, so we 26012472Sglenn.bergmans@arm.com # only need to track the source and header. 26112472Sglenn.bergmans@arm.com self.cc_file = File(modname + '.pb.cc') 26211421Sdavid.guillen@arm.com self.hh_file = File(modname + '.pb.h') 26311421Sdavid.guillen@arm.com 26411421Sdavid.guillen@arm.comclass UnitTest(object): 26511421Sdavid.guillen@arm.com '''Create a UnitTest''' 26611421Sdavid.guillen@arm.com 26711421Sdavid.guillen@arm.com all = [] 26811421Sdavid.guillen@arm.com def __init__(self, target, *sources, **kwargs): 26911421Sdavid.guillen@arm.com '''Specify the target name and any sources. Sources that are 27011421Sdavid.guillen@arm.com not SourceFiles are evalued with Source(). All files are 27111421Sdavid.guillen@arm.com guarded with a guard of the same name as the UnitTest 27211421Sdavid.guillen@arm.com target.''' 27311421Sdavid.guillen@arm.com 27411421Sdavid.guillen@arm.com srcs = [] 27511421Sdavid.guillen@arm.com for src in sources: 27611421Sdavid.guillen@arm.com if not isinstance(src, SourceFile): 27711421Sdavid.guillen@arm.com src = Source(src, skip_lib=True) 27811236Sandreas.sandberg@arm.com src.guards[target] = True 27911236Sandreas.sandberg@arm.com srcs.append(src) 28011236Sandreas.sandberg@arm.com 28111236Sandreas.sandberg@arm.com self.sources = srcs 28211236Sandreas.sandberg@arm.com self.target = target 28311236Sandreas.sandberg@arm.com self.main = kwargs.get('main', False) 28411236Sandreas.sandberg@arm.com UnitTest.all.append(self) 28511236Sandreas.sandberg@arm.com 28611236Sandreas.sandberg@arm.com# Children should have access 28711011SAndreas.Sandberg@ARM.comExport('Source') 28811011SAndreas.Sandberg@ARM.comExport('PySource') 28911421Sdavid.guillen@arm.comExport('SimObject') 29011421Sdavid.guillen@arm.comExport('SwigSource') 29111421Sdavid.guillen@arm.comExport('ProtoBuf') 29211236Sandreas.sandberg@arm.comExport('UnitTest') 29311236Sandreas.sandberg@arm.com 29411236Sandreas.sandberg@arm.com######################################################################## 29511236Sandreas.sandberg@arm.com# 29611236Sandreas.sandberg@arm.com# Debug Flags 29711421Sdavid.guillen@arm.com# 29811421Sdavid.guillen@arm.comdebug_flags = {} 29911421Sdavid.guillen@arm.comdef DebugFlag(name, desc=None): 30012472Sglenn.bergmans@arm.com if name in debug_flags: 30112472Sglenn.bergmans@arm.com raise AttributeError, "Flag %s already specified" % name 30212472Sglenn.bergmans@arm.com debug_flags[name] = (name, (), desc) 30312472Sglenn.bergmans@arm.com 30412472Sglenn.bergmans@arm.comdef CompoundFlag(name, flags, desc=None): 30512472Sglenn.bergmans@arm.com if name in debug_flags: 30612472Sglenn.bergmans@arm.com raise AttributeError, "Flag %s already specified" % name 30712472Sglenn.bergmans@arm.com 30812472Sglenn.bergmans@arm.com compound = tuple(flags) 30912472Sglenn.bergmans@arm.com debug_flags[name] = (name, compound, desc) 31012472Sglenn.bergmans@arm.com 31112472Sglenn.bergmans@arm.comExport('DebugFlag') 31212472Sglenn.bergmans@arm.comExport('CompoundFlag') 31312472Sglenn.bergmans@arm.com 31411236Sandreas.sandberg@arm.com######################################################################## 31511236Sandreas.sandberg@arm.com# 31611236Sandreas.sandberg@arm.com# Set some compiler variables 31711236Sandreas.sandberg@arm.com# 31811236Sandreas.sandberg@arm.com 31911236Sandreas.sandberg@arm.com# Include file paths are rooted in this directory. SCons will 32011236Sandreas.sandberg@arm.com# automatically expand '.' to refer to both the source directory and 32111236Sandreas.sandberg@arm.com# the corresponding build directory to pick up generated include 32211236Sandreas.sandberg@arm.com# files. 32311011SAndreas.Sandberg@ARM.comenv.Append(CPPPATH=Dir('.')) 32411011SAndreas.Sandberg@ARM.com 32511236Sandreas.sandberg@arm.comfor extra_dir in extras_dir_list: 32611236Sandreas.sandberg@arm.com env.Append(CPPPATH=Dir(extra_dir)) 32711236Sandreas.sandberg@arm.com 32811236Sandreas.sandberg@arm.com# Workaround for bug in SCons version > 0.97d20071212 32911236Sandreas.sandberg@arm.com# Scons bug id: 2006 gem5 Bug id: 308 33011236Sandreas.sandberg@arm.comfor root, dirs, files in os.walk(base_dir, topdown=True): 33111236Sandreas.sandberg@arm.com Dir(root[len(base_dir) + 1:]) 33211011SAndreas.Sandberg@ARM.com 33312472Sglenn.bergmans@arm.com######################################################################## 33412472Sglenn.bergmans@arm.com# 33512472Sglenn.bergmans@arm.com# Walk the tree and execute all SConscripts in subdirectories 33612472Sglenn.bergmans@arm.com# 33712472Sglenn.bergmans@arm.com 33812472Sglenn.bergmans@arm.comhere = Dir('.').srcnode().abspath 33912472Sglenn.bergmans@arm.comfor root, dirs, files in os.walk(base_dir, topdown=True): 34012472Sglenn.bergmans@arm.com if root == here: 34112472Sglenn.bergmans@arm.com # we don't want to recurse back into this SConscript 34212472Sglenn.bergmans@arm.com continue 34312472Sglenn.bergmans@arm.com 34412472Sglenn.bergmans@arm.com if 'SConscript' in files: 34512472Sglenn.bergmans@arm.com build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 3469806Sstever@gmail.com SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3477584SAli.Saidi@arm.com 3489338SAndreas.Sandberg@arm.comfor extra_dir in extras_dir_list: 3497584SAli.Saidi@arm.com prefix_len = len(dirname(extra_dir)) + 1 3507584SAli.Saidi@arm.com 3517584SAli.Saidi@arm.com # Also add the corresponding build directory to pick up generated 3527584SAli.Saidi@arm.com # include files. 3537584SAli.Saidi@arm.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 3549338SAndreas.Sandberg@arm.com 3559525SAndreas.Sandberg@ARM.com for root, dirs, files in os.walk(extra_dir, topdown=True): 3567584SAli.Saidi@arm.com # if build lives in the extras directory, don't walk down it 3577584SAli.Saidi@arm.com if 'build' in dirs: 3587584SAli.Saidi@arm.com dirs.remove('build') 3597584SAli.Saidi@arm.com 36012472Sglenn.bergmans@arm.com if 'SConscript' in files: 36112472Sglenn.bergmans@arm.com build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 36212472Sglenn.bergmans@arm.com SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 36312472Sglenn.bergmans@arm.com 36412472Sglenn.bergmans@arm.comfor opt in export_vars: 36512472Sglenn.bergmans@arm.com env.ConfigFile(opt) 36612472Sglenn.bergmans@arm.com 36712472Sglenn.bergmans@arm.comdef makeTheISA(source, target, env): 36812472Sglenn.bergmans@arm.com isas = [ src.get_contents() for src in source ] 36912472Sglenn.bergmans@arm.com target_isa = env['TARGET_ISA'] 37012472Sglenn.bergmans@arm.com def define(isa): 37112472Sglenn.bergmans@arm.com return isa.upper() + '_ISA' 37212472Sglenn.bergmans@arm.com 37312472Sglenn.bergmans@arm.com def namespace(isa): 3749806Sstever@gmail.com return isa[0].upper() + isa[1:].lower() + 'ISA' 3757584SAli.Saidi@arm.com 3769338SAndreas.Sandberg@arm.com 3779525SAndreas.Sandberg@ARM.com code = code_formatter() 3787584SAli.Saidi@arm.com code('''\ 3797584SAli.Saidi@arm.com#ifndef __CONFIG_THE_ISA_HH__ 3807584SAli.Saidi@arm.com#define __CONFIG_THE_ISA_HH__ 3817584SAli.Saidi@arm.com 3827584SAli.Saidi@arm.com''') 3837584SAli.Saidi@arm.com 38412077Sgedare@rtems.org # create defines for the preprocessing and compile-time determination 38512077Sgedare@rtems.org for i,isa in enumerate(isas): 38612077Sgedare@rtems.org code('#define $0 $1', define(isa), i + 1) 38712077Sgedare@rtems.org code() 38812077Sgedare@rtems.org 38912077Sgedare@rtems.org # create an enum for any run-time determination of the ISA, we 3908512Sgeoffrey.blake@arm.com # reuse the same name as the namespaces 3918512Sgeoffrey.blake@arm.com code('enum class Arch {') 3929338SAndreas.Sandberg@arm.com for i,isa in enumerate(isas): 39313106Sgiacomo.travaglini@arm.com if i + 1 == len(isas): 39413106Sgiacomo.travaglini@arm.com code(' $0 = $1', namespace(isa), define(isa)) 3958512Sgeoffrey.blake@arm.com else: 39612467SCurtis.Dunham@arm.com code(' $0 = $1,', namespace(isa), define(isa)) 39710037SARM gem5 Developers code('};') 39810037SARM gem5 Developers 39911668Sandreas.sandberg@arm.com code(''' 40012975Sgiacomo.travaglini@arm.com 40112975Sgiacomo.travaglini@arm.com#define THE_ISA ${{define(target_isa)}} 40212975Sgiacomo.travaglini@arm.com#define TheISA ${{namespace(target_isa)}} 40312975Sgiacomo.travaglini@arm.com#define THE_ISA_STR "${{target_isa}}" 40410037SARM gem5 Developers 40512472Sglenn.bergmans@arm.com#endif // __CONFIG_THE_ISA_HH__''') 40612472Sglenn.bergmans@arm.com 40712472Sglenn.bergmans@arm.com code.write(str(target[0])) 40812472Sglenn.bergmans@arm.com 40912472Sglenn.bergmans@arm.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 41012472Sglenn.bergmans@arm.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 41112733Sandreas.sandberg@arm.com 41212975Sgiacomo.travaglini@arm.comdef makeTheGPUISA(source, target, env): 41312975Sgiacomo.travaglini@arm.com isas = [ src.get_contents() for src in source ] 41412975Sgiacomo.travaglini@arm.com target_gpu_isa = env['TARGET_GPU_ISA'] 41512975Sgiacomo.travaglini@arm.com def define(isa): 41612733Sandreas.sandberg@arm.com return isa.upper() + '_ISA' 41712472Sglenn.bergmans@arm.com 41812472Sglenn.bergmans@arm.com def namespace(isa): 41912472Sglenn.bergmans@arm.com return isa[0].upper() + isa[1:].lower() + 'ISA' 42012472Sglenn.bergmans@arm.com 42112472Sglenn.bergmans@arm.com 42210847Sandreas.sandberg@arm.com code = code_formatter() 42310847Sandreas.sandberg@arm.com code('''\ 42410847Sandreas.sandberg@arm.com#ifndef __CONFIG_THE_GPU_ISA_HH__ 42510847Sandreas.sandberg@arm.com#define __CONFIG_THE_GPU_ISA_HH__ 42610847Sandreas.sandberg@arm.com 42710847Sandreas.sandberg@arm.com''') 42812975Sgiacomo.travaglini@arm.com 42912975Sgiacomo.travaglini@arm.com # create defines for the preprocessing and compile-time determination 43010847Sandreas.sandberg@arm.com for i,isa in enumerate(isas): 4318870SAli.Saidi@ARM.com code('#define $0 $1', define(isa), i + 1) 4328870SAli.Saidi@ARM.com code() 4339338SAndreas.Sandberg@arm.com 4348870SAli.Saidi@ARM.com # create an enum for any run-time determination of the ISA, we 4358870SAli.Saidi@ARM.com # reuse the same name as the namespaces 4368870SAli.Saidi@ARM.com code('enum class GPUArch {') 43712472Sglenn.bergmans@arm.com for i,isa in enumerate(isas): 43812472Sglenn.bergmans@arm.com if i + 1 == len(isas): 43912472Sglenn.bergmans@arm.com code(' $0 = $1', namespace(isa), define(isa)) 44012472Sglenn.bergmans@arm.com else: 44112472Sglenn.bergmans@arm.com code(' $0 = $1,', namespace(isa), define(isa)) 44212472Sglenn.bergmans@arm.com code('};') 44312472Sglenn.bergmans@arm.com 44412472Sglenn.bergmans@arm.com code(''' 44512472Sglenn.bergmans@arm.com 44612472Sglenn.bergmans@arm.com#define THE_GPU_ISA ${{define(target_gpu_isa)}} 4477950SAli.Saidi@ARM.com#define TheGpuISA ${{namespace(target_gpu_isa)}} 4487754SWilliam.Wang@arm.com#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 4499338SAndreas.Sandberg@arm.com 4507754SWilliam.Wang@arm.com#endif // __CONFIG_THE_GPU_ISA_HH__''') 4517754SWilliam.Wang@arm.com 45212659Sandreas.sandberg@arm.com code.write(str(target[0])) 45312659Sandreas.sandberg@arm.com 45412472Sglenn.bergmans@arm.comenv.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 45512472Sglenn.bergmans@arm.com MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 45612472Sglenn.bergmans@arm.com 45712472Sglenn.bergmans@arm.com######################################################################## 45812472Sglenn.bergmans@arm.com# 45912472Sglenn.bergmans@arm.com# Prevent any SimObjects from being added after this point, they 46012472Sglenn.bergmans@arm.com# should all have been added in the SConscripts above 46112472Sglenn.bergmans@arm.com# 46212472Sglenn.bergmans@arm.comSimObject.fixed = True 46312472Sglenn.bergmans@arm.com 4647753SWilliam.Wang@arm.comclass DictImporter(object): 4657753SWilliam.Wang@arm.com '''This importer takes a dictionary of arbitrary module names that 4669338SAndreas.Sandberg@arm.com map to arbitrary filenames.''' 4679394Sandreas.hansson@arm.com def __init__(self, modules): 4689330Schander.sudanthi@arm.com self.modules = modules 4697753SWilliam.Wang@arm.com self.installed = set() 4709939Sdam.sunwoo@arm.com 4719939Sdam.sunwoo@arm.com def __del__(self): 4729646SChris.Emmons@arm.com self.unload() 4739646SChris.Emmons@arm.com 4749646SChris.Emmons@arm.com def unload(self): 4759646SChris.Emmons@arm.com import sys 4769646SChris.Emmons@arm.com for module in self.installed: 4779646SChris.Emmons@arm.com del sys.modules[module] 47811237Sandreas.sandberg@arm.com self.installed = set() 47910840Sandreas.sandberg@arm.com 48011090Sandreas.sandberg@arm.com def find_module(self, fullname, path): 48111090Sandreas.sandberg@arm.com if fullname == 'm5.defines': 48212232Sgiacomo.travaglini@arm.com return self 48312232Sgiacomo.travaglini@arm.com 48412232Sgiacomo.travaglini@arm.com if fullname == 'm5.objects': 48512232Sgiacomo.travaglini@arm.com return self 4869646SChris.Emmons@arm.com 48711090Sandreas.sandberg@arm.com if fullname.startswith('_m5'): 48811090Sandreas.sandberg@arm.com return None 48911090Sandreas.sandberg@arm.com 49011090Sandreas.sandberg@arm.com source = self.modules.get(fullname, None) 49111898Ssudhanshu.jha@arm.com if source is not None and fullname.startswith('m5.objects'): 49211898Ssudhanshu.jha@arm.com return self 49311090Sandreas.sandberg@arm.com 49412472Sglenn.bergmans@arm.com return None 49512472Sglenn.bergmans@arm.com 49612472Sglenn.bergmans@arm.com def load_module(self, fullname): 49712472Sglenn.bergmans@arm.com mod = imp.new_module(fullname) 49812472Sglenn.bergmans@arm.com sys.modules[fullname] = mod 49912472Sglenn.bergmans@arm.com self.installed.add(fullname) 50012472Sglenn.bergmans@arm.com 50112472Sglenn.bergmans@arm.com mod.__loader__ = self 50212472Sglenn.bergmans@arm.com if fullname == 'm5.objects': 50312472Sglenn.bergmans@arm.com mod.__path__ = fullname.split('.') 50412472Sglenn.bergmans@arm.com return mod 50512472Sglenn.bergmans@arm.com 50612472Sglenn.bergmans@arm.com if fullname == 'm5.defines': 50712472Sglenn.bergmans@arm.com mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 50812472Sglenn.bergmans@arm.com return mod 50912472Sglenn.bergmans@arm.com 51012472Sglenn.bergmans@arm.com source = self.modules[fullname] 5117584SAli.Saidi@arm.com if source.modname == '__init__': 5127584SAli.Saidi@arm.com mod.__path__ = source.modpath 5139338SAndreas.Sandberg@arm.com mod.__file__ = source.abspath 5143630SN/A 51513636Sgiacomo.travaglini@arm.com exec file(source.abspath, 'r') in mod.__dict__ 5168870SAli.Saidi@ARM.com 51711297Sandreas.sandberg@arm.com return mod 51811297Sandreas.sandberg@arm.com 51911297Sandreas.sandberg@arm.comimport m5.SimObject 52011297Sandreas.sandberg@arm.comimport m5.params 52111297Sandreas.sandberg@arm.comfrom m5.util import code_formatter 52211297Sandreas.sandberg@arm.com 52311297Sandreas.sandberg@arm.comm5.SimObject.clear() 52411297Sandreas.sandberg@arm.comm5.params.clear() 52511597Sandreas.sandberg@arm.com 52611597Sandreas.sandberg@arm.com# install the python importer so we can grab stuff from the source 52711597Sandreas.sandberg@arm.com# tree itself. We can't have SimObjects added after this point or 52811597Sandreas.sandberg@arm.com# else we won't know about them for the rest of the stuff. 52911597Sandreas.sandberg@arm.comimporter = DictImporter(PySource.modules) 53011597Sandreas.sandberg@arm.comsys.meta_path[0:0] = [ importer ] 53111597Sandreas.sandberg@arm.com 53211597Sandreas.sandberg@arm.com# import all sim objects so we can populate the all_objects list 53311597Sandreas.sandberg@arm.com# make sure that we're working with a list, then let's sort it 53411597Sandreas.sandberg@arm.comfor modname in SimObject.modnames: 53511297Sandreas.sandberg@arm.com exec('from m5.objects import %s' % modname) 53611597Sandreas.sandberg@arm.com 53711297Sandreas.sandberg@arm.com# we need to unload all of the currently imported modules so that they 53811297Sandreas.sandberg@arm.com# will be re-imported the next time the sconscript is run 53911297Sandreas.sandberg@arm.comimporter.unload() 54011297Sandreas.sandberg@arm.comsys.meta_path.remove(importer) 54111297Sandreas.sandberg@arm.com 54211297Sandreas.sandberg@arm.comsim_objects = m5.SimObject.allClasses 54310353SGeoffrey.Blake@arm.comall_enums = m5.params.allEnums 54410353SGeoffrey.Blake@arm.com 54510353SGeoffrey.Blake@arm.comif m5.SimObject.noCxxHeader: 54610353SGeoffrey.Blake@arm.com print >> sys.stderr, \ 54710353SGeoffrey.Blake@arm.com "warning: At least one SimObject lacks a header specification. " \ 54810353SGeoffrey.Blake@arm.com "This can cause unexpected results in the generated SWIG " \ 54910353SGeoffrey.Blake@arm.com "wrappers." 55011297Sandreas.sandberg@arm.com 55110353SGeoffrey.Blake@arm.com# Find param types that need to be explicitly wrapped with swig. 55210353SGeoffrey.Blake@arm.com# These will be recognized because the ParamDesc will have a 55311297Sandreas.sandberg@arm.com# swig_decl() method. Most param types are based on types that don't 55411297Sandreas.sandberg@arm.com# need this, either because they're based on native types (like Int) 55512069Snikos.nikoleris@arm.com# or because they're SimObjects (which get swigged independently). 55612069Snikos.nikoleris@arm.com# For now the only things handled here are VectorParam types. 55711297Sandreas.sandberg@arm.comparams_to_swig = {} 55811297Sandreas.sandberg@arm.comfor name,obj in sorted(sim_objects.iteritems()): 55911297Sandreas.sandberg@arm.com for param in obj._params.local.values(): 56011597Sandreas.sandberg@arm.com # load the ptype attribute now because it depends on the 56111597Sandreas.sandberg@arm.com # current version of SimObject.allClasses, but when scons 56211297Sandreas.sandberg@arm.com # actually uses the value, all versions of 5638870SAli.Saidi@ARM.com # SimObject.allClasses will have been loaded 56412598Snikos.nikoleris@arm.com param.ptype 56512598Snikos.nikoleris@arm.com 56612598Snikos.nikoleris@arm.com if not hasattr(param, 'swig_decl'): 56712598Snikos.nikoleris@arm.com continue 56812598Snikos.nikoleris@arm.com pname = param.ptype_str 5698870SAli.Saidi@ARM.com if pname not in params_to_swig: 57010037SARM gem5 Developers params_to_swig[pname] = param 57110037SARM gem5 Developers 5728870SAli.Saidi@ARM.com######################################################################## 57312472Sglenn.bergmans@arm.com# 57412472Sglenn.bergmans@arm.com# calculate extra dependencies 57512472Sglenn.bergmans@arm.com# 57612472Sglenn.bergmans@arm.commodule_depends = ["m5", "m5.SimObject", "m5.params"] 57712472Sglenn.bergmans@arm.comdepends = [ PySource.modules[dep].snode for dep in module_depends ] 57812785Sandreas.sandberg@arm.comdepends.sort(key = lambda x: x.name) 57912785Sandreas.sandberg@arm.com 58012472Sglenn.bergmans@arm.com######################################################################## 58112472Sglenn.bergmans@arm.com# 58212472Sglenn.bergmans@arm.com# Commands for the basic automatically generated python files 58312472Sglenn.bergmans@arm.com# 58412472Sglenn.bergmans@arm.com 58512472Sglenn.bergmans@arm.com# Generate Python file containing a dict specifying the current 58612472Sglenn.bergmans@arm.com# buildEnv flags. 5873630SN/Adef makeDefinesPyFile(target, source, env): 5887753SWilliam.Wang@arm.com build_env = source[0].get_contents() 5897753SWilliam.Wang@arm.com 5907753SWilliam.Wang@arm.com code = code_formatter() 5917584SAli.Saidi@arm.com code(""" 5927584SAli.Saidi@arm.comimport _m5.core 59311236Sandreas.sandberg@arm.comimport m5.util 59411236Sandreas.sandberg@arm.com 59511236Sandreas.sandberg@arm.combuildEnv = m5.util.SmartDict($build_env) 59613505Sgiacomo.travaglini@arm.com 59711244Sandreas.sandberg@arm.comcompileDate = _m5.core.compileDate 59811244Sandreas.sandberg@arm.com_globals = globals() 59911244Sandreas.sandberg@arm.comfor key,val in _m5.core.__dict__.iteritems(): 6007584SAli.Saidi@arm.com if key.startswith('flag_'): 6017584SAli.Saidi@arm.com flag = key[5:] 60212077Sgedare@rtems.org _globals[flag] = val 60313106Sgiacomo.travaglini@arm.comdel _globals 60413106Sgiacomo.travaglini@arm.com""") 60512077Sgedare@rtems.org code.write(target[0].abspath) 6067753SWilliam.Wang@arm.com 60712659Sandreas.sandberg@arm.comdefines_info = Value(build_env) 60812659Sandreas.sandberg@arm.com# Generate a file with all of the compile options in it 6098282SAli.Saidi@ARM.comenv.Command('python/m5/defines.py', defines_info, 6108525SAli.Saidi@ARM.com MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 6118212SAli.Saidi@ARM.comPySource('m5', 'python/m5/defines.py') 6128212SAli.Saidi@ARM.com 6138212SAli.Saidi@ARM.com# Generate python file containing info about the M5 source code 6148212SAli.Saidi@ARM.comdef makeInfoPyFile(target, source, env): 6158212SAli.Saidi@ARM.com code = code_formatter() 6167584SAli.Saidi@arm.com for src in source: 6177731SAli.Saidi@ARM.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 6188461SAli.Saidi@ARM.com code('$src = ${{repr(data)}}') 6198461SAli.Saidi@ARM.com code.write(str(target[0])) 6207696SAli.Saidi@ARM.com 6217696SAli.Saidi@ARM.com# Generate a file that wraps the basic top level files 6227696SAli.Saidi@ARM.comenv.Command('python/m5/info.py', 6237696SAli.Saidi@ARM.com [ '#/COPYING', '#/LICENSE', '#/README', ], 6247696SAli.Saidi@ARM.com MakeAction(makeInfoPyFile, Transform("INFO"))) 6257696SAli.Saidi@ARM.comPySource('m5', 'python/m5/info.py') 6267696SAli.Saidi@ARM.com 6277696SAli.Saidi@ARM.com######################################################################## 6287696SAli.Saidi@ARM.com# 6297696SAli.Saidi@ARM.com# Create all of the SimObject param headers and enum headers 6307696SAli.Saidi@ARM.com# 6317696SAli.Saidi@ARM.com 6327696SAli.Saidi@ARM.comdef createSimObjectParamStruct(target, source, env): 6337696SAli.Saidi@ARM.com assert len(target) == 1 and len(source) == 1 6348906Skoansin.tan@gmail.com 63510397Sstephan.diestelhorst@arm.com name = str(source[0].get_contents()) 6367696SAli.Saidi@ARM.com obj = sim_objects[name] 6377696SAli.Saidi@ARM.com 6388713Sandreas.hansson@arm.com code = code_formatter() 6398713Sandreas.hansson@arm.com obj.cxx_param_decl(code) 6408713Sandreas.hansson@arm.com code.write(target[0].abspath) 6418839Sandreas.hansson@arm.com 6428839Sandreas.hansson@arm.comdef createSimObjectCxxConfig(is_header): 6438839Sandreas.hansson@arm.com def body(target, source, env): 64412077Sgedare@rtems.org assert len(target) == 1 and len(source) == 1 6458839Sandreas.hansson@arm.com 6468713Sandreas.hansson@arm.com name = str(source[0].get_contents()) 6478713Sandreas.hansson@arm.com obj = sim_objects[name] 6488713Sandreas.hansson@arm.com 6498713Sandreas.hansson@arm.com code = code_formatter() 6508870SAli.Saidi@ARM.com obj.cxx_config_param_file(code, is_header) 6518870SAli.Saidi@ARM.com code.write(target[0].abspath) 6528870SAli.Saidi@ARM.com return body 6537696SAli.Saidi@ARM.com 65410353SGeoffrey.Blake@arm.comdef createParamSwigWrapper(target, source, env): 65510353SGeoffrey.Blake@arm.com assert len(target) == 1 and len(source) == 1 65610353SGeoffrey.Blake@arm.com 65710353SGeoffrey.Blake@arm.com name = str(source[0].get_contents()) 65810353SGeoffrey.Blake@arm.com param = params_to_swig[name] 65910353SGeoffrey.Blake@arm.com 66010353SGeoffrey.Blake@arm.com code = code_formatter() 66110353SGeoffrey.Blake@arm.com param.swig_decl(code) 6627696SAli.Saidi@ARM.com code.write(target[0].abspath) 6637696SAli.Saidi@ARM.com 6647696SAli.Saidi@ARM.comdef createEnumStrings(target, source, env): 6657696SAli.Saidi@ARM.com assert len(target) == 1 and len(source) == 1 6668839Sandreas.hansson@arm.com 6678839Sandreas.hansson@arm.com name = str(source[0].get_contents()) 66811244Sandreas.sandberg@arm.com obj = all_enums[name] 6698839Sandreas.hansson@arm.com 6708839Sandreas.hansson@arm.com code = code_formatter() 6718839Sandreas.hansson@arm.com obj.cxx_def(code) 6728839Sandreas.hansson@arm.com code.write(target[0].abspath) 6738839Sandreas.hansson@arm.com 6748839Sandreas.hansson@arm.comdef createEnumDecls(target, source, env): 6758839Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 6768839Sandreas.hansson@arm.com 6778839Sandreas.hansson@arm.com name = str(source[0].get_contents()) 6788839Sandreas.hansson@arm.com obj = all_enums[name] 6798839Sandreas.hansson@arm.com 6808839Sandreas.hansson@arm.com code = code_formatter() 6818839Sandreas.hansson@arm.com obj.cxx_decl(code) 6828839Sandreas.hansson@arm.com code.write(target[0].abspath) 6838839Sandreas.hansson@arm.com 6848839Sandreas.hansson@arm.comdef createEnumSwigWrapper(target, source, env): 6858839Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 6868839Sandreas.hansson@arm.com 6878839Sandreas.hansson@arm.com name = str(source[0].get_contents()) 6888839Sandreas.hansson@arm.com obj = all_enums[name] 6898839Sandreas.hansson@arm.com 6908839Sandreas.hansson@arm.com code = code_formatter() 6918906Skoansin.tan@gmail.com obj.swig_decl(code) 6928839Sandreas.hansson@arm.com code.write(target[0].abspath) 69310397Sstephan.diestelhorst@arm.com 6947696SAli.Saidi@ARM.comdef createSimObjectSwigWrapper(target, source, env): 69510353SGeoffrey.Blake@arm.com name = source[0].get_contents() 69610353SGeoffrey.Blake@arm.com obj = sim_objects[name] 69710353SGeoffrey.Blake@arm.com 69810353SGeoffrey.Blake@arm.com code = code_formatter() 69910353SGeoffrey.Blake@arm.com obj.swig_decl(code) 70010353SGeoffrey.Blake@arm.com code.write(target[0].abspath) 70110353SGeoffrey.Blake@arm.com 70210353SGeoffrey.Blake@arm.com# dummy target for generated code 70310353SGeoffrey.Blake@arm.com# we start out with all the Source files so they get copied to build/*/ also. 70410353SGeoffrey.Blake@arm.comSWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 70510353SGeoffrey.Blake@arm.com 70610353SGeoffrey.Blake@arm.com# Generate all of the SimObject param C++ struct header files 70710353SGeoffrey.Blake@arm.comparams_hh_files = [] 70810353SGeoffrey.Blake@arm.comfor name,simobj in sorted(sim_objects.iteritems()): 70910353SGeoffrey.Blake@arm.com py_source = PySource.modules[simobj.__module__] 71010353SGeoffrey.Blake@arm.com extra_deps = [ py_source.tnode ] 71110353SGeoffrey.Blake@arm.com 71210353SGeoffrey.Blake@arm.com hh_file = File('params/%s.hh' % name) 71310353SGeoffrey.Blake@arm.com params_hh_files.append(hh_file) 71410353SGeoffrey.Blake@arm.com env.Command(hh_file, Value(name), 71510353SGeoffrey.Blake@arm.com MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 71610353SGeoffrey.Blake@arm.com env.Depends(hh_file, depends + extra_deps) 71710353SGeoffrey.Blake@arm.com env.Depends(SWIG, hh_file) 71810353SGeoffrey.Blake@arm.com 71910353SGeoffrey.Blake@arm.com# C++ parameter description files 72010353SGeoffrey.Blake@arm.comif GetOption('with_cxx_config'): 72110353SGeoffrey.Blake@arm.com for name,simobj in sorted(sim_objects.iteritems()): 72210397Sstephan.diestelhorst@arm.com py_source = PySource.modules[simobj.__module__] 72310353SGeoffrey.Blake@arm.com extra_deps = [ py_source.tnode ] 7248870SAli.Saidi@ARM.com 72513636Sgiacomo.travaglini@arm.com cxx_config_hh_file = File('cxx_config/%s.hh' % name) 72612069Snikos.nikoleris@arm.com cxx_config_cc_file = File('cxx_config/%s.cc' % name) 72712069Snikos.nikoleris@arm.com env.Command(cxx_config_hh_file, Value(name), 72812069Snikos.nikoleris@arm.com MakeAction(createSimObjectCxxConfig(True), 72912069Snikos.nikoleris@arm.com Transform("CXXCPRHH"))) 73012069Snikos.nikoleris@arm.com env.Command(cxx_config_cc_file, Value(name), 73112069Snikos.nikoleris@arm.com MakeAction(createSimObjectCxxConfig(False), 73212069Snikos.nikoleris@arm.com Transform("CXXCPRCC"))) 73312069Snikos.nikoleris@arm.com env.Depends(cxx_config_hh_file, depends + extra_deps + 73412069Snikos.nikoleris@arm.com [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 73512069Snikos.nikoleris@arm.com env.Depends(cxx_config_cc_file, depends + extra_deps + 73612069Snikos.nikoleris@arm.com [cxx_config_hh_file]) 73712069Snikos.nikoleris@arm.com Source(cxx_config_cc_file) 73812069Snikos.nikoleris@arm.com 73911236Sandreas.sandberg@arm.com cxx_config_init_cc_file = File('cxx_config/init.cc') 74011236Sandreas.sandberg@arm.com 74112069Snikos.nikoleris@arm.com def createCxxConfigInitCC(target, source, env): 74212069Snikos.nikoleris@arm.com assert len(target) == 1 and len(source) == 1 74313505Sgiacomo.travaglini@arm.com 74413814Sgiacomo.travaglini@arm.com code = code_formatter() 74512069Snikos.nikoleris@arm.com 74613106Sgiacomo.travaglini@arm.com for name,simobj in sorted(sim_objects.iteritems()): 74713106Sgiacomo.travaglini@arm.com if not hasattr(simobj, 'abstract') or not simobj.abstract: 74812069Snikos.nikoleris@arm.com code('#include "cxx_config/${name}.hh"') 74912069Snikos.nikoleris@arm.com code() 75012069Snikos.nikoleris@arm.com code('void cxxConfigInit()') 75112069Snikos.nikoleris@arm.com code('{') 75212069Snikos.nikoleris@arm.com code.indent() 75312069Snikos.nikoleris@arm.com for name,simobj in sorted(sim_objects.iteritems()): 75412069Snikos.nikoleris@arm.com not_abstract = not hasattr(simobj, 'abstract') or \ 75512069Snikos.nikoleris@arm.com not simobj.abstract 75612069Snikos.nikoleris@arm.com if not_abstract and 'type' in simobj.__dict__: 75712069Snikos.nikoleris@arm.com code('cxx_config_directory["${name}"] = ' 75812069Snikos.nikoleris@arm.com '${name}CxxConfigParams::makeDirectoryEntry();') 75912069Snikos.nikoleris@arm.com code.dedent() 76012069Snikos.nikoleris@arm.com code('}') 76112069Snikos.nikoleris@arm.com code.write(target[0].abspath) 76212069Snikos.nikoleris@arm.com 76312069Snikos.nikoleris@arm.com py_source = PySource.modules[simobj.__module__] 76412069Snikos.nikoleris@arm.com extra_deps = [ py_source.tnode ] 76512069Snikos.nikoleris@arm.com env.Command(cxx_config_init_cc_file, Value(name), 76611244Sandreas.sandberg@arm.com MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 76711244Sandreas.sandberg@arm.com cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 76811244Sandreas.sandberg@arm.com for name,simobj in sorted(sim_objects.iteritems()) 76912069Snikos.nikoleris@arm.com if not hasattr(simobj, 'abstract') or not simobj.abstract] 77012975Sgiacomo.travaglini@arm.com Depends(cxx_config_init_cc_file, cxx_param_hh_files + 77112975Sgiacomo.travaglini@arm.com [File('sim/cxx_config.hh')]) 77212975Sgiacomo.travaglini@arm.com Source(cxx_config_init_cc_file) 77312975Sgiacomo.travaglini@arm.com 77412975Sgiacomo.travaglini@arm.com# Generate any needed param SWIG wrapper files 7759185SAli.Saidi@ARM.comparams_i_files = [] 7769185SAli.Saidi@ARM.comfor name,param in sorted(params_to_swig.iteritems()): 7778870SAli.Saidi@ARM.com i_file = File('python/_m5/%s.i' % (param.swig_module_name())) 77812659Sandreas.sandberg@arm.com params_i_files.append(i_file) 77912659Sandreas.sandberg@arm.com env.Command(i_file, Value(name), 7808870SAli.Saidi@ARM.com MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 7818870SAli.Saidi@ARM.com env.Depends(i_file, depends) 7828870SAli.Saidi@ARM.com env.Depends(SWIG, i_file) 7838870SAli.Saidi@ARM.com SwigSource('_m5', i_file) 7848870SAli.Saidi@ARM.com 7859052Sgeoffrey.blake@arm.com# Generate all enum header files 7869835Sandreas.hansson@arm.comfor name,enum in sorted(all_enums.iteritems()): 7879835Sandreas.hansson@arm.com py_source = PySource.modules[enum.__module__] 7888870SAli.Saidi@ARM.com extra_deps = [ py_source.tnode ] 7898870SAli.Saidi@ARM.com 7908870SAli.Saidi@ARM.com cc_file = File('enums/%s.cc' % name) 7918870SAli.Saidi@ARM.com env.Command(cc_file, Value(name), 7928870SAli.Saidi@ARM.com MakeAction(createEnumStrings, Transform("ENUM STR"))) 7938870SAli.Saidi@ARM.com env.Depends(cc_file, depends + extra_deps) 7948870SAli.Saidi@ARM.com env.Depends(SWIG, cc_file) 7958870SAli.Saidi@ARM.com Source(cc_file) 7968870SAli.Saidi@ARM.com 7978870SAli.Saidi@ARM.com hh_file = File('enums/%s.hh' % name) 7988870SAli.Saidi@ARM.com env.Command(hh_file, Value(name), 7998870SAli.Saidi@ARM.com MakeAction(createEnumDecls, Transform("ENUMDECL"))) 80010397Sstephan.diestelhorst@arm.com env.Depends(hh_file, depends + extra_deps) 8018870SAli.Saidi@ARM.com env.Depends(SWIG, hh_file) 80212069Snikos.nikoleris@arm.com 80312069Snikos.nikoleris@arm.com i_file = File('python/_m5/enum_%s.i' % name) 80412069Snikos.nikoleris@arm.com env.Command(i_file, Value(name), 80512069Snikos.nikoleris@arm.com MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 80612069Snikos.nikoleris@arm.com env.Depends(i_file, depends + extra_deps) 80712069Snikos.nikoleris@arm.com env.Depends(SWIG, i_file) 80812069Snikos.nikoleris@arm.com SwigSource('_m5', i_file) 80912069Snikos.nikoleris@arm.com 81012069Snikos.nikoleris@arm.com# Generate SimObject SWIG wrapper files 81112069Snikos.nikoleris@arm.comfor name,simobj in sorted(sim_objects.iteritems()): 81212069Snikos.nikoleris@arm.com py_source = PySource.modules[simobj.__module__] 81312069Snikos.nikoleris@arm.com extra_deps = [ py_source.tnode ] 81412069Snikos.nikoleris@arm.com i_file = File('python/_m5/param_%s.i' % name) 81512069Snikos.nikoleris@arm.com env.Command(i_file, Value(name), 81612069Snikos.nikoleris@arm.com MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 81712069Snikos.nikoleris@arm.com env.Depends(i_file, depends + extra_deps) 81812069Snikos.nikoleris@arm.com SwigSource('_m5', i_file) 81912069Snikos.nikoleris@arm.com 82012069Snikos.nikoleris@arm.com# Generate the main swig init file 82112069Snikos.nikoleris@arm.comdef makeEmbeddedSwigInit(package): 82212069Snikos.nikoleris@arm.com def body(target, source, env): 82312069Snikos.nikoleris@arm.com assert len(target) == 1 and len(source) == 1 82412069Snikos.nikoleris@arm.com 82512069Snikos.nikoleris@arm.com code = code_formatter() 82612069Snikos.nikoleris@arm.com module = source[0].get_contents() 82712069Snikos.nikoleris@arm.com # Provide the full context so that the swig-generated call to 82812069Snikos.nikoleris@arm.com # Py_InitModule ends up placing the embedded module in the 82912069Snikos.nikoleris@arm.com # right package. 83012069Snikos.nikoleris@arm.com context = str(package) + "._" + str(module) 83112069Snikos.nikoleris@arm.com code('''\ 83212069Snikos.nikoleris@arm.com #include "sim/init.hh" 83312069Snikos.nikoleris@arm.com 83410353SGeoffrey.Blake@arm.com extern "C" { 83510353SGeoffrey.Blake@arm.com void init_${module}(); 83610353SGeoffrey.Blake@arm.com } 83710353SGeoffrey.Blake@arm.com 83810353SGeoffrey.Blake@arm.com EmbeddedSwig embed_swig_${module}(init_${module}, "${context}"); 83910353SGeoffrey.Blake@arm.com ''') 84010353SGeoffrey.Blake@arm.com code.write(str(target[0])) 84110353SGeoffrey.Blake@arm.com return body 84213505Sgiacomo.travaglini@arm.com 84313505Sgiacomo.travaglini@arm.com# Build all swig modules 84410353SGeoffrey.Blake@arm.comfor swig in SwigSource.all: 84510353SGeoffrey.Blake@arm.com env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 84610353SGeoffrey.Blake@arm.com MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 8478870SAli.Saidi@ARM.com '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 84812598Snikos.nikoleris@arm.com cc_file = str(swig.tnode) 84912598Snikos.nikoleris@arm.com init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 85012598Snikos.nikoleris@arm.com env.Command(init_file, Value(swig.module), 85112598Snikos.nikoleris@arm.com MakeAction(makeEmbeddedSwigInit(swig.package), 85212116Sjose.marinho@arm.com Transform("EMBED SW"))) 85312116Sjose.marinho@arm.com env.Depends(SWIG, init_file) 85410037SARM gem5 Developers Source(init_file, **swig.guards) 85510037SARM gem5 Developers 8568870SAli.Saidi@ARM.com# Build all protocol buffers if we have got protoc and protobuf available 85710037SARM gem5 Developersif env['HAVE_PROTOBUF']: 85810358SAli.Saidi@ARM.com for proto in ProtoBuf.all: 85913636Sgiacomo.travaglini@arm.com # Use both the source and header as the target, and the .proto 86013636Sgiacomo.travaglini@arm.com # file as the source. When executing the protoc compiler, also 86113636Sgiacomo.travaglini@arm.com # specify the proto_path to avoid having the generated files 86211244Sandreas.sandberg@arm.com # include the path. 86311244Sandreas.sandberg@arm.com env.Command([proto.cc_file, proto.hh_file], proto.tnode, 86411244Sandreas.sandberg@arm.com MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 86511244Sandreas.sandberg@arm.com '--proto_path ${SOURCE.dir} $SOURCE', 86610037SARM gem5 Developers Transform("PROTOC"))) 86712598Snikos.nikoleris@arm.com 86812598Snikos.nikoleris@arm.com env.Depends(SWIG, [proto.cc_file, proto.hh_file]) 86912598Snikos.nikoleris@arm.com # Add the C++ source file 87012598Snikos.nikoleris@arm.com Source(proto.cc_file, **proto.guards) 87112116Sjose.marinho@arm.comelif ProtoBuf.all: 87212116Sjose.marinho@arm.com print 'Got protobuf to build, but lacks support!' 87310037SARM gem5 Developers Exit(1) 87410037SARM gem5 Developers 87510037SARM gem5 Developers# 87613532Sjairo.balart@metempsy.com# Handle debug flags 87711297Sandreas.sandberg@arm.com# 87811297Sandreas.sandberg@arm.comdef makeDebugFlagCC(target, source, env): 87911297Sandreas.sandberg@arm.com assert(len(target) == 1 and len(source) == 1) 88011297Sandreas.sandberg@arm.com 88111297Sandreas.sandberg@arm.com code = code_formatter() 88211297Sandreas.sandberg@arm.com 88311297Sandreas.sandberg@arm.com # delay definition of CompoundFlags until after all the definition 88411297Sandreas.sandberg@arm.com # of all constituent SimpleFlags 88511297Sandreas.sandberg@arm.com comp_code = code_formatter() 88611297Sandreas.sandberg@arm.com 88711297Sandreas.sandberg@arm.com # file header 88811297Sandreas.sandberg@arm.com code(''' 88911297Sandreas.sandberg@arm.com/* 89011297Sandreas.sandberg@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 89111297Sandreas.sandberg@arm.com */ 89211297Sandreas.sandberg@arm.com 89311297Sandreas.sandberg@arm.com#include "base/debug.hh" 89411297Sandreas.sandberg@arm.com 89511297Sandreas.sandberg@arm.comnamespace Debug { 89611297Sandreas.sandberg@arm.com 89711297Sandreas.sandberg@arm.com''') 89811297Sandreas.sandberg@arm.com 89911297Sandreas.sandberg@arm.com for name, flag in sorted(source[0].read().iteritems()): 90011297Sandreas.sandberg@arm.com n, compound, desc = flag 90111297Sandreas.sandberg@arm.com assert n == name 90211297Sandreas.sandberg@arm.com 90311297Sandreas.sandberg@arm.com if not compound: 90411297Sandreas.sandberg@arm.com code('SimpleFlag $name("$name", "$desc");') 90512006Sandreas.sandberg@arm.com else: 90611297Sandreas.sandberg@arm.com comp_code('CompoundFlag $name("$name", "$desc",') 90711297Sandreas.sandberg@arm.com comp_code.indent() 90811297Sandreas.sandberg@arm.com last = len(compound) - 1 90911297Sandreas.sandberg@arm.com for i,flag in enumerate(compound): 91011297Sandreas.sandberg@arm.com if i != last: 91111297Sandreas.sandberg@arm.com comp_code('&$flag,') 91211297Sandreas.sandberg@arm.com else: 91311297Sandreas.sandberg@arm.com comp_code('&$flag);') 91411297Sandreas.sandberg@arm.com comp_code.dedent() 91511297Sandreas.sandberg@arm.com 91611297Sandreas.sandberg@arm.com code.append(comp_code) 91712741Sandreas.sandberg@arm.com code() 91812741Sandreas.sandberg@arm.com code('} // namespace Debug') 91911297Sandreas.sandberg@arm.com 92011297Sandreas.sandberg@arm.com code.write(str(target[0])) 92111297Sandreas.sandberg@arm.com 92211297Sandreas.sandberg@arm.comdef makeDebugFlagHH(target, source, env): 92311297Sandreas.sandberg@arm.com assert(len(target) == 1 and len(source) == 1) 92411297Sandreas.sandberg@arm.com 92512896Sandreas.sandberg@arm.com val = eval(source[0].get_contents()) 92611297Sandreas.sandberg@arm.com name, compound, desc = val 92711297Sandreas.sandberg@arm.com 92811297Sandreas.sandberg@arm.com code = code_formatter() 92911297Sandreas.sandberg@arm.com 93011297Sandreas.sandberg@arm.com # file header boilerplate 93111297Sandreas.sandberg@arm.com code('''\ 93211297Sandreas.sandberg@arm.com/* 93311297Sandreas.sandberg@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 93411297Sandreas.sandberg@arm.com */ 93511297Sandreas.sandberg@arm.com 93611297Sandreas.sandberg@arm.com#ifndef __DEBUG_${name}_HH__ 93711297Sandreas.sandberg@arm.com#define __DEBUG_${name}_HH__ 93811297Sandreas.sandberg@arm.com 93911297Sandreas.sandberg@arm.comnamespace Debug { 94011297Sandreas.sandberg@arm.com''') 94111297Sandreas.sandberg@arm.com 94211297Sandreas.sandberg@arm.com if compound: 94311297Sandreas.sandberg@arm.com code('class CompoundFlag;') 94411297Sandreas.sandberg@arm.com code('class SimpleFlag;') 94511297Sandreas.sandberg@arm.com 94611297Sandreas.sandberg@arm.com if compound: 94711297Sandreas.sandberg@arm.com code('extern CompoundFlag $name;') 94811297Sandreas.sandberg@arm.com for flag in compound: 94911297Sandreas.sandberg@arm.com code('extern SimpleFlag $flag;') 95011297Sandreas.sandberg@arm.com else: 95111297Sandreas.sandberg@arm.com code('extern SimpleFlag $name;') 95211297Sandreas.sandberg@arm.com 95311297Sandreas.sandberg@arm.com code(''' 95411297Sandreas.sandberg@arm.com} 95511297Sandreas.sandberg@arm.com 95611297Sandreas.sandberg@arm.com#endif // __DEBUG_${name}_HH__ 95711297Sandreas.sandberg@arm.com''') 95811297Sandreas.sandberg@arm.com 95911297Sandreas.sandberg@arm.com code.write(str(target[0])) 96011297Sandreas.sandberg@arm.com 96111297Sandreas.sandberg@arm.comfor name,flag in sorted(debug_flags.iteritems()): 96211297Sandreas.sandberg@arm.com n, compound, desc = flag 96312741Sandreas.sandberg@arm.com assert n == name 96412741Sandreas.sandberg@arm.com 96511297Sandreas.sandberg@arm.com hh_file = 'debug/%s.hh' % name 96611297Sandreas.sandberg@arm.com env.Command(hh_file, Value(flag), 96711297Sandreas.sandberg@arm.com MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 96811297Sandreas.sandberg@arm.com env.Depends(SWIG, hh_file) 96911297Sandreas.sandberg@arm.com 97011297Sandreas.sandberg@arm.comenv.Command('debug/flags.cc', Value(debug_flags), 97111297Sandreas.sandberg@arm.com MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 97211297Sandreas.sandberg@arm.comenv.Depends(SWIG, 'debug/flags.cc') 97311297Sandreas.sandberg@arm.comSource('debug/flags.cc') 97413636Sgiacomo.travaglini@arm.com 97511297Sandreas.sandberg@arm.com# version tags 97611297Sandreas.sandberg@arm.comtags = \ 97711297Sandreas.sandberg@arm.comenv.Command('sim/tags.cc', None, 97811297Sandreas.sandberg@arm.com MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 97911297Sandreas.sandberg@arm.com Transform("VER TAGS"))) 98011297Sandreas.sandberg@arm.comenv.AlwaysBuild(tags) 98111297Sandreas.sandberg@arm.com 98211297Sandreas.sandberg@arm.com# Embed python files. All .py files that have been indicated by a 98311297Sandreas.sandberg@arm.com# PySource() call in a SConscript need to be embedded into the M5 98411297Sandreas.sandberg@arm.com# library. To do that, we compile the file to byte code, marshal the 98511297Sandreas.sandberg@arm.com# byte code, compress it, and then generate a c++ file that 98611297Sandreas.sandberg@arm.com# inserts the result into an array. 98711297Sandreas.sandberg@arm.comdef embedPyFile(target, source, env): 98811297Sandreas.sandberg@arm.com def c_str(string): 98911297Sandreas.sandberg@arm.com if string is None: 99012975Sgiacomo.travaglini@arm.com return "0" 99112975Sgiacomo.travaglini@arm.com return '"%s"' % string 99212975Sgiacomo.travaglini@arm.com 99312975Sgiacomo.travaglini@arm.com '''Action function to compile a .py into a code object, marshal 99411297Sandreas.sandberg@arm.com it, compress it, and stick it into an asm file so the code appears 99511297Sandreas.sandberg@arm.com as just bytes with a label in the data section''' 99611297Sandreas.sandberg@arm.com 99711297Sandreas.sandberg@arm.com src = file(str(source[0]), 'r').read() 99811297Sandreas.sandberg@arm.com 99911297Sandreas.sandberg@arm.com pysource = PySource.tnodes[source[0]] 100011297Sandreas.sandberg@arm.com compiled = compile(src, pysource.abspath, 'exec') 100112472Sglenn.bergmans@arm.com marshalled = marshal.dumps(compiled) 100212472Sglenn.bergmans@arm.com compressed = zlib.compress(marshalled) 100312472Sglenn.bergmans@arm.com data = compressed 100413015Sciro.santilli@arm.com sym = pysource.symname 100513015Sciro.santilli@arm.com 100613015Sciro.santilli@arm.com code = code_formatter() 100711297Sandreas.sandberg@arm.com code('''\ 100812659Sandreas.sandberg@arm.com#include "sim/init.hh" 100912659Sandreas.sandberg@arm.com 101011297Sandreas.sandberg@arm.comnamespace { 101111297Sandreas.sandberg@arm.com 101211297Sandreas.sandberg@arm.comconst uint8_t data_${sym}[] = { 101311297Sandreas.sandberg@arm.com''') 101411297Sandreas.sandberg@arm.com code.indent() 101511297Sandreas.sandberg@arm.com step = 16 101611297Sandreas.sandberg@arm.com for i in xrange(0, len(data), step): 101711297Sandreas.sandberg@arm.com x = array.array('B', data[i:i+step]) 101811297Sandreas.sandberg@arm.com code(''.join('%d,' % d for d in x)) 101911297Sandreas.sandberg@arm.com code.dedent() 102011297Sandreas.sandberg@arm.com 102112741Sandreas.sandberg@arm.com code('''}; 102212741Sandreas.sandberg@arm.com 102312741Sandreas.sandberg@arm.comEmbeddedPython embedded_${sym}( 102412741Sandreas.sandberg@arm.com ${{c_str(pysource.arcname)}}, 102512741Sandreas.sandberg@arm.com ${{c_str(pysource.abspath)}}, 102612741Sandreas.sandberg@arm.com ${{c_str(pysource.modpath)}}, 102711297Sandreas.sandberg@arm.com data_${sym}, 102811297Sandreas.sandberg@arm.com ${{len(data)}}, 102911297Sandreas.sandberg@arm.com ${{len(marshalled)}}); 103011297Sandreas.sandberg@arm.com 103113015Sciro.santilli@arm.com} // anonymous namespace 103212472Sglenn.bergmans@arm.com''') 103312472Sglenn.bergmans@arm.com code.write(str(target[0])) 103411297Sandreas.sandberg@arm.com 103511297Sandreas.sandberg@arm.comfor source in PySource.all: 103611297Sandreas.sandberg@arm.com env.Command(source.cpp, source.tnode, 103712472Sglenn.bergmans@arm.com MakeAction(embedPyFile, Transform("EMBED PY"))) 103812741Sandreas.sandberg@arm.com env.Depends(SWIG, source.cpp) 103912741Sandreas.sandberg@arm.com Source(source.cpp, skip_no_python=True) 104011297Sandreas.sandberg@arm.com 104111297Sandreas.sandberg@arm.com######################################################################## 104211597Sandreas.sandberg@arm.com# 104311297Sandreas.sandberg@arm.com# Define binaries. Each different build type (debug, opt, etc.) gets 104411597Sandreas.sandberg@arm.com# a slightly different build environment. 104511297Sandreas.sandberg@arm.com# 104611297Sandreas.sandberg@arm.com 104712598Snikos.nikoleris@arm.com# List of constructed environments to pass back to SConstruct 104812598Snikos.nikoleris@arm.comdate_source = Source('base/date.cc', skip_lib=True) 104912598Snikos.nikoleris@arm.com 105012598Snikos.nikoleris@arm.com# Capture this directory for the closure makeEnv, otherwise when it is 105112116Sjose.marinho@arm.com# called, it won't know what directory it should use. 105212116Sjose.marinho@arm.comvariant_dir = Dir('.').path 105311297Sandreas.sandberg@arm.comdef variant(*path): 105411297Sandreas.sandberg@arm.com return os.path.join(variant_dir, *path) 105512006Sandreas.sandberg@arm.comdef variantd(*path): 105612006Sandreas.sandberg@arm.com return variant(*path)+'/' 105712006Sandreas.sandberg@arm.com 105812006Sandreas.sandberg@arm.com# Function to create a new build environment as clone of current 105912006Sandreas.sandberg@arm.com# environment 'env' with modified object suffix and optional stripped 106012472Sglenn.bergmans@arm.com# binary. Additional keyword arguments are appended to corresponding 106112472Sglenn.bergmans@arm.com# build environment vars. 106212472Sglenn.bergmans@arm.comdef makeEnv(env, label, objsfx, strip = False, **kwargs): 106313532Sjairo.balart@metempsy.com # SCons doesn't know to append a library suffix when there is a '.' in the 106412472Sglenn.bergmans@arm.com # name. Use '_' instead. 106512472Sglenn.bergmans@arm.com libname = variant('gem5_' + label) 106612472Sglenn.bergmans@arm.com exename = variant('gem5.' + label) 106712472Sglenn.bergmans@arm.com secondary_exename = variant('m5.' + label) 106812472Sglenn.bergmans@arm.com 106912472Sglenn.bergmans@arm.com new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 107012472Sglenn.bergmans@arm.com new_env.Label = label 107112472Sglenn.bergmans@arm.com new_env.Append(**kwargs) 107212472Sglenn.bergmans@arm.com 107312472Sglenn.bergmans@arm.com swig_env = new_env.Clone() 107412760Srohit.kurup@arm.com 107513532Sjairo.balart@metempsy.com # Both gcc and clang have issues with unused labels and values in 107613532Sjairo.balart@metempsy.com # the SWIG generated code 107713532Sjairo.balart@metempsy.com swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 107813814Sgiacomo.travaglini@arm.com 107913532Sjairo.balart@metempsy.com if env['GCC']: 108013532Sjairo.balart@metempsy.com # Depending on the SWIG version, we also need to supress 108113532Sjairo.balart@metempsy.com # warnings about uninitialized variables and missing field 108213532Sjairo.balart@metempsy.com # initializers. 108313532Sjairo.balart@metempsy.com swig_env.Append(CCFLAGS=['-Wno-uninitialized', 108413532Sjairo.balart@metempsy.com '-Wno-missing-field-initializers', 108513532Sjairo.balart@metempsy.com '-Wno-unused-but-set-variable', 108613532Sjairo.balart@metempsy.com '-Wno-maybe-uninitialized', 108713532Sjairo.balart@metempsy.com '-Wno-type-limits']) 108812760Srohit.kurup@arm.com 108912760Srohit.kurup@arm.com 109012760Srohit.kurup@arm.com # The address sanitizer is available for gcc >= 4.8 109112760Srohit.kurup@arm.com if GetOption('with_asan'): 109212760Srohit.kurup@arm.com if GetOption('with_ubsan') and \ 109312760Srohit.kurup@arm.com compareVersions(env['GCC_VERSION'], '4.9') >= 0: 109412760Srohit.kurup@arm.com new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 109512760Srohit.kurup@arm.com '-fno-omit-frame-pointer']) 109612760Srohit.kurup@arm.com new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 109713532Sjairo.balart@metempsy.com else: 109813532Sjairo.balart@metempsy.com new_env.Append(CCFLAGS=['-fsanitize=address', 109913880Sgiacomo.travaglini@arm.com '-fno-omit-frame-pointer']) 110013996Sgiacomo.travaglini@arm.com new_env.Append(LINKFLAGS='-fsanitize=address') 110114225Sadrian.herrera@arm.com # Only gcc >= 4.9 supports UBSan, so check both the version 110213532Sjairo.balart@metempsy.com # and the command-line option before adding the compiler and 110313879Sgiacomo.travaglini@arm.com # linker flags. 110413879Sgiacomo.travaglini@arm.com elif GetOption('with_ubsan') and \ 110513879Sgiacomo.travaglini@arm.com compareVersions(env['GCC_VERSION'], '4.9') >= 0: 110613532Sjairo.balart@metempsy.com new_env.Append(CCFLAGS='-fsanitize=undefined') 110713532Sjairo.balart@metempsy.com new_env.Append(LINKFLAGS='-fsanitize=undefined') 110813996Sgiacomo.travaglini@arm.com 110913532Sjairo.balart@metempsy.com 111013532Sjairo.balart@metempsy.com if env['CLANG']: 111113532Sjairo.balart@metempsy.com swig_env.Append(CCFLAGS=['-Wno-sometimes-uninitialized', 111213532Sjairo.balart@metempsy.com '-Wno-deprecated-register', 111313532Sjairo.balart@metempsy.com '-Wno-tautological-compare']) 111413532Sjairo.balart@metempsy.com 111513532Sjairo.balart@metempsy.com # We require clang >= 3.1, so there is no need to check any 111613532Sjairo.balart@metempsy.com # versions here. 111713532Sjairo.balart@metempsy.com if GetOption('with_ubsan'): 111813532Sjairo.balart@metempsy.com if GetOption('with_asan'): 111913532Sjairo.balart@metempsy.com new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 112013532Sjairo.balart@metempsy.com '-fno-omit-frame-pointer']) 112113532Sjairo.balart@metempsy.com new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 112213532Sjairo.balart@metempsy.com else: 112313532Sjairo.balart@metempsy.com new_env.Append(CCFLAGS='-fsanitize=undefined') 1124 new_env.Append(LINKFLAGS='-fsanitize=undefined') 1125 1126 elif GetOption('with_asan'): 1127 new_env.Append(CCFLAGS=['-fsanitize=address', 1128 '-fno-omit-frame-pointer']) 1129 new_env.Append(LINKFLAGS='-fsanitize=address') 1130 1131 werror_env = new_env.Clone() 1132 # Treat warnings as errors but white list some warnings that we 1133 # want to allow (e.g., deprecation warnings). 1134 werror_env.Append(CCFLAGS=['-Werror', 1135 '-Wno-error=deprecated-declarations', 1136 '-Wno-error=deprecated', 1137 ]) 1138 1139 def make_obj(source, static, extra_deps = None): 1140 '''This function adds the specified source to the correct 1141 build environment, and returns the corresponding SCons Object 1142 nodes''' 1143 1144 if source.swig: 1145 env = swig_env 1146 elif source.Werror: 1147 env = werror_env 1148 else: 1149 env = new_env 1150 1151 if static: 1152 obj = env.StaticObject(source.tnode) 1153 else: 1154 obj = env.SharedObject(source.tnode) 1155 1156 if extra_deps: 1157 env.Depends(obj, extra_deps) 1158 1159 return obj 1160 1161 lib_guards = {'main': False, 'skip_lib': False} 1162 1163 # Without Python, leave out all SWIG and Python content from the 1164 # library builds. The option doesn't affect gem5 built as a program 1165 if GetOption('without_python'): 1166 lib_guards['skip_no_python'] = False 1167 1168 static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] 1169 shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] 1170 1171 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 1172 static_objs.append(static_date) 1173 1174 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 1175 shared_objs.append(shared_date) 1176 1177 # First make a library of everything but main() so other programs can 1178 # link against m5. 1179 static_lib = new_env.StaticLibrary(libname, static_objs) 1180 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1181 1182 # Now link a stub with main() and the static library. 1183 main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 1184 1185 for test in UnitTest.all: 1186 flags = { test.target : True } 1187 test_sources = Source.get(**flags) 1188 test_objs = [ make_obj(s, static=True) for s in test_sources ] 1189 if test.main: 1190 test_objs += main_objs 1191 path = variant('unittest/%s.%s' % (test.target, label)) 1192 new_env.Program(path, test_objs + static_objs) 1193 1194 progname = exename 1195 if strip: 1196 progname += '.unstripped' 1197 1198 # When linking the gem5 binary, the command line can be too big for the 1199 # shell to handle. Use "subprocess" to spawn processes without passing 1200 # through the shell to avoid this problem. That means we also can't use 1201 # shell syntax in any of the commands this will run, but that isn't 1202 # currently an issue. 1203 def spawn_with_subprocess(sh, escape, cmd, args, env): 1204 return subprocess.call(args, env=env) 1205 1206 # Since we're not running through a shell, no escaping is necessary either. 1207 targets = new_env.Program(progname, main_objs + static_objs, 1208 SPAWN=spawn_with_subprocess, 1209 ESCAPE=lambda x: x) 1210 1211 if strip: 1212 if sys.platform == 'sunos5': 1213 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1214 else: 1215 cmd = 'strip $SOURCE -o $TARGET' 1216 targets = new_env.Command(exename, progname, 1217 MakeAction(cmd, Transform("STRIP"))) 1218 1219 new_env.Command(secondary_exename, exename, 1220 MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 1221 1222 new_env.M5Binary = targets[0] 1223 return new_env 1224 1225# Start out with the compiler flags common to all compilers, 1226# i.e. they all use -g for opt and -g -pg for prof 1227ccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 1228 'perf' : ['-g']} 1229 1230# Start out with the linker flags common to all linkers, i.e. -pg for 1231# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 1232# no-as-needed and as-needed as the binutils linker is too clever and 1233# simply doesn't link to the library otherwise. 1234ldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 1235 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 1236 1237# For Link Time Optimization, the optimisation flags used to compile 1238# individual files are decoupled from those used at link time 1239# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 1240# to also update the linker flags based on the target. 1241if env['GCC']: 1242 if sys.platform == 'sunos5': 1243 ccflags['debug'] += ['-gstabs+'] 1244 else: 1245 ccflags['debug'] += ['-ggdb3'] 1246 ldflags['debug'] += ['-O0'] 1247 # opt, fast, prof and perf all share the same cc flags, also add 1248 # the optimization to the ldflags as LTO defers the optimization 1249 # to link time 1250 for target in ['opt', 'fast', 'prof', 'perf']: 1251 ccflags[target] += ['-O3'] 1252 ldflags[target] += ['-O3'] 1253 1254 ccflags['fast'] += env['LTO_CCFLAGS'] 1255 ldflags['fast'] += env['LTO_LDFLAGS'] 1256elif env['CLANG']: 1257 ccflags['debug'] += ['-g', '-O0'] 1258 # opt, fast, prof and perf all share the same cc flags 1259 for target in ['opt', 'fast', 'prof', 'perf']: 1260 ccflags[target] += ['-O3'] 1261else: 1262 print 'Unknown compiler, please fix compiler options' 1263 Exit(1) 1264 1265 1266# To speed things up, we only instantiate the build environments we 1267# need. We try to identify the needed environment for each target; if 1268# we can't, we fall back on instantiating all the environments just to 1269# be safe. 1270target_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 1271obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 1272 'gpo' : 'perf'} 1273 1274def identifyTarget(t): 1275 ext = t.split('.')[-1] 1276 if ext in target_types: 1277 return ext 1278 if obj2target.has_key(ext): 1279 return obj2target[ext] 1280 match = re.search(r'/tests/([^/]+)/', t) 1281 if match and match.group(1) in target_types: 1282 return match.group(1) 1283 return 'all' 1284 1285needed_envs = [identifyTarget(target) for target in BUILD_TARGETS] 1286if 'all' in needed_envs: 1287 needed_envs += target_types 1288 1289def makeEnvirons(target, source, env): 1290 # cause any later Source() calls to be fatal, as a diagnostic. 1291 Source.done() 1292 1293 envList = [] 1294 1295 # Debug binary 1296 if 'debug' in needed_envs: 1297 envList.append( 1298 makeEnv(env, 'debug', '.do', 1299 CCFLAGS = Split(ccflags['debug']), 1300 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 1301 LINKFLAGS = Split(ldflags['debug']))) 1302 1303 # Optimized binary 1304 if 'opt' in needed_envs: 1305 envList.append( 1306 makeEnv(env, 'opt', '.o', 1307 CCFLAGS = Split(ccflags['opt']), 1308 CPPDEFINES = ['TRACING_ON=1'], 1309 LINKFLAGS = Split(ldflags['opt']))) 1310 1311 # "Fast" binary 1312 if 'fast' in needed_envs: 1313 envList.append( 1314 makeEnv(env, 'fast', '.fo', strip = True, 1315 CCFLAGS = Split(ccflags['fast']), 1316 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1317 LINKFLAGS = Split(ldflags['fast']))) 1318 1319 # Profiled binary using gprof 1320 if 'prof' in needed_envs: 1321 envList.append( 1322 makeEnv(env, 'prof', '.po', 1323 CCFLAGS = Split(ccflags['prof']), 1324 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1325 LINKFLAGS = Split(ldflags['prof']))) 1326 1327 # Profiled binary using google-pprof 1328 if 'perf' in needed_envs: 1329 envList.append( 1330 makeEnv(env, 'perf', '.gpo', 1331 CCFLAGS = Split(ccflags['perf']), 1332 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1333 LINKFLAGS = Split(ldflags['perf']))) 1334 1335 # Set up the regression tests for each build. 1336 for e in envList: 1337 SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 1338 variant_dir = variantd('tests', e.Label), 1339 exports = { 'env' : e }, duplicate = False) 1340 1341# The MakeEnvirons Builder defers the full dependency collection until 1342# after processing the ISA definition (due to dynamically generated 1343# source files). Add this dependency to all targets so they will wait 1344# until the environments are completely set up. Otherwise, a second 1345# process (e.g. -j2 or higher) will try to compile the requested target, 1346# not know how, and fail. 1347env.Append(BUILDERS = {'MakeEnvirons' : 1348 Builder(action=MakeAction(makeEnvirons, 1349 Transform("ENVIRONS", 1)))}) 1350 1351isa_target = env['PHONY_BASE'] + '-deps' 1352environs = env['PHONY_BASE'] + '-environs' 1353env.Depends('#all-deps', isa_target) 1354env.Depends('#all-environs', environs) 1355env.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 1356envSetup = env.MakeEnvirons(environs, isa_target) 1357 1358# make sure no -deps targets occur before all ISAs are complete 1359env.Depends(isa_target, '#all-isas') 1360# likewise for -environs targets and all the -deps targets 1361env.Depends(environs, '#all-deps') 1362