SConscript revision 11718:09f8fda798bc
1955SN/A# -*- mode:python -*- 2955SN/A 311408Sandreas.sandberg@arm.com# Copyright (c) 2004-2005 The Regents of The University of Michigan 49812Sandreas.hansson@arm.com# All rights reserved. 59812Sandreas.hansson@arm.com# 69812Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without 79812Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are 89812Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright 99812Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer; 109812Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright 119812Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the 129812Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution; 139812Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its 149812Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from 157816Ssteve.reinhardt@amd.com# this software without specific prior written permission. 165871Snate@binkert.org# 171762SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28955SN/A# 29955SN/A# Authors: Nathan Binkert 30955SN/A 31955SN/Aimport array 32955SN/Aimport bisect 33955SN/Aimport imp 34955SN/Aimport marshal 35955SN/Aimport os 36955SN/Aimport re 37955SN/Aimport sys 38955SN/Aimport zlib 39955SN/A 40955SN/Afrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 41955SN/A 422665Ssaidi@eecs.umich.eduimport SCons 432665Ssaidi@eecs.umich.edu 445863Snate@binkert.org# This file defines how to build a particular configuration of gem5 45955SN/A# based on variable settings in the 'env' build environment. 46955SN/A 47955SN/AImport('*') 48955SN/A 49955SN/A# Children need to see the environment 508878Ssteve.reinhardt@amd.comExport('env') 512632Sstever@eecs.umich.edu 528878Ssteve.reinhardt@amd.combuild_env = [(opt, env[opt]) for opt in export_vars] 532632Sstever@eecs.umich.edu 54955SN/Afrom m5.util import code_formatter, compareVersions 558878Ssteve.reinhardt@amd.com 562632Sstever@eecs.umich.edu######################################################################## 572761Sstever@eecs.umich.edu# Code for adding source files of various types 582632Sstever@eecs.umich.edu# 592632Sstever@eecs.umich.edu# When specifying a source file of some type, a set of guards can be 602632Sstever@eecs.umich.edu# specified for that file. When get() is used to find the files, if 612761Sstever@eecs.umich.edu# get specifies a set of filters, only files that match those filters 622761Sstever@eecs.umich.edu# will be accepted (unspecified filters on files are assumed to be 632761Sstever@eecs.umich.edu# false). Current filters are: 648878Ssteve.reinhardt@amd.com# main -- specifies the gem5 main() function 658878Ssteve.reinhardt@amd.com# skip_lib -- do not put this file into the gem5 library 662761Sstever@eecs.umich.edu# skip_no_python -- do not put this file into a no_python library 672761Sstever@eecs.umich.edu# as it embeds compiled Python 682761Sstever@eecs.umich.edu# <unittest> -- unit tests use filters based on the unit test name 692761Sstever@eecs.umich.edu# 702761Sstever@eecs.umich.edu# A parent can now be specified for a source file and default filter 718878Ssteve.reinhardt@amd.com# values will be retrieved recursively from parents (children override 728878Ssteve.reinhardt@amd.com# parents). 732632Sstever@eecs.umich.edu# 742632Sstever@eecs.umich.educlass SourceMeta(type): 758878Ssteve.reinhardt@amd.com '''Meta class for source files that keeps track of all files of a 768878Ssteve.reinhardt@amd.com particular type and has a get function for finding all functions 772632Sstever@eecs.umich.edu of a certain type that match a set of guards''' 78955SN/A def __init__(cls, name, bases, dict): 79955SN/A super(SourceMeta, cls).__init__(name, bases, dict) 80955SN/A cls.all = [] 815863Snate@binkert.org 825863Snate@binkert.org def get(cls, **guards): 835863Snate@binkert.org '''Find all files that match the specified guards. If a source 845863Snate@binkert.org file does not specify a flag, the default is False''' 855863Snate@binkert.org for src in cls.all: 865863Snate@binkert.org for flag,value in guards.iteritems(): 875863Snate@binkert.org # if the flag is found and has a different value, skip 885863Snate@binkert.org # this file 895863Snate@binkert.org if src.all_guards.get(flag, False) != value: 905863Snate@binkert.org break 915863Snate@binkert.org else: 928878Ssteve.reinhardt@amd.com yield src 935863Snate@binkert.org 945863Snate@binkert.orgclass SourceFile(object): 955863Snate@binkert.org '''Base object that encapsulates the notion of a source file. 969812Sandreas.hansson@arm.com This includes, the source node, target node, various manipulations 979812Sandreas.hansson@arm.com of those. A source file also specifies a set of guards which 985863Snate@binkert.org describing which builds the source file applies to. A parent can 999812Sandreas.hansson@arm.com also be specified to get default guards from''' 1005863Snate@binkert.org __metaclass__ = SourceMeta 1015863Snate@binkert.org def __init__(self, source, parent=None, **guards): 1025863Snate@binkert.org self.guards = guards 1039812Sandreas.hansson@arm.com self.parent = parent 1049812Sandreas.hansson@arm.com 1055863Snate@binkert.org tnode = source 1065863Snate@binkert.org if not isinstance(source, SCons.Node.FS.File): 1078878Ssteve.reinhardt@amd.com tnode = File(source) 1085863Snate@binkert.org 1095863Snate@binkert.org self.tnode = tnode 1105863Snate@binkert.org self.snode = tnode.srcnode() 1116654Snate@binkert.org 11210196SCurtis.Dunham@arm.com for base in type(self).__mro__: 113955SN/A if issubclass(base, SourceFile): 1145396Ssaidi@eecs.umich.edu base.all.append(self) 11511401Sandreas.sandberg@arm.com 1165863Snate@binkert.org @property 1175863Snate@binkert.org def filename(self): 1184202Sbinkertn@umich.edu return str(self.tnode) 1195863Snate@binkert.org 1205863Snate@binkert.org @property 1215863Snate@binkert.org def dirname(self): 1225863Snate@binkert.org return dirname(self.filename) 123955SN/A 1246654Snate@binkert.org @property 1255273Sstever@gmail.com def basename(self): 1265871Snate@binkert.org return basename(self.filename) 1275273Sstever@gmail.com 1286655Snate@binkert.org @property 1298878Ssteve.reinhardt@amd.com def extname(self): 1306655Snate@binkert.org index = self.basename.rfind('.') 1316655Snate@binkert.org if index <= 0: 1329219Spower.jg@gmail.com # dot files aren't extensions 1336655Snate@binkert.org return self.basename, None 1345871Snate@binkert.org 1356654Snate@binkert.org return self.basename[:index], self.basename[index+1:] 1368947Sandreas.hansson@arm.com 1375396Ssaidi@eecs.umich.edu @property 1388120Sgblack@eecs.umich.edu def all_guards(self): 1398120Sgblack@eecs.umich.edu '''find all guards for this object getting default values 1408120Sgblack@eecs.umich.edu recursively from its parents''' 1418120Sgblack@eecs.umich.edu guards = {} 1428120Sgblack@eecs.umich.edu if self.parent: 1438120Sgblack@eecs.umich.edu guards.update(self.parent.guards) 1448120Sgblack@eecs.umich.edu guards.update(self.guards) 1458120Sgblack@eecs.umich.edu return guards 1468879Ssteve.reinhardt@amd.com 1478879Ssteve.reinhardt@amd.com def __lt__(self, other): return self.filename < other.filename 1488879Ssteve.reinhardt@amd.com def __le__(self, other): return self.filename <= other.filename 1498879Ssteve.reinhardt@amd.com def __gt__(self, other): return self.filename > other.filename 1508879Ssteve.reinhardt@amd.com def __ge__(self, other): return self.filename >= other.filename 1518879Ssteve.reinhardt@amd.com def __eq__(self, other): return self.filename == other.filename 1528879Ssteve.reinhardt@amd.com def __ne__(self, other): return self.filename != other.filename 1538879Ssteve.reinhardt@amd.com 1548879Ssteve.reinhardt@amd.com @staticmethod 1558879Ssteve.reinhardt@amd.com def done(): 1568879Ssteve.reinhardt@amd.com def disabled(cls, name, *ignored): 1578879Ssteve.reinhardt@amd.com raise RuntimeError("Additional SourceFile '%s'" % name,\ 1588879Ssteve.reinhardt@amd.com "declared, but targets deps are already fixed.") 1598120Sgblack@eecs.umich.edu SourceFile.__init__ = disabled 1608120Sgblack@eecs.umich.edu 1618120Sgblack@eecs.umich.edu 1628120Sgblack@eecs.umich.educlass Source(SourceFile): 1638120Sgblack@eecs.umich.edu '''Add a c/c++ source file to the build''' 1648120Sgblack@eecs.umich.edu def __init__(self, source, Werror=True, swig=False, **guards): 1658120Sgblack@eecs.umich.edu '''specify the source file, and any guards''' 1668120Sgblack@eecs.umich.edu super(Source, self).__init__(source, **guards) 1678120Sgblack@eecs.umich.edu 1688120Sgblack@eecs.umich.edu self.Werror = Werror 1698120Sgblack@eecs.umich.edu self.swig = swig 1708120Sgblack@eecs.umich.edu 1718120Sgblack@eecs.umich.educlass PySource(SourceFile): 1728120Sgblack@eecs.umich.edu '''Add a python source file to the named package''' 1738879Ssteve.reinhardt@amd.com invalid_sym_char = re.compile('[^A-z0-9_]') 1748879Ssteve.reinhardt@amd.com modules = {} 1758879Ssteve.reinhardt@amd.com tnodes = {} 1768879Ssteve.reinhardt@amd.com symnames = {} 17710458Sandreas.hansson@arm.com 17810458Sandreas.hansson@arm.com def __init__(self, package, source, **guards): 17910458Sandreas.hansson@arm.com '''specify the python package, the source file, and any guards''' 1808879Ssteve.reinhardt@amd.com super(PySource, self).__init__(source, **guards) 1818879Ssteve.reinhardt@amd.com 1828879Ssteve.reinhardt@amd.com modname,ext = self.extname 1838879Ssteve.reinhardt@amd.com assert ext == 'py' 1849227Sandreas.hansson@arm.com 1859227Sandreas.hansson@arm.com if package: 1868879Ssteve.reinhardt@amd.com path = package.split('.') 1878879Ssteve.reinhardt@amd.com else: 1888879Ssteve.reinhardt@amd.com path = [] 1898879Ssteve.reinhardt@amd.com 19010453SAndrew.Bardsley@arm.com modpath = path[:] 19110453SAndrew.Bardsley@arm.com if modname != '__init__': 19210453SAndrew.Bardsley@arm.com modpath += [ modname ] 19310456SCurtis.Dunham@arm.com modpath = '.'.join(modpath) 19410456SCurtis.Dunham@arm.com 19510456SCurtis.Dunham@arm.com arcpath = path + [ self.basename ] 19610457Sandreas.hansson@arm.com abspath = self.snode.abspath 19710457Sandreas.hansson@arm.com if not exists(abspath): 19811342Sandreas.hansson@arm.com abspath = self.tnode.abspath 19911342Sandreas.hansson@arm.com 2008120Sgblack@eecs.umich.edu self.package = package 2018947Sandreas.hansson@arm.com self.modname = modname 2027816Ssteve.reinhardt@amd.com self.modpath = modpath 2035871Snate@binkert.org self.arcname = joinpath(*arcpath) 2045871Snate@binkert.org self.abspath = abspath 2056121Snate@binkert.org self.compiled = File(self.filename + 'c') 2065871Snate@binkert.org self.cpp = File(self.filename + '.cc') 2075871Snate@binkert.org self.symname = PySource.invalid_sym_char.sub('_', modpath) 2089926Sstan.czerniawski@arm.com 2099926Sstan.czerniawski@arm.com PySource.modules[modpath] = self 2109119Sandreas.hansson@arm.com PySource.tnodes[self.tnode] = self 21110068Sandreas.hansson@arm.com PySource.symnames[self.symname] = self 21210068Sandreas.hansson@arm.com 213955SN/Aclass SimObject(PySource): 2149416SAndreas.Sandberg@ARM.com '''Add a SimObject python file as a python source object and add 21511342Sandreas.hansson@arm.com it to a list of sim object modules''' 21611212Sjoseph.gross@amd.com 21711212Sjoseph.gross@amd.com fixed = False 21811212Sjoseph.gross@amd.com modnames = [] 21911212Sjoseph.gross@amd.com 22011212Sjoseph.gross@amd.com def __init__(self, source, **guards): 2219416SAndreas.Sandberg@ARM.com '''Specify the source file and any guards (automatically in 2229416SAndreas.Sandberg@ARM.com the m5.objects package)''' 2235871Snate@binkert.org super(SimObject, self).__init__('m5.objects', source, **guards) 22410584Sandreas.hansson@arm.com if self.fixed: 2259416SAndreas.Sandberg@ARM.com raise AttributeError, "Too late to call SimObject now." 2269416SAndreas.Sandberg@ARM.com 2275871Snate@binkert.org bisect.insort_right(SimObject.modnames, self.modname) 228955SN/A 22910671Sandreas.hansson@arm.comclass SwigSource(SourceFile): 23010671Sandreas.hansson@arm.com '''Add a swig file to build''' 23110671Sandreas.hansson@arm.com 23210671Sandreas.hansson@arm.com def __init__(self, package, source, **guards): 2338881Smarc.orr@gmail.com '''Specify the python package, the source file, and any guards''' 2346121Snate@binkert.org super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 2356121Snate@binkert.org 2361533SN/A modname,ext = self.extname 2379239Sandreas.hansson@arm.com assert ext == 'i' 2389239Sandreas.hansson@arm.com 2399239Sandreas.hansson@arm.com self.package = package 2409239Sandreas.hansson@arm.com self.module = modname 2419239Sandreas.hansson@arm.com cc_file = joinpath(self.dirname, modname + '_wrap.cc') 2429239Sandreas.hansson@arm.com py_file = joinpath(self.dirname, modname + '.py') 2439239Sandreas.hansson@arm.com 2449239Sandreas.hansson@arm.com self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 2459239Sandreas.hansson@arm.com self.py_source = PySource(package, py_file, parent=self, **guards) 2469239Sandreas.hansson@arm.com 2479239Sandreas.hansson@arm.comclass ProtoBuf(SourceFile): 2489239Sandreas.hansson@arm.com '''Add a Protocol Buffer to build''' 2496655Snate@binkert.org 2506655Snate@binkert.org def __init__(self, source, **guards): 2516655Snate@binkert.org '''Specify the source file, and any guards''' 2526655Snate@binkert.org super(ProtoBuf, self).__init__(source, **guards) 2535871Snate@binkert.org 2545871Snate@binkert.org # Get the file name and the extension 2555863Snate@binkert.org modname,ext = self.extname 2565871Snate@binkert.org assert ext == 'proto' 2578878Ssteve.reinhardt@amd.com 2585871Snate@binkert.org # Currently, we stick to generating the C++ headers, so we 2595871Snate@binkert.org # only need to track the source and header. 2605871Snate@binkert.org self.cc_file = File(modname + '.pb.cc') 2615863Snate@binkert.org self.hh_file = File(modname + '.pb.h') 2626121Snate@binkert.org 2635863Snate@binkert.orgclass UnitTest(object): 26411408Sandreas.sandberg@arm.com '''Create a UnitTest''' 26511408Sandreas.sandberg@arm.com 2668336Ssteve.reinhardt@amd.com all = [] 26711469SCurtis.Dunham@arm.com def __init__(self, target, *sources, **kwargs): 26811469SCurtis.Dunham@arm.com '''Specify the target name and any sources. Sources that are 2698336Ssteve.reinhardt@amd.com not SourceFiles are evalued with Source(). All files are 2704678Snate@binkert.org guarded with a guard of the same name as the UnitTest 27111887Sandreas.sandberg@arm.com target.''' 27211887Sandreas.sandberg@arm.com 27311887Sandreas.sandberg@arm.com srcs = [] 27411887Sandreas.sandberg@arm.com for src in sources: 27511887Sandreas.sandberg@arm.com if not isinstance(src, SourceFile): 27611887Sandreas.sandberg@arm.com src = Source(src, skip_lib=True) 27711887Sandreas.sandberg@arm.com src.guards[target] = True 27811887Sandreas.sandberg@arm.com srcs.append(src) 27911887Sandreas.sandberg@arm.com 28011887Sandreas.sandberg@arm.com self.sources = srcs 28111887Sandreas.sandberg@arm.com self.target = target 28211408Sandreas.sandberg@arm.com self.main = kwargs.get('main', False) 28311401Sandreas.sandberg@arm.com UnitTest.all.append(self) 28411401Sandreas.sandberg@arm.com 28511401Sandreas.sandberg@arm.com# Children should have access 28611401Sandreas.sandberg@arm.comExport('Source') 28711401Sandreas.sandberg@arm.comExport('PySource') 28811401Sandreas.sandberg@arm.comExport('SimObject') 2898336Ssteve.reinhardt@amd.comExport('SwigSource') 2908336Ssteve.reinhardt@amd.comExport('ProtoBuf') 2918336Ssteve.reinhardt@amd.comExport('UnitTest') 2924678Snate@binkert.org 29311401Sandreas.sandberg@arm.com######################################################################## 2944678Snate@binkert.org# 2954678Snate@binkert.org# Debug Flags 29611401Sandreas.sandberg@arm.com# 29711401Sandreas.sandberg@arm.comdebug_flags = {} 2988336Ssteve.reinhardt@amd.comdef DebugFlag(name, desc=None): 2994678Snate@binkert.org if name in debug_flags: 3008336Ssteve.reinhardt@amd.com raise AttributeError, "Flag %s already specified" % name 3018336Ssteve.reinhardt@amd.com debug_flags[name] = (name, (), desc) 3028336Ssteve.reinhardt@amd.com 3038336Ssteve.reinhardt@amd.comdef CompoundFlag(name, flags, desc=None): 3048336Ssteve.reinhardt@amd.com if name in debug_flags: 3058336Ssteve.reinhardt@amd.com raise AttributeError, "Flag %s already specified" % name 3065871Snate@binkert.org 3075871Snate@binkert.org compound = tuple(flags) 3088336Ssteve.reinhardt@amd.com debug_flags[name] = (name, compound, desc) 30911408Sandreas.sandberg@arm.com 31011408Sandreas.sandberg@arm.comExport('DebugFlag') 31111408Sandreas.sandberg@arm.comExport('CompoundFlag') 31211408Sandreas.sandberg@arm.com 31311408Sandreas.sandberg@arm.com######################################################################## 31411408Sandreas.sandberg@arm.com# 31511408Sandreas.sandberg@arm.com# Set some compiler variables 3168336Ssteve.reinhardt@amd.com# 31711401Sandreas.sandberg@arm.com 31811401Sandreas.sandberg@arm.com# Include file paths are rooted in this directory. SCons will 31911401Sandreas.sandberg@arm.com# automatically expand '.' to refer to both the source directory and 3205871Snate@binkert.org# the corresponding build directory to pick up generated include 3218336Ssteve.reinhardt@amd.com# files. 3228336Ssteve.reinhardt@amd.comenv.Append(CPPPATH=Dir('.')) 32311401Sandreas.sandberg@arm.com 32411401Sandreas.sandberg@arm.comfor extra_dir in extras_dir_list: 32511401Sandreas.sandberg@arm.com env.Append(CPPPATH=Dir(extra_dir)) 32611401Sandreas.sandberg@arm.com 32711401Sandreas.sandberg@arm.com# Workaround for bug in SCons version > 0.97d20071212 3284678Snate@binkert.org# Scons bug id: 2006 gem5 Bug id: 308 3295871Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True): 3304678Snate@binkert.org Dir(root[len(base_dir) + 1:]) 33111401Sandreas.sandberg@arm.com 33211401Sandreas.sandberg@arm.com######################################################################## 33311401Sandreas.sandberg@arm.com# 33411401Sandreas.sandberg@arm.com# Walk the tree and execute all SConscripts in subdirectories 33511401Sandreas.sandberg@arm.com# 33611401Sandreas.sandberg@arm.com 33711401Sandreas.sandberg@arm.comhere = Dir('.').srcnode().abspath 33811401Sandreas.sandberg@arm.comfor root, dirs, files in os.walk(base_dir, topdown=True): 33911401Sandreas.sandberg@arm.com if root == here: 34011401Sandreas.sandberg@arm.com # we don't want to recurse back into this SConscript 34111401Sandreas.sandberg@arm.com continue 34211401Sandreas.sandberg@arm.com 34311450Sandreas.sandberg@arm.com if 'SConscript' in files: 34411450Sandreas.sandberg@arm.com build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 34511450Sandreas.sandberg@arm.com SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 34611450Sandreas.sandberg@arm.com 34711450Sandreas.sandberg@arm.comfor extra_dir in extras_dir_list: 34811450Sandreas.sandberg@arm.com prefix_len = len(dirname(extra_dir)) + 1 34911450Sandreas.sandberg@arm.com 35011450Sandreas.sandberg@arm.com # Also add the corresponding build directory to pick up generated 35111450Sandreas.sandberg@arm.com # include files. 35211450Sandreas.sandberg@arm.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 35311450Sandreas.sandberg@arm.com 35411401Sandreas.sandberg@arm.com for root, dirs, files in os.walk(extra_dir, topdown=True): 35511450Sandreas.sandberg@arm.com # if build lives in the extras directory, don't walk down it 35611450Sandreas.sandberg@arm.com if 'build' in dirs: 35711450Sandreas.sandberg@arm.com dirs.remove('build') 35811401Sandreas.sandberg@arm.com 35911450Sandreas.sandberg@arm.com if 'SConscript' in files: 36011401Sandreas.sandberg@arm.com build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 3618336Ssteve.reinhardt@amd.com SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3628336Ssteve.reinhardt@amd.com 3638336Ssteve.reinhardt@amd.comfor opt in export_vars: 3648336Ssteve.reinhardt@amd.com env.ConfigFile(opt) 3658336Ssteve.reinhardt@amd.com 3668336Ssteve.reinhardt@amd.comdef makeTheISA(source, target, env): 3678336Ssteve.reinhardt@amd.com isas = [ src.get_contents() for src in source ] 3688336Ssteve.reinhardt@amd.com target_isa = env['TARGET_ISA'] 3698336Ssteve.reinhardt@amd.com def define(isa): 3708336Ssteve.reinhardt@amd.com return isa.upper() + '_ISA' 37111401Sandreas.sandberg@arm.com 37211401Sandreas.sandberg@arm.com def namespace(isa): 3738336Ssteve.reinhardt@amd.com return isa[0].upper() + isa[1:].lower() + 'ISA' 3748336Ssteve.reinhardt@amd.com 3758336Ssteve.reinhardt@amd.com 3765871Snate@binkert.org code = code_formatter() 37711476Sandreas.sandberg@arm.com code('''\ 37811476Sandreas.sandberg@arm.com#ifndef __CONFIG_THE_ISA_HH__ 37911476Sandreas.sandberg@arm.com#define __CONFIG_THE_ISA_HH__ 38011476Sandreas.sandberg@arm.com 38111476Sandreas.sandberg@arm.com''') 38211476Sandreas.sandberg@arm.com 38311476Sandreas.sandberg@arm.com # create defines for the preprocessing and compile-time determination 38411476Sandreas.sandberg@arm.com for i,isa in enumerate(isas): 38511476Sandreas.sandberg@arm.com code('#define $0 $1', define(isa), i + 1) 38611887Sandreas.sandberg@arm.com code() 38711887Sandreas.sandberg@arm.com 38811887Sandreas.sandberg@arm.com # create an enum for any run-time determination of the ISA, we 38911408Sandreas.sandberg@arm.com # reuse the same name as the namespaces 39011887Sandreas.sandberg@arm.com code('enum class Arch {') 39111887Sandreas.sandberg@arm.com for i,isa in enumerate(isas): 39211887Sandreas.sandberg@arm.com if i + 1 == len(isas): 39311887Sandreas.sandberg@arm.com code(' $0 = $1', namespace(isa), define(isa)) 39411887Sandreas.sandberg@arm.com else: 39511887Sandreas.sandberg@arm.com code(' $0 = $1,', namespace(isa), define(isa)) 39611926Sgabeblack@google.com code('};') 39711926Sgabeblack@google.com 39811926Sgabeblack@google.com code(''' 39911926Sgabeblack@google.com 40011887Sandreas.sandberg@arm.com#define THE_ISA ${{define(target_isa)}} 40111887Sandreas.sandberg@arm.com#define TheISA ${{namespace(target_isa)}} 40211944Sandreas.sandberg@arm.com#define THE_ISA_STR "${{target_isa}}" 40311887Sandreas.sandberg@arm.com 40411927Sgabeblack@google.com#endif // __CONFIG_THE_ISA_HH__''') 40511927Sgabeblack@google.com 40611927Sgabeblack@google.com code.write(str(target[0])) 40711927Sgabeblack@google.com 40811927Sgabeblack@google.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 40911927Sgabeblack@google.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 41011887Sandreas.sandberg@arm.com 41111928Sgabeblack@google.comdef makeTheGPUISA(source, target, env): 41211928Sgabeblack@google.com isas = [ src.get_contents() for src in source ] 41311887Sandreas.sandberg@arm.com target_gpu_isa = env['TARGET_GPU_ISA'] 41411887Sandreas.sandberg@arm.com def define(isa): 41511887Sandreas.sandberg@arm.com return isa.upper() + '_ISA' 41611887Sandreas.sandberg@arm.com 41711887Sandreas.sandberg@arm.com def namespace(isa): 41811887Sandreas.sandberg@arm.com return isa[0].upper() + isa[1:].lower() + 'ISA' 41911887Sandreas.sandberg@arm.com 42011887Sandreas.sandberg@arm.com 42111887Sandreas.sandberg@arm.com code = code_formatter() 42211887Sandreas.sandberg@arm.com code('''\ 42311476Sandreas.sandberg@arm.com#ifndef __CONFIG_THE_GPU_ISA_HH__ 42411476Sandreas.sandberg@arm.com#define __CONFIG_THE_GPU_ISA_HH__ 42511408Sandreas.sandberg@arm.com 42611408Sandreas.sandberg@arm.com''') 42711408Sandreas.sandberg@arm.com 42811408Sandreas.sandberg@arm.com # create defines for the preprocessing and compile-time determination 42911408Sandreas.sandberg@arm.com for i,isa in enumerate(isas): 43011408Sandreas.sandberg@arm.com code('#define $0 $1', define(isa), i + 1) 43111408Sandreas.sandberg@arm.com code() 43211887Sandreas.sandberg@arm.com 43311887Sandreas.sandberg@arm.com # create an enum for any run-time determination of the ISA, we 43411476Sandreas.sandberg@arm.com # reuse the same name as the namespaces 43511887Sandreas.sandberg@arm.com code('enum class GPUArch {') 43611887Sandreas.sandberg@arm.com for i,isa in enumerate(isas): 43711476Sandreas.sandberg@arm.com if i + 1 == len(isas): 43811476Sandreas.sandberg@arm.com code(' $0 = $1', namespace(isa), define(isa)) 43911476Sandreas.sandberg@arm.com else: 44011476Sandreas.sandberg@arm.com code(' $0 = $1,', namespace(isa), define(isa)) 4416121Snate@binkert.org code('};') 442955SN/A 443955SN/A code(''' 4442632Sstever@eecs.umich.edu 4452632Sstever@eecs.umich.edu#define THE_GPU_ISA ${{define(target_gpu_isa)}} 446955SN/A#define TheGpuISA ${{namespace(target_gpu_isa)}} 447955SN/A#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 448955SN/A 449955SN/A#endif // __CONFIG_THE_GPU_ISA_HH__''') 4508878Ssteve.reinhardt@amd.com 451955SN/A code.write(str(target[0])) 4522632Sstever@eecs.umich.edu 4532632Sstever@eecs.umich.eduenv.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 4542632Sstever@eecs.umich.edu MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 4552632Sstever@eecs.umich.edu 4562632Sstever@eecs.umich.edu######################################################################## 4572632Sstever@eecs.umich.edu# 4582632Sstever@eecs.umich.edu# Prevent any SimObjects from being added after this point, they 4598268Ssteve.reinhardt@amd.com# should all have been added in the SConscripts above 4608268Ssteve.reinhardt@amd.com# 4618268Ssteve.reinhardt@amd.comSimObject.fixed = True 4628268Ssteve.reinhardt@amd.com 4638268Ssteve.reinhardt@amd.comclass DictImporter(object): 4648268Ssteve.reinhardt@amd.com '''This importer takes a dictionary of arbitrary module names that 4658268Ssteve.reinhardt@amd.com map to arbitrary filenames.''' 4662632Sstever@eecs.umich.edu def __init__(self, modules): 4672632Sstever@eecs.umich.edu self.modules = modules 4682632Sstever@eecs.umich.edu self.installed = set() 4692632Sstever@eecs.umich.edu 4708268Ssteve.reinhardt@amd.com def __del__(self): 4712632Sstever@eecs.umich.edu self.unload() 4728268Ssteve.reinhardt@amd.com 4738268Ssteve.reinhardt@amd.com def unload(self): 4748268Ssteve.reinhardt@amd.com import sys 4758268Ssteve.reinhardt@amd.com for module in self.installed: 4763718Sstever@eecs.umich.edu del sys.modules[module] 4772634Sstever@eecs.umich.edu self.installed = set() 4782634Sstever@eecs.umich.edu 4795863Snate@binkert.org def find_module(self, fullname, path): 4802638Sstever@eecs.umich.edu if fullname == 'm5.defines': 4818268Ssteve.reinhardt@amd.com return self 4822632Sstever@eecs.umich.edu 4832632Sstever@eecs.umich.edu if fullname == 'm5.objects': 4842632Sstever@eecs.umich.edu return self 4852632Sstever@eecs.umich.edu 4862632Sstever@eecs.umich.edu if fullname.startswith('m5.internal'): 4871858SN/A return None 4883716Sstever@eecs.umich.edu 4892638Sstever@eecs.umich.edu source = self.modules.get(fullname, None) 4902638Sstever@eecs.umich.edu if source is not None and fullname.startswith('m5.objects'): 4912638Sstever@eecs.umich.edu return self 4922638Sstever@eecs.umich.edu 4932638Sstever@eecs.umich.edu return None 4942638Sstever@eecs.umich.edu 4952638Sstever@eecs.umich.edu def load_module(self, fullname): 4965863Snate@binkert.org mod = imp.new_module(fullname) 4975863Snate@binkert.org sys.modules[fullname] = mod 4985863Snate@binkert.org self.installed.add(fullname) 499955SN/A 5005341Sstever@gmail.com mod.__loader__ = self 5015341Sstever@gmail.com if fullname == 'm5.objects': 5025863Snate@binkert.org mod.__path__ = fullname.split('.') 5037756SAli.Saidi@ARM.com return mod 5045341Sstever@gmail.com 5056121Snate@binkert.org if fullname == 'm5.defines': 5064494Ssaidi@eecs.umich.edu mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 5076121Snate@binkert.org return mod 5081105SN/A 5092667Sstever@eecs.umich.edu source = self.modules[fullname] 5102667Sstever@eecs.umich.edu if source.modname == '__init__': 5112667Sstever@eecs.umich.edu mod.__path__ = source.modpath 5122667Sstever@eecs.umich.edu mod.__file__ = source.abspath 5136121Snate@binkert.org 5142667Sstever@eecs.umich.edu exec file(source.abspath, 'r') in mod.__dict__ 5155341Sstever@gmail.com 5165863Snate@binkert.org return mod 5175341Sstever@gmail.com 5185341Sstever@gmail.comimport m5.SimObject 5195341Sstever@gmail.comimport m5.params 5208120Sgblack@eecs.umich.edufrom m5.util import code_formatter 5215341Sstever@gmail.com 5228120Sgblack@eecs.umich.edum5.SimObject.clear() 5235341Sstever@gmail.comm5.params.clear() 5248120Sgblack@eecs.umich.edu 5256121Snate@binkert.org# install the python importer so we can grab stuff from the source 5266121Snate@binkert.org# tree itself. We can't have SimObjects added after this point or 5278980Ssteve.reinhardt@amd.com# else we won't know about them for the rest of the stuff. 5289396Sandreas.hansson@arm.comimporter = DictImporter(PySource.modules) 5295397Ssaidi@eecs.umich.edusys.meta_path[0:0] = [ importer ] 5305397Ssaidi@eecs.umich.edu 5317727SAli.Saidi@ARM.com# import all sim objects so we can populate the all_objects list 5328268Ssteve.reinhardt@amd.com# make sure that we're working with a list, then let's sort it 5336168Snate@binkert.orgfor modname in SimObject.modnames: 5345341Sstever@gmail.com exec('from m5.objects import %s' % modname) 5358120Sgblack@eecs.umich.edu 5368120Sgblack@eecs.umich.edu# we need to unload all of the currently imported modules so that they 5378120Sgblack@eecs.umich.edu# will be re-imported the next time the sconscript is run 5386814Sgblack@eecs.umich.eduimporter.unload() 5395863Snate@binkert.orgsys.meta_path.remove(importer) 5408120Sgblack@eecs.umich.edu 5415341Sstever@gmail.comsim_objects = m5.SimObject.allClasses 5425863Snate@binkert.orgall_enums = m5.params.allEnums 5438268Ssteve.reinhardt@amd.com 5446121Snate@binkert.orgif m5.SimObject.noCxxHeader: 5456121Snate@binkert.org print >> sys.stderr, \ 5468268Ssteve.reinhardt@amd.com "warning: At least one SimObject lacks a header specification. " \ 5475742Snate@binkert.org "This can cause unexpected results in the generated SWIG " \ 5485742Snate@binkert.org "wrappers." 5495341Sstever@gmail.com 5505742Snate@binkert.org# Find param types that need to be explicitly wrapped with swig. 5515742Snate@binkert.org# These will be recognized because the ParamDesc will have a 5525341Sstever@gmail.com# swig_decl() method. Most param types are based on types that don't 5536017Snate@binkert.org# need this, either because they're based on native types (like Int) 5546121Snate@binkert.org# or because they're SimObjects (which get swigged independently). 5556017Snate@binkert.org# For now the only things handled here are VectorParam types. 5567816Ssteve.reinhardt@amd.comparams_to_swig = {} 5577756SAli.Saidi@ARM.comfor name,obj in sorted(sim_objects.iteritems()): 5587756SAli.Saidi@ARM.com for param in obj._params.local.values(): 5597756SAli.Saidi@ARM.com # load the ptype attribute now because it depends on the 5607756SAli.Saidi@ARM.com # current version of SimObject.allClasses, but when scons 5617756SAli.Saidi@ARM.com # actually uses the value, all versions of 5627756SAli.Saidi@ARM.com # SimObject.allClasses will have been loaded 5637756SAli.Saidi@ARM.com param.ptype 5647756SAli.Saidi@ARM.com 5657816Ssteve.reinhardt@amd.com if not hasattr(param, 'swig_decl'): 5667816Ssteve.reinhardt@amd.com continue 5677816Ssteve.reinhardt@amd.com pname = param.ptype_str 5687816Ssteve.reinhardt@amd.com if pname not in params_to_swig: 5697816Ssteve.reinhardt@amd.com params_to_swig[pname] = param 5707816Ssteve.reinhardt@amd.com 5717816Ssteve.reinhardt@amd.com######################################################################## 5727816Ssteve.reinhardt@amd.com# 5737816Ssteve.reinhardt@amd.com# calculate extra dependencies 5747816Ssteve.reinhardt@amd.com# 5757756SAli.Saidi@ARM.commodule_depends = ["m5", "m5.SimObject", "m5.params"] 5767816Ssteve.reinhardt@amd.comdepends = [ PySource.modules[dep].snode for dep in module_depends ] 5777816Ssteve.reinhardt@amd.comdepends.sort(key = lambda x: x.name) 5787816Ssteve.reinhardt@amd.com 5797816Ssteve.reinhardt@amd.com######################################################################## 5807816Ssteve.reinhardt@amd.com# 5817816Ssteve.reinhardt@amd.com# Commands for the basic automatically generated python files 5827816Ssteve.reinhardt@amd.com# 5837816Ssteve.reinhardt@amd.com 5847816Ssteve.reinhardt@amd.com# Generate Python file containing a dict specifying the current 5857816Ssteve.reinhardt@amd.com# buildEnv flags. 5867816Ssteve.reinhardt@amd.comdef makeDefinesPyFile(target, source, env): 5877816Ssteve.reinhardt@amd.com build_env = source[0].get_contents() 5887816Ssteve.reinhardt@amd.com 5897816Ssteve.reinhardt@amd.com code = code_formatter() 5907816Ssteve.reinhardt@amd.com code(""" 5917816Ssteve.reinhardt@amd.comimport m5.internal 5927816Ssteve.reinhardt@amd.comimport m5.util 5937816Ssteve.reinhardt@amd.com 5947816Ssteve.reinhardt@amd.combuildEnv = m5.util.SmartDict($build_env) 5957816Ssteve.reinhardt@amd.com 5967816Ssteve.reinhardt@amd.comcompileDate = m5.internal.core.compileDate 5977816Ssteve.reinhardt@amd.com_globals = globals() 5987816Ssteve.reinhardt@amd.comfor key,val in m5.internal.core.__dict__.iteritems(): 5997816Ssteve.reinhardt@amd.com if key.startswith('flag_'): 6007816Ssteve.reinhardt@amd.com flag = key[5:] 6017816Ssteve.reinhardt@amd.com _globals[flag] = val 6027816Ssteve.reinhardt@amd.comdel _globals 6037816Ssteve.reinhardt@amd.com""") 6047816Ssteve.reinhardt@amd.com code.write(target[0].abspath) 6057816Ssteve.reinhardt@amd.com 6067816Ssteve.reinhardt@amd.comdefines_info = Value(build_env) 6077816Ssteve.reinhardt@amd.com# Generate a file with all of the compile options in it 6087816Ssteve.reinhardt@amd.comenv.Command('python/m5/defines.py', defines_info, 6097816Ssteve.reinhardt@amd.com MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 6107816Ssteve.reinhardt@amd.comPySource('m5', 'python/m5/defines.py') 6117816Ssteve.reinhardt@amd.com 6127816Ssteve.reinhardt@amd.com# Generate python file containing info about the M5 source code 6137816Ssteve.reinhardt@amd.comdef makeInfoPyFile(target, source, env): 6147816Ssteve.reinhardt@amd.com code = code_formatter() 6157816Ssteve.reinhardt@amd.com for src in source: 6167816Ssteve.reinhardt@amd.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 6177816Ssteve.reinhardt@amd.com code('$src = ${{repr(data)}}') 6187816Ssteve.reinhardt@amd.com code.write(str(target[0])) 6197816Ssteve.reinhardt@amd.com 6207816Ssteve.reinhardt@amd.com# Generate a file that wraps the basic top level files 6217816Ssteve.reinhardt@amd.comenv.Command('python/m5/info.py', 6227816Ssteve.reinhardt@amd.com [ '#/COPYING', '#/LICENSE', '#/README', ], 6237816Ssteve.reinhardt@amd.com MakeAction(makeInfoPyFile, Transform("INFO"))) 6247816Ssteve.reinhardt@amd.comPySource('m5', 'python/m5/info.py') 6257816Ssteve.reinhardt@amd.com 6267816Ssteve.reinhardt@amd.com######################################################################## 6277816Ssteve.reinhardt@amd.com# 6287816Ssteve.reinhardt@amd.com# Create all of the SimObject param headers and enum headers 6297816Ssteve.reinhardt@amd.com# 6307816Ssteve.reinhardt@amd.com 6317816Ssteve.reinhardt@amd.comdef createSimObjectParamStruct(target, source, env): 6327816Ssteve.reinhardt@amd.com assert len(target) == 1 and len(source) == 1 6337816Ssteve.reinhardt@amd.com 6347816Ssteve.reinhardt@amd.com name = str(source[0].get_contents()) 6357816Ssteve.reinhardt@amd.com obj = sim_objects[name] 6367816Ssteve.reinhardt@amd.com 6378947Sandreas.hansson@arm.com code = code_formatter() 6388947Sandreas.hansson@arm.com obj.cxx_param_decl(code) 6397756SAli.Saidi@ARM.com code.write(target[0].abspath) 6408120Sgblack@eecs.umich.edu 6417756SAli.Saidi@ARM.comdef createSimObjectCxxConfig(is_header): 6427756SAli.Saidi@ARM.com def body(target, source, env): 6437756SAli.Saidi@ARM.com assert len(target) == 1 and len(source) == 1 6447756SAli.Saidi@ARM.com 6457816Ssteve.reinhardt@amd.com name = str(source[0].get_contents()) 6467816Ssteve.reinhardt@amd.com obj = sim_objects[name] 6477816Ssteve.reinhardt@amd.com 6487816Ssteve.reinhardt@amd.com code = code_formatter() 6497816Ssteve.reinhardt@amd.com obj.cxx_config_param_file(code, is_header) 6507816Ssteve.reinhardt@amd.com code.write(target[0].abspath) 6517816Ssteve.reinhardt@amd.com return body 6527816Ssteve.reinhardt@amd.com 6537816Ssteve.reinhardt@amd.comdef createParamSwigWrapper(target, source, env): 6547816Ssteve.reinhardt@amd.com assert len(target) == 1 and len(source) == 1 6557756SAli.Saidi@ARM.com 6567756SAli.Saidi@ARM.com name = str(source[0].get_contents()) 6579227Sandreas.hansson@arm.com param = params_to_swig[name] 6589227Sandreas.hansson@arm.com 6599227Sandreas.hansson@arm.com code = code_formatter() 6609227Sandreas.hansson@arm.com param.swig_decl(code) 6619590Sandreas@sandberg.pp.se code.write(target[0].abspath) 6629590Sandreas@sandberg.pp.se 6639590Sandreas@sandberg.pp.sedef createEnumStrings(target, source, env): 6649590Sandreas@sandberg.pp.se assert len(target) == 1 and len(source) == 1 6659590Sandreas@sandberg.pp.se 6669590Sandreas@sandberg.pp.se name = str(source[0].get_contents()) 6676654Snate@binkert.org obj = all_enums[name] 6686654Snate@binkert.org 6695871Snate@binkert.org code = code_formatter() 6706121Snate@binkert.org obj.cxx_def(code) 6718946Sandreas.hansson@arm.com code.write(target[0].abspath) 6729419Sandreas.hansson@arm.com 6733940Ssaidi@eecs.umich.edudef createEnumDecls(target, source, env): 6743918Ssaidi@eecs.umich.edu assert len(target) == 1 and len(source) == 1 6753918Ssaidi@eecs.umich.edu 6761858SN/A name = str(source[0].get_contents()) 6779556Sandreas.hansson@arm.com obj = all_enums[name] 6789556Sandreas.hansson@arm.com 6799556Sandreas.hansson@arm.com code = code_formatter() 6809556Sandreas.hansson@arm.com obj.cxx_decl(code) 68111294Sandreas.hansson@arm.com code.write(target[0].abspath) 68211294Sandreas.hansson@arm.com 68311294Sandreas.hansson@arm.comdef createEnumSwigWrapper(target, source, env): 68411294Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 68510878Sandreas.hansson@arm.com 68610878Sandreas.hansson@arm.com name = str(source[0].get_contents()) 68711811Sbaz21@cam.ac.uk obj = all_enums[name] 68811811Sbaz21@cam.ac.uk 68911811Sbaz21@cam.ac.uk code = code_formatter() 6909556Sandreas.hansson@arm.com obj.swig_decl(code) 6919556Sandreas.hansson@arm.com code.write(target[0].abspath) 6929556Sandreas.hansson@arm.com 6939556Sandreas.hansson@arm.comdef createSimObjectSwigWrapper(target, source, env): 6949556Sandreas.hansson@arm.com name = source[0].get_contents() 6959556Sandreas.hansson@arm.com obj = sim_objects[name] 6969556Sandreas.hansson@arm.com 6979556Sandreas.hansson@arm.com code = code_formatter() 6989556Sandreas.hansson@arm.com obj.swig_decl(code) 6999556Sandreas.hansson@arm.com code.write(target[0].abspath) 7009556Sandreas.hansson@arm.com 7019556Sandreas.hansson@arm.com# dummy target for generated code 7029556Sandreas.hansson@arm.com# we start out with all the Source files so they get copied to build/*/ also. 7039556Sandreas.hansson@arm.comSWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 7049556Sandreas.hansson@arm.com 7059556Sandreas.hansson@arm.com# Generate all of the SimObject param C++ struct header files 7069556Sandreas.hansson@arm.comparams_hh_files = [] 7079556Sandreas.hansson@arm.comfor name,simobj in sorted(sim_objects.iteritems()): 7089556Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 7096121Snate@binkert.org extra_deps = [ py_source.tnode ] 71011500Sandreas.hansson@arm.com 71110238Sandreas.hansson@arm.com hh_file = File('params/%s.hh' % name) 71210878Sandreas.hansson@arm.com params_hh_files.append(hh_file) 7139420Sandreas.hansson@arm.com env.Command(hh_file, Value(name), 71411500Sandreas.hansson@arm.com MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 71511500Sandreas.hansson@arm.com env.Depends(hh_file, depends + extra_deps) 7169420Sandreas.hansson@arm.com env.Depends(SWIG, hh_file) 7179420Sandreas.hansson@arm.com 7189420Sandreas.hansson@arm.com# C++ parameter description files 7199420Sandreas.hansson@arm.comif GetOption('with_cxx_config'): 7209420Sandreas.hansson@arm.com for name,simobj in sorted(sim_objects.iteritems()): 72110264Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 72210264Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 72310264Sandreas.hansson@arm.com 72410264Sandreas.hansson@arm.com cxx_config_hh_file = File('cxx_config/%s.hh' % name) 72511925Sgabeblack@google.com cxx_config_cc_file = File('cxx_config/%s.cc' % name) 72611925Sgabeblack@google.com env.Command(cxx_config_hh_file, Value(name), 72711500Sandreas.hansson@arm.com MakeAction(createSimObjectCxxConfig(True), 72810264Sandreas.hansson@arm.com Transform("CXXCPRHH"))) 72911500Sandreas.hansson@arm.com env.Command(cxx_config_cc_file, Value(name), 73011500Sandreas.hansson@arm.com MakeAction(createSimObjectCxxConfig(False), 73111500Sandreas.hansson@arm.com Transform("CXXCPRCC"))) 73211500Sandreas.hansson@arm.com env.Depends(cxx_config_hh_file, depends + extra_deps + 73310866Sandreas.hansson@arm.com [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 73411500Sandreas.hansson@arm.com env.Depends(cxx_config_cc_file, depends + extra_deps + 73511500Sandreas.hansson@arm.com [cxx_config_hh_file]) 73611500Sandreas.hansson@arm.com Source(cxx_config_cc_file) 73711500Sandreas.hansson@arm.com 73811500Sandreas.hansson@arm.com cxx_config_init_cc_file = File('cxx_config/init.cc') 73911500Sandreas.hansson@arm.com 74011500Sandreas.hansson@arm.com def createCxxConfigInitCC(target, source, env): 74110264Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 74210457Sandreas.hansson@arm.com 74310457Sandreas.hansson@arm.com code = code_formatter() 74410457Sandreas.hansson@arm.com 74510457Sandreas.hansson@arm.com for name,simobj in sorted(sim_objects.iteritems()): 74610457Sandreas.hansson@arm.com if not hasattr(simobj, 'abstract') or not simobj.abstract: 74710457Sandreas.hansson@arm.com code('#include "cxx_config/${name}.hh"') 74810457Sandreas.hansson@arm.com code() 74910457Sandreas.hansson@arm.com code('void cxxConfigInit()') 75010457Sandreas.hansson@arm.com code('{') 75110238Sandreas.hansson@arm.com code.indent() 75210238Sandreas.hansson@arm.com for name,simobj in sorted(sim_objects.iteritems()): 75310238Sandreas.hansson@arm.com not_abstract = not hasattr(simobj, 'abstract') or \ 75410238Sandreas.hansson@arm.com not simobj.abstract 75510238Sandreas.hansson@arm.com if not_abstract and 'type' in simobj.__dict__: 75610238Sandreas.hansson@arm.com code('cxx_config_directory["${name}"] = ' 75710416Sandreas.hansson@arm.com '${name}CxxConfigParams::makeDirectoryEntry();') 75810238Sandreas.hansson@arm.com code.dedent() 7599227Sandreas.hansson@arm.com code('}') 76010238Sandreas.hansson@arm.com code.write(target[0].abspath) 76110416Sandreas.hansson@arm.com 76210416Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 7639227Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 7649590Sandreas@sandberg.pp.se env.Command(cxx_config_init_cc_file, Value(name), 7659590Sandreas@sandberg.pp.se MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 7669590Sandreas@sandberg.pp.se cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 76711497SMatteo.Andreozzi@arm.com for name,simobj in sorted(sim_objects.iteritems()) 76811497SMatteo.Andreozzi@arm.com if not hasattr(simobj, 'abstract') or not simobj.abstract] 76911497SMatteo.Andreozzi@arm.com Depends(cxx_config_init_cc_file, cxx_param_hh_files + 77011497SMatteo.Andreozzi@arm.com [File('sim/cxx_config.hh')]) 7718737Skoansin.tan@gmail.com Source(cxx_config_init_cc_file) 77210878Sandreas.hansson@arm.com 77311500Sandreas.hansson@arm.com# Generate any needed param SWIG wrapper files 7749420Sandreas.hansson@arm.comparams_i_files = [] 7758737Skoansin.tan@gmail.comfor name,param in sorted(params_to_swig.iteritems()): 77610106SMitch.Hayenga@arm.com i_file = File('python/m5/internal/%s.i' % (param.swig_module_name())) 7778737Skoansin.tan@gmail.com params_i_files.append(i_file) 7788737Skoansin.tan@gmail.com env.Command(i_file, Value(name), 77910878Sandreas.hansson@arm.com MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 78010878Sandreas.hansson@arm.com env.Depends(i_file, depends) 7818737Skoansin.tan@gmail.com env.Depends(SWIG, i_file) 7828737Skoansin.tan@gmail.com SwigSource('m5.internal', i_file) 7838737Skoansin.tan@gmail.com 7848737Skoansin.tan@gmail.com# Generate all enum header files 7858737Skoansin.tan@gmail.comfor name,enum in sorted(all_enums.iteritems()): 7868737Skoansin.tan@gmail.com py_source = PySource.modules[enum.__module__] 78711294Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 7889556Sandreas.hansson@arm.com 7899556Sandreas.hansson@arm.com cc_file = File('enums/%s.cc' % name) 7909556Sandreas.hansson@arm.com env.Command(cc_file, Value(name), 79111294Sandreas.hansson@arm.com MakeAction(createEnumStrings, Transform("ENUM STR"))) 79210278SAndreas.Sandberg@ARM.com env.Depends(cc_file, depends + extra_deps) 79310278SAndreas.Sandberg@ARM.com env.Depends(SWIG, cc_file) 79410278SAndreas.Sandberg@ARM.com Source(cc_file) 79510278SAndreas.Sandberg@ARM.com 79610278SAndreas.Sandberg@ARM.com hh_file = File('enums/%s.hh' % name) 79710278SAndreas.Sandberg@ARM.com env.Command(hh_file, Value(name), 7989556Sandreas.hansson@arm.com MakeAction(createEnumDecls, Transform("ENUMDECL"))) 7999590Sandreas@sandberg.pp.se env.Depends(hh_file, depends + extra_deps) 8009590Sandreas@sandberg.pp.se env.Depends(SWIG, hh_file) 8019420Sandreas.hansson@arm.com 8029846Sandreas.hansson@arm.com i_file = File('python/m5/internal/enum_%s.i' % name) 8039846Sandreas.hansson@arm.com env.Command(i_file, Value(name), 8049846Sandreas.hansson@arm.com MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 8059846Sandreas.hansson@arm.com env.Depends(i_file, depends + extra_deps) 8068946Sandreas.hansson@arm.com env.Depends(SWIG, i_file) 80711811Sbaz21@cam.ac.uk SwigSource('m5.internal', i_file) 80811811Sbaz21@cam.ac.uk 80911811Sbaz21@cam.ac.uk# Generate SimObject SWIG wrapper files 81011811Sbaz21@cam.ac.ukfor name,simobj in sorted(sim_objects.iteritems()): 8113918Ssaidi@eecs.umich.edu py_source = PySource.modules[simobj.__module__] 8129068SAli.Saidi@ARM.com extra_deps = [ py_source.tnode ] 8139068SAli.Saidi@ARM.com i_file = File('python/m5/internal/param_%s.i' % name) 8149068SAli.Saidi@ARM.com env.Command(i_file, Value(name), 8159068SAli.Saidi@ARM.com MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 8169068SAli.Saidi@ARM.com env.Depends(i_file, depends + extra_deps) 8179068SAli.Saidi@ARM.com SwigSource('m5.internal', i_file) 8189068SAli.Saidi@ARM.com 8199068SAli.Saidi@ARM.com# Generate the main swig init file 8209068SAli.Saidi@ARM.comdef makeEmbeddedSwigInit(package): 8219419Sandreas.hansson@arm.com def body(target, source, env): 8229068SAli.Saidi@ARM.com assert len(target) == 1 and len(source) == 1 8239068SAli.Saidi@ARM.com 8249068SAli.Saidi@ARM.com code = code_formatter() 8259068SAli.Saidi@ARM.com module = source[0].get_contents() 8269068SAli.Saidi@ARM.com # Provide the full context so that the swig-generated call to 8279068SAli.Saidi@ARM.com # Py_InitModule ends up placing the embedded module in the 8283918Ssaidi@eecs.umich.edu # right package. 8293918Ssaidi@eecs.umich.edu context = str(package) + "._" + str(module) 8306157Snate@binkert.org code('''\ 8316157Snate@binkert.org #include "sim/init.hh" 8326157Snate@binkert.org 8336157Snate@binkert.org extern "C" { 8345397Ssaidi@eecs.umich.edu void init_${module}(); 8355397Ssaidi@eecs.umich.edu } 8366121Snate@binkert.org 8376121Snate@binkert.org EmbeddedSwig embed_swig_${module}(init_${module}, "${context}"); 8386121Snate@binkert.org ''') 8396121Snate@binkert.org code.write(str(target[0])) 8406121Snate@binkert.org return body 8416121Snate@binkert.org 8425397Ssaidi@eecs.umich.edu# Build all swig modules 8431851SN/Afor swig in SwigSource.all: 8441851SN/A env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 8457739Sgblack@eecs.umich.edu MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 846955SN/A '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 8479396Sandreas.hansson@arm.com cc_file = str(swig.tnode) 8489396Sandreas.hansson@arm.com init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 8499396Sandreas.hansson@arm.com env.Command(init_file, Value(swig.module), 8509396Sandreas.hansson@arm.com MakeAction(makeEmbeddedSwigInit(swig.package), 8519396Sandreas.hansson@arm.com Transform("EMBED SW"))) 8529396Sandreas.hansson@arm.com env.Depends(SWIG, init_file) 8539396Sandreas.hansson@arm.com Source(init_file, **swig.guards) 8549396Sandreas.hansson@arm.com 8559396Sandreas.hansson@arm.com# Build all protocol buffers if we have got protoc and protobuf available 8569396Sandreas.hansson@arm.comif env['HAVE_PROTOBUF']: 8579396Sandreas.hansson@arm.com for proto in ProtoBuf.all: 8589396Sandreas.hansson@arm.com # Use both the source and header as the target, and the .proto 8599396Sandreas.hansson@arm.com # file as the source. When executing the protoc compiler, also 8609396Sandreas.hansson@arm.com # specify the proto_path to avoid having the generated files 8619396Sandreas.hansson@arm.com # include the path. 8629396Sandreas.hansson@arm.com env.Command([proto.cc_file, proto.hh_file], proto.tnode, 8639477Sandreas.hansson@arm.com MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 8649477Sandreas.hansson@arm.com '--proto_path ${SOURCE.dir} $SOURCE', 8659477Sandreas.hansson@arm.com Transform("PROTOC"))) 8669477Sandreas.hansson@arm.com 8679477Sandreas.hansson@arm.com env.Depends(SWIG, [proto.cc_file, proto.hh_file]) 8689477Sandreas.hansson@arm.com # Add the C++ source file 8699477Sandreas.hansson@arm.com Source(proto.cc_file, **proto.guards) 8709477Sandreas.hansson@arm.comelif ProtoBuf.all: 8719477Sandreas.hansson@arm.com print 'Got protobuf to build, but lacks support!' 8729477Sandreas.hansson@arm.com Exit(1) 8739477Sandreas.hansson@arm.com 8749477Sandreas.hansson@arm.com# 8759477Sandreas.hansson@arm.com# Handle debug flags 8769477Sandreas.hansson@arm.com# 8779477Sandreas.hansson@arm.comdef makeDebugFlagCC(target, source, env): 8789477Sandreas.hansson@arm.com assert(len(target) == 1 and len(source) == 1) 8799477Sandreas.hansson@arm.com 8809477Sandreas.hansson@arm.com code = code_formatter() 8819477Sandreas.hansson@arm.com 8829477Sandreas.hansson@arm.com # delay definition of CompoundFlags until after all the definition 8839477Sandreas.hansson@arm.com # of all constituent SimpleFlags 8849477Sandreas.hansson@arm.com comp_code = code_formatter() 8859396Sandreas.hansson@arm.com 8863053Sstever@eecs.umich.edu # file header 8876121Snate@binkert.org code(''' 8883053Sstever@eecs.umich.edu/* 8893053Sstever@eecs.umich.edu * DO NOT EDIT THIS FILE! Automatically generated by SCons. 8903053Sstever@eecs.umich.edu */ 8913053Sstever@eecs.umich.edu 8923053Sstever@eecs.umich.edu#include "base/debug.hh" 8939072Sandreas.hansson@arm.com 8943053Sstever@eecs.umich.edunamespace Debug { 8954742Sstever@eecs.umich.edu 8964742Sstever@eecs.umich.edu''') 8973053Sstever@eecs.umich.edu 8983053Sstever@eecs.umich.edu for name, flag in sorted(source[0].read().iteritems()): 8993053Sstever@eecs.umich.edu n, compound, desc = flag 90010181SCurtis.Dunham@arm.com assert n == name 9016654Snate@binkert.org 9023053Sstever@eecs.umich.edu if not compound: 9033053Sstever@eecs.umich.edu code('SimpleFlag $name("$name", "$desc");') 9043053Sstever@eecs.umich.edu else: 9053053Sstever@eecs.umich.edu comp_code('CompoundFlag $name("$name", "$desc",') 90610425Sandreas.hansson@arm.com comp_code.indent() 90710425Sandreas.hansson@arm.com last = len(compound) - 1 90810425Sandreas.hansson@arm.com for i,flag in enumerate(compound): 90910425Sandreas.hansson@arm.com if i != last: 91010425Sandreas.hansson@arm.com comp_code('&$flag,') 91110425Sandreas.hansson@arm.com else: 91210425Sandreas.hansson@arm.com comp_code('&$flag);') 91310425Sandreas.hansson@arm.com comp_code.dedent() 91410425Sandreas.hansson@arm.com 91510425Sandreas.hansson@arm.com code.append(comp_code) 91610425Sandreas.hansson@arm.com code() 9172667Sstever@eecs.umich.edu code('} // namespace Debug') 9184554Sbinkertn@umich.edu 9196121Snate@binkert.org code.write(str(target[0])) 9202667Sstever@eecs.umich.edu 92110710Sandreas.hansson@arm.comdef makeDebugFlagHH(target, source, env): 92210710Sandreas.hansson@arm.com assert(len(target) == 1 and len(source) == 1) 92310710Sandreas.hansson@arm.com 92411811Sbaz21@cam.ac.uk val = eval(source[0].get_contents()) 92511811Sbaz21@cam.ac.uk name, compound, desc = val 92611811Sbaz21@cam.ac.uk 92711811Sbaz21@cam.ac.uk code = code_formatter() 92811811Sbaz21@cam.ac.uk 92911811Sbaz21@cam.ac.uk # file header boilerplate 93010710Sandreas.hansson@arm.com code('''\ 93110710Sandreas.hansson@arm.com/* 93210710Sandreas.hansson@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 93310710Sandreas.hansson@arm.com */ 93410384SCurtis.Dunham@arm.com 9354554Sbinkertn@umich.edu#ifndef __DEBUG_${name}_HH__ 9364554Sbinkertn@umich.edu#define __DEBUG_${name}_HH__ 9374554Sbinkertn@umich.edu 9386121Snate@binkert.orgnamespace Debug { 9394554Sbinkertn@umich.edu''') 9404554Sbinkertn@umich.edu 9414554Sbinkertn@umich.edu if compound: 9424781Snate@binkert.org code('class CompoundFlag;') 9434554Sbinkertn@umich.edu code('class SimpleFlag;') 9444554Sbinkertn@umich.edu 9452667Sstever@eecs.umich.edu if compound: 9464554Sbinkertn@umich.edu code('extern CompoundFlag $name;') 9474554Sbinkertn@umich.edu for flag in compound: 9484554Sbinkertn@umich.edu code('extern SimpleFlag $flag;') 9494554Sbinkertn@umich.edu else: 9502667Sstever@eecs.umich.edu code('extern SimpleFlag $name;') 9514554Sbinkertn@umich.edu 9522667Sstever@eecs.umich.edu code(''' 9534554Sbinkertn@umich.edu} 9546121Snate@binkert.org 9552667Sstever@eecs.umich.edu#endif // __DEBUG_${name}_HH__ 9569986Sandreas@sandberg.pp.se''') 9579986Sandreas@sandberg.pp.se 9589986Sandreas@sandberg.pp.se code.write(str(target[0])) 9599986Sandreas@sandberg.pp.se 9609986Sandreas@sandberg.pp.sefor name,flag in sorted(debug_flags.iteritems()): 9619986Sandreas@sandberg.pp.se n, compound, desc = flag 9629986Sandreas@sandberg.pp.se assert n == name 9639986Sandreas@sandberg.pp.se 9649986Sandreas@sandberg.pp.se hh_file = 'debug/%s.hh' % name 9659986Sandreas@sandberg.pp.se env.Command(hh_file, Value(flag), 9669986Sandreas@sandberg.pp.se MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 9679986Sandreas@sandberg.pp.se env.Depends(SWIG, hh_file) 9689986Sandreas@sandberg.pp.se 9699986Sandreas@sandberg.pp.seenv.Command('debug/flags.cc', Value(debug_flags), 9709986Sandreas@sandberg.pp.se MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 9719986Sandreas@sandberg.pp.seenv.Depends(SWIG, 'debug/flags.cc') 9729986Sandreas@sandberg.pp.seSource('debug/flags.cc') 9739986Sandreas@sandberg.pp.se 9749986Sandreas@sandberg.pp.se# version tags 9759986Sandreas@sandberg.pp.setags = \ 9762638Sstever@eecs.umich.eduenv.Command('sim/tags.cc', None, 9772638Sstever@eecs.umich.edu MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 9786121Snate@binkert.org Transform("VER TAGS"))) 9793716Sstever@eecs.umich.eduenv.AlwaysBuild(tags) 9805522Snate@binkert.org 9819986Sandreas@sandberg.pp.se# Embed python files. All .py files that have been indicated by a 9829986Sandreas@sandberg.pp.se# PySource() call in a SConscript need to be embedded into the M5 9839986Sandreas@sandberg.pp.se# library. To do that, we compile the file to byte code, marshal the 9845522Snate@binkert.org# byte code, compress it, and then generate a c++ file that 9855227Ssaidi@eecs.umich.edu# inserts the result into an array. 9865227Ssaidi@eecs.umich.edudef embedPyFile(target, source, env): 9875227Ssaidi@eecs.umich.edu def c_str(string): 9885227Ssaidi@eecs.umich.edu if string is None: 9896654Snate@binkert.org return "0" 9906654Snate@binkert.org return '"%s"' % string 9917769SAli.Saidi@ARM.com 9927769SAli.Saidi@ARM.com '''Action function to compile a .py into a code object, marshal 9937769SAli.Saidi@ARM.com it, compress it, and stick it into an asm file so the code appears 9947769SAli.Saidi@ARM.com as just bytes with a label in the data section''' 9955227Ssaidi@eecs.umich.edu 9965227Ssaidi@eecs.umich.edu src = file(str(source[0]), 'r').read() 9975227Ssaidi@eecs.umich.edu 9985204Sstever@gmail.com pysource = PySource.tnodes[source[0]] 9995204Sstever@gmail.com compiled = compile(src, pysource.abspath, 'exec') 10005204Sstever@gmail.com marshalled = marshal.dumps(compiled) 10015204Sstever@gmail.com compressed = zlib.compress(marshalled) 10025204Sstever@gmail.com data = compressed 10035204Sstever@gmail.com sym = pysource.symname 10045204Sstever@gmail.com 10055204Sstever@gmail.com code = code_formatter() 10065204Sstever@gmail.com code('''\ 10075204Sstever@gmail.com#include "sim/init.hh" 10085204Sstever@gmail.com 10095204Sstever@gmail.comnamespace { 10105204Sstever@gmail.com 10115204Sstever@gmail.comconst uint8_t data_${sym}[] = { 10125204Sstever@gmail.com''') 10135204Sstever@gmail.com code.indent() 10145204Sstever@gmail.com step = 16 10156121Snate@binkert.org for i in xrange(0, len(data), step): 10165204Sstever@gmail.com x = array.array('B', data[i:i+step]) 10177727SAli.Saidi@ARM.com code(''.join('%d,' % d for d in x)) 10187727SAli.Saidi@ARM.com code.dedent() 10197727SAli.Saidi@ARM.com 10207727SAli.Saidi@ARM.com code('''}; 10217727SAli.Saidi@ARM.com 102210453SAndrew.Bardsley@arm.comEmbeddedPython embedded_${sym}( 102310453SAndrew.Bardsley@arm.com ${{c_str(pysource.arcname)}}, 102410453SAndrew.Bardsley@arm.com ${{c_str(pysource.abspath)}}, 102510453SAndrew.Bardsley@arm.com ${{c_str(pysource.modpath)}}, 102610453SAndrew.Bardsley@arm.com data_${sym}, 102710453SAndrew.Bardsley@arm.com ${{len(data)}}, 102810453SAndrew.Bardsley@arm.com ${{len(marshalled)}}); 102910453SAndrew.Bardsley@arm.com 103010453SAndrew.Bardsley@arm.com} // anonymous namespace 103110453SAndrew.Bardsley@arm.com''') 103210453SAndrew.Bardsley@arm.com code.write(str(target[0])) 103310160Sandreas.hansson@arm.com 103410453SAndrew.Bardsley@arm.comfor source in PySource.all: 103510453SAndrew.Bardsley@arm.com env.Command(source.cpp, source.tnode, 103610453SAndrew.Bardsley@arm.com MakeAction(embedPyFile, Transform("EMBED PY"))) 103710453SAndrew.Bardsley@arm.com env.Depends(SWIG, source.cpp) 103810453SAndrew.Bardsley@arm.com Source(source.cpp, skip_no_python=True) 103910453SAndrew.Bardsley@arm.com 104010453SAndrew.Bardsley@arm.com######################################################################## 104110453SAndrew.Bardsley@arm.com# 10429812Sandreas.hansson@arm.com# Define binaries. Each different build type (debug, opt, etc.) gets 104310453SAndrew.Bardsley@arm.com# a slightly different build environment. 104410453SAndrew.Bardsley@arm.com# 104510453SAndrew.Bardsley@arm.com 104610453SAndrew.Bardsley@arm.com# List of constructed environments to pass back to SConstruct 104710453SAndrew.Bardsley@arm.comdate_source = Source('base/date.cc', skip_lib=True) 104810453SAndrew.Bardsley@arm.com 104910453SAndrew.Bardsley@arm.com# Capture this directory for the closure makeEnv, otherwise when it is 105010453SAndrew.Bardsley@arm.com# called, it won't know what directory it should use. 105110453SAndrew.Bardsley@arm.comvariant_dir = Dir('.').path 105210453SAndrew.Bardsley@arm.comdef variant(*path): 105310453SAndrew.Bardsley@arm.com return os.path.join(variant_dir, *path) 105410453SAndrew.Bardsley@arm.comdef variantd(*path): 10557727SAli.Saidi@ARM.com return variant(*path)+'/' 105610453SAndrew.Bardsley@arm.com 105710453SAndrew.Bardsley@arm.com# Function to create a new build environment as clone of current 105810453SAndrew.Bardsley@arm.com# environment 'env' with modified object suffix and optional stripped 105910453SAndrew.Bardsley@arm.com# binary. Additional keyword arguments are appended to corresponding 106010453SAndrew.Bardsley@arm.com# build environment vars. 10613118Sstever@eecs.umich.edudef makeEnv(env, label, objsfx, strip = False, **kwargs): 106210453SAndrew.Bardsley@arm.com # SCons doesn't know to append a library suffix when there is a '.' in the 106310453SAndrew.Bardsley@arm.com # name. Use '_' instead. 106410453SAndrew.Bardsley@arm.com libname = variant('gem5_' + label) 106510453SAndrew.Bardsley@arm.com exename = variant('gem5.' + label) 10663118Sstever@eecs.umich.edu secondary_exename = variant('m5.' + label) 10673483Ssaidi@eecs.umich.edu 10683494Ssaidi@eecs.umich.edu new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 10693494Ssaidi@eecs.umich.edu new_env.Label = label 10703483Ssaidi@eecs.umich.edu new_env.Append(**kwargs) 10713483Ssaidi@eecs.umich.edu 10723483Ssaidi@eecs.umich.edu swig_env = new_env.Clone() 10733053Sstever@eecs.umich.edu 10743053Sstever@eecs.umich.edu # Both gcc and clang have issues with unused labels and values in 10753918Ssaidi@eecs.umich.edu # the SWIG generated code 10763053Sstever@eecs.umich.edu swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 10773053Sstever@eecs.umich.edu 10783053Sstever@eecs.umich.edu if env['GCC']: 10793053Sstever@eecs.umich.edu # Depending on the SWIG version, we also need to supress 10803053Sstever@eecs.umich.edu # warnings about uninitialized variables and missing field 10819396Sandreas.hansson@arm.com # initializers. 10829396Sandreas.hansson@arm.com swig_env.Append(CCFLAGS=['-Wno-uninitialized', 10839396Sandreas.hansson@arm.com '-Wno-missing-field-initializers', 10849396Sandreas.hansson@arm.com '-Wno-unused-but-set-variable', 10859396Sandreas.hansson@arm.com '-Wno-maybe-uninitialized', 10869396Sandreas.hansson@arm.com '-Wno-type-limits']) 10879396Sandreas.hansson@arm.com 10889396Sandreas.hansson@arm.com 10899396Sandreas.hansson@arm.com # The address sanitizer is available for gcc >= 4.8 10909477Sandreas.hansson@arm.com if GetOption('with_asan'): 10919396Sandreas.hansson@arm.com if GetOption('with_ubsan') and \ 10929477Sandreas.hansson@arm.com compareVersions(env['GCC_VERSION'], '4.9') >= 0: 10939477Sandreas.hansson@arm.com new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 10949477Sandreas.hansson@arm.com '-fno-omit-frame-pointer']) 10959477Sandreas.hansson@arm.com new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 10969396Sandreas.hansson@arm.com else: 10977840Snate@binkert.org new_env.Append(CCFLAGS=['-fsanitize=address', 10987865Sgblack@eecs.umich.edu '-fno-omit-frame-pointer']) 10997865Sgblack@eecs.umich.edu new_env.Append(LINKFLAGS='-fsanitize=address') 11007865Sgblack@eecs.umich.edu # Only gcc >= 4.9 supports UBSan, so check both the version 11017865Sgblack@eecs.umich.edu # and the command-line option before adding the compiler and 11027865Sgblack@eecs.umich.edu # linker flags. 11037840Snate@binkert.org elif GetOption('with_ubsan') and \ 11049900Sandreas@sandberg.pp.se compareVersions(env['GCC_VERSION'], '4.9') >= 0: 11059900Sandreas@sandberg.pp.se new_env.Append(CCFLAGS='-fsanitize=undefined') 11069900Sandreas@sandberg.pp.se new_env.Append(LINKFLAGS='-fsanitize=undefined') 11079900Sandreas@sandberg.pp.se 110810456SCurtis.Dunham@arm.com 110910456SCurtis.Dunham@arm.com if env['CLANG']: 111010456SCurtis.Dunham@arm.com swig_env.Append(CCFLAGS=['-Wno-sometimes-uninitialized', 111110456SCurtis.Dunham@arm.com '-Wno-deprecated-register', 111210456SCurtis.Dunham@arm.com '-Wno-tautological-compare']) 111310456SCurtis.Dunham@arm.com 111410456SCurtis.Dunham@arm.com # We require clang >= 3.1, so there is no need to check any 111510456SCurtis.Dunham@arm.com # versions here. 111610456SCurtis.Dunham@arm.com if GetOption('with_ubsan'): 111710456SCurtis.Dunham@arm.com if GetOption('with_asan'): 11189045SAli.Saidi@ARM.com new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 111911235Sandreas.sandberg@arm.com '-fno-omit-frame-pointer']) 112011235Sandreas.sandberg@arm.com new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 112111235Sandreas.sandberg@arm.com else: 112211235Sandreas.sandberg@arm.com new_env.Append(CCFLAGS='-fsanitize=undefined') 112311235Sandreas.sandberg@arm.com new_env.Append(LINKFLAGS='-fsanitize=undefined') 112411235Sandreas.sandberg@arm.com 112511235Sandreas.sandberg@arm.com elif GetOption('with_asan'): 112611235Sandreas.sandberg@arm.com new_env.Append(CCFLAGS=['-fsanitize=address', 112711811Sbaz21@cam.ac.uk '-fno-omit-frame-pointer']) 112811811Sbaz21@cam.ac.uk new_env.Append(LINKFLAGS='-fsanitize=address') 112911811Sbaz21@cam.ac.uk 113011811Sbaz21@cam.ac.uk werror_env = new_env.Clone() 113111811Sbaz21@cam.ac.uk # Treat warnings as errors but white list some warnings that we 113211235Sandreas.sandberg@arm.com # want to allow (e.g., deprecation warnings). 113311235Sandreas.sandberg@arm.com werror_env.Append(CCFLAGS=['-Werror', 113411235Sandreas.sandberg@arm.com '-Wno-error=deprecated-declarations', 113511235Sandreas.sandberg@arm.com '-Wno-error=deprecated', 113611235Sandreas.sandberg@arm.com ]) 113711235Sandreas.sandberg@arm.com 113811235Sandreas.sandberg@arm.com def make_obj(source, static, extra_deps = None): 11397840Snate@binkert.org '''This function adds the specified source to the correct 11407840Snate@binkert.org build environment, and returns the corresponding SCons Object 11417840Snate@binkert.org nodes''' 11421858SN/A 11431858SN/A if source.swig: 11441858SN/A env = swig_env 11451858SN/A elif source.Werror: 11461858SN/A env = werror_env 11471858SN/A else: 11489903Sandreas.hansson@arm.com env = new_env 11499903Sandreas.hansson@arm.com 11509903Sandreas.hansson@arm.com if static: 11519903Sandreas.hansson@arm.com obj = env.StaticObject(source.tnode) 115210841Sandreas.sandberg@arm.com else: 11539651SAndreas.Sandberg@ARM.com obj = env.SharedObject(source.tnode) 11549903Sandreas.hansson@arm.com 11559651SAndreas.Sandberg@ARM.com if extra_deps: 11569651SAndreas.Sandberg@ARM.com env.Depends(obj, extra_deps) 115710841Sandreas.sandberg@arm.com 115810841Sandreas.sandberg@arm.com return obj 115910841Sandreas.sandberg@arm.com 116010841Sandreas.sandberg@arm.com lib_guards = {'main': False, 'skip_lib': False} 116110841Sandreas.sandberg@arm.com 116210841Sandreas.sandberg@arm.com # Without Python, leave out all SWIG and Python content from the 11639651SAndreas.Sandberg@ARM.com # library builds. The option doesn't affect gem5 built as a program 11649651SAndreas.Sandberg@ARM.com if GetOption('without_python'): 11659651SAndreas.Sandberg@ARM.com lib_guards['skip_no_python'] = False 11669651SAndreas.Sandberg@ARM.com 11679651SAndreas.Sandberg@ARM.com static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] 11689651SAndreas.Sandberg@ARM.com shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] 11699651SAndreas.Sandberg@ARM.com 11709651SAndreas.Sandberg@ARM.com static_date = make_obj(date_source, static=True, extra_deps=static_objs) 11719651SAndreas.Sandberg@ARM.com static_objs.append(static_date) 117210841Sandreas.sandberg@arm.com 117310841Sandreas.sandberg@arm.com shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 117410841Sandreas.sandberg@arm.com shared_objs.append(shared_date) 117510841Sandreas.sandberg@arm.com 117610841Sandreas.sandberg@arm.com # First make a library of everything but main() so other programs can 117710841Sandreas.sandberg@arm.com # link against m5. 117810860Sandreas.sandberg@arm.com static_lib = new_env.StaticLibrary(libname, static_objs) 117910841Sandreas.sandberg@arm.com shared_lib = new_env.SharedLibrary(libname, shared_objs) 118010841Sandreas.sandberg@arm.com 118110841Sandreas.sandberg@arm.com # Now link a stub with main() and the static library. 118210841Sandreas.sandberg@arm.com main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 118310841Sandreas.sandberg@arm.com 118410841Sandreas.sandberg@arm.com for test in UnitTest.all: 118510841Sandreas.sandberg@arm.com flags = { test.target : True } 118610841Sandreas.sandberg@arm.com test_sources = Source.get(**flags) 118710841Sandreas.sandberg@arm.com test_objs = [ make_obj(s, static=True) for s in test_sources ] 118810841Sandreas.sandberg@arm.com if test.main: 118910841Sandreas.sandberg@arm.com test_objs += main_objs 11909651SAndreas.Sandberg@ARM.com path = variant('unittest/%s.%s' % (test.target, label)) 11919651SAndreas.Sandberg@ARM.com new_env.Program(path, test_objs + static_objs) 11929986Sandreas@sandberg.pp.se 11939986Sandreas@sandberg.pp.se progname = exename 11949986Sandreas@sandberg.pp.se if strip: 11959986Sandreas@sandberg.pp.se progname += '.unstripped' 11969986Sandreas@sandberg.pp.se 11979986Sandreas@sandberg.pp.se targets = new_env.Program(progname, main_objs + static_objs) 11985863Snate@binkert.org 11995863Snate@binkert.org if strip: 12005863Snate@binkert.org if sys.platform == 'sunos5': 12015863Snate@binkert.org cmd = 'cp $SOURCE $TARGET; strip $TARGET' 12026121Snate@binkert.org else: 12031858SN/A cmd = 'strip $SOURCE -o $TARGET' 12045863Snate@binkert.org targets = new_env.Command(exename, progname, 12055863Snate@binkert.org MakeAction(cmd, Transform("STRIP"))) 12065863Snate@binkert.org 12075863Snate@binkert.org new_env.Command(secondary_exename, exename, 12085863Snate@binkert.org MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 12092139SN/A 12104202Sbinkertn@umich.edu new_env.M5Binary = targets[0] 121111308Santhony.gutierrez@amd.com return new_env 12124202Sbinkertn@umich.edu 121311308Santhony.gutierrez@amd.com# Start out with the compiler flags common to all compilers, 12142139SN/A# i.e. they all use -g for opt and -g -pg for prof 12156994Snate@binkert.orgccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 12166994Snate@binkert.org 'perf' : ['-g']} 12176994Snate@binkert.org 12186994Snate@binkert.org# Start out with the linker flags common to all linkers, i.e. -pg for 12196994Snate@binkert.org# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 12206994Snate@binkert.org# no-as-needed and as-needed as the binutils linker is too clever and 12216994Snate@binkert.org# simply doesn't link to the library otherwise. 12226994Snate@binkert.orgldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 122310319SAndreas.Sandberg@ARM.com 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 12246994Snate@binkert.org 12256994Snate@binkert.org# For Link Time Optimization, the optimisation flags used to compile 12266994Snate@binkert.org# individual files are decoupled from those used at link time 12276994Snate@binkert.org# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 12286994Snate@binkert.org# to also update the linker flags based on the target. 12296994Snate@binkert.orgif env['GCC']: 12306994Snate@binkert.org if sys.platform == 'sunos5': 12316994Snate@binkert.org ccflags['debug'] += ['-gstabs+'] 12326994Snate@binkert.org else: 12336994Snate@binkert.org ccflags['debug'] += ['-ggdb3'] 12346994Snate@binkert.org ldflags['debug'] += ['-O0'] 12352155SN/A # opt, fast, prof and perf all share the same cc flags, also add 12365863Snate@binkert.org # the optimization to the ldflags as LTO defers the optimization 12371869SN/A # to link time 12381869SN/A for target in ['opt', 'fast', 'prof', 'perf']: 12395863Snate@binkert.org ccflags[target] += ['-O3'] 12405863Snate@binkert.org ldflags[target] += ['-O3'] 12414202Sbinkertn@umich.edu 12426108Snate@binkert.org ccflags['fast'] += env['LTO_CCFLAGS'] 12436108Snate@binkert.org ldflags['fast'] += env['LTO_LDFLAGS'] 12446108Snate@binkert.orgelif env['CLANG']: 12456108Snate@binkert.org ccflags['debug'] += ['-g', '-O0'] 12469219Spower.jg@gmail.com # opt, fast, prof and perf all share the same cc flags 12479219Spower.jg@gmail.com for target in ['opt', 'fast', 'prof', 'perf']: 12489219Spower.jg@gmail.com ccflags[target] += ['-O3'] 12499219Spower.jg@gmail.comelse: 12509219Spower.jg@gmail.com print 'Unknown compiler, please fix compiler options' 12519219Spower.jg@gmail.com Exit(1) 12529219Spower.jg@gmail.com 12539219Spower.jg@gmail.com 12544202Sbinkertn@umich.edu# To speed things up, we only instantiate the build environments we 12555863Snate@binkert.org# need. We try to identify the needed environment for each target; if 125610135SCurtis.Dunham@arm.com# we can't, we fall back on instantiating all the environments just to 12578474Sgblack@eecs.umich.edu# be safe. 12585742Snate@binkert.orgtarget_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 12598268Ssteve.reinhardt@amd.comobj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 12608268Ssteve.reinhardt@amd.com 'gpo' : 'perf'} 12618268Ssteve.reinhardt@amd.com 12625742Snate@binkert.orgdef identifyTarget(t): 12635341Sstever@gmail.com ext = t.split('.')[-1] 12648474Sgblack@eecs.umich.edu if ext in target_types: 12658474Sgblack@eecs.umich.edu return ext 12665342Sstever@gmail.com if obj2target.has_key(ext): 12674202Sbinkertn@umich.edu return obj2target[ext] 12684202Sbinkertn@umich.edu match = re.search(r'/tests/([^/]+)/', t) 126911308Santhony.gutierrez@amd.com if match and match.group(1) in target_types: 12704202Sbinkertn@umich.edu return match.group(1) 12715863Snate@binkert.org return 'all' 12725863Snate@binkert.org 127311308Santhony.gutierrez@amd.comneeded_envs = [identifyTarget(target) for target in BUILD_TARGETS] 12746994Snate@binkert.orgif 'all' in needed_envs: 12756994Snate@binkert.org needed_envs += target_types 127610319SAndreas.Sandberg@ARM.com 12775863Snate@binkert.orgdef makeEnvirons(target, source, env): 12785863Snate@binkert.org # cause any later Source() calls to be fatal, as a diagnostic. 12795863Snate@binkert.org Source.done() 12805863Snate@binkert.org 12815863Snate@binkert.org envList = [] 12825863Snate@binkert.org 12835863Snate@binkert.org # Debug binary 12845863Snate@binkert.org if 'debug' in needed_envs: 12857840Snate@binkert.org envList.append( 12865863Snate@binkert.org makeEnv(env, 'debug', '.do', 12875952Ssaidi@eecs.umich.edu CCFLAGS = Split(ccflags['debug']), 12889651SAndreas.Sandberg@ARM.com CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 128911308Santhony.gutierrez@amd.com LINKFLAGS = Split(ldflags['debug']))) 12909219Spower.jg@gmail.com 12919219Spower.jg@gmail.com # Optimized binary 129211235Sandreas.sandberg@arm.com if 'opt' in needed_envs: 129311235Sandreas.sandberg@arm.com envList.append( 12941869SN/A makeEnv(env, 'opt', '.o', 12951858SN/A CCFLAGS = Split(ccflags['opt']), 12965863Snate@binkert.org CPPDEFINES = ['TRACING_ON=1'], 129711308Santhony.gutierrez@amd.com LINKFLAGS = Split(ldflags['opt']))) 129811308Santhony.gutierrez@amd.com 129911308Santhony.gutierrez@amd.com # "Fast" binary 13001858SN/A if 'fast' in needed_envs: 1301955SN/A envList.append( 1302955SN/A makeEnv(env, 'fast', '.fo', strip = True, 13031869SN/A CCFLAGS = Split(ccflags['fast']), 13041869SN/A CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 13051869SN/A LINKFLAGS = Split(ldflags['fast']))) 13061869SN/A 13071869SN/A # Profiled binary using gprof 13085863Snate@binkert.org if 'prof' in needed_envs: 13095863Snate@binkert.org envList.append( 13105863Snate@binkert.org makeEnv(env, 'prof', '.po', 13111869SN/A CCFLAGS = Split(ccflags['prof']), 13125863Snate@binkert.org CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 13131869SN/A LINKFLAGS = Split(ldflags['prof']))) 13145863Snate@binkert.org 13151869SN/A # Profiled binary using google-pprof 13161869SN/A if 'perf' in needed_envs: 13171869SN/A envList.append( 13181869SN/A makeEnv(env, 'perf', '.gpo', 13198483Sgblack@eecs.umich.edu CCFLAGS = Split(ccflags['perf']), 13201869SN/A CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 13211869SN/A LINKFLAGS = Split(ldflags['perf']))) 13221869SN/A 13231869SN/A # Set up the regression tests for each build. 13245863Snate@binkert.org for e in envList: 13255863Snate@binkert.org SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 13261869SN/A variant_dir = variantd('tests', e.Label), 13275863Snate@binkert.org exports = { 'env' : e }, duplicate = False) 13285863Snate@binkert.org 13293356Sbinkertn@umich.edu# The MakeEnvirons Builder defers the full dependency collection until 13303356Sbinkertn@umich.edu# after processing the ISA definition (due to dynamically generated 13313356Sbinkertn@umich.edu# source files). Add this dependency to all targets so they will wait 13323356Sbinkertn@umich.edu# until the environments are completely set up. Otherwise, a second 13333356Sbinkertn@umich.edu# process (e.g. -j2 or higher) will try to compile the requested target, 13344781Snate@binkert.org# not know how, and fail. 13355863Snate@binkert.orgenv.Append(BUILDERS = {'MakeEnvirons' : 13365863Snate@binkert.org Builder(action=MakeAction(makeEnvirons, 13371869SN/A Transform("ENVIRONS", 1)))}) 13381869SN/A 13391869SN/Aisa_target = env['PHONY_BASE'] + '-deps' 13406121Snate@binkert.orgenvirons = env['PHONY_BASE'] + '-environs' 13411869SN/Aenv.Depends('#all-deps', isa_target) 13422638Sstever@eecs.umich.eduenv.Depends('#all-environs', environs) 13436121Snate@binkert.orgenv.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 13446121Snate@binkert.orgenvSetup = env.MakeEnvirons(environs, isa_target) 13452638Sstever@eecs.umich.edu 134611293Sandreas.hansson@arm.com# make sure no -deps targets occur before all ISAs are complete 134711293Sandreas.hansson@arm.comenv.Depends(isa_target, '#all-isas') 134811293Sandreas.hansson@arm.com# likewise for -environs targets and all the -deps targets 13495749Scws3k@cs.virginia.eduenv.Depends(environs, '#all-deps') 13509537Satgutier@umich.edu