SConscript revision 11370:af870035ab6b
1955SN/A# -*- mode:python -*- 2955SN/A 37816Ssteve.reinhardt@amd.com# Copyright (c) 2004-2005 The Regents of The University of Michigan 45871Snate@binkert.org# All rights reserved. 51762SN/A# 6955SN/A# Redistribution and use in source and binary forms, with or without 7955SN/A# modification, are permitted provided that the following conditions are 8955SN/A# met: redistributions of source code must retain the above copyright 9955SN/A# notice, this list of conditions and the following disclaimer; 10955SN/A# redistributions in binary form must reproduce the above copyright 11955SN/A# notice, this list of conditions and the following disclaimer in the 12955SN/A# documentation and/or other materials provided with the distribution; 13955SN/A# neither the name of the copyright holders nor the names of its 14955SN/A# contributors may be used to endorse or promote products derived from 15955SN/A# this software without specific prior written permission. 16955SN/A# 17955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28955SN/A# 29955SN/A# Authors: Nathan Binkert 302665Ssaidi@eecs.umich.edu 312665Ssaidi@eecs.umich.eduimport array 325863Snate@binkert.orgimport bisect 33955SN/Aimport imp 34955SN/Aimport marshal 35955SN/Aimport os 36955SN/Aimport re 37955SN/Aimport sys 388878Ssteve.reinhardt@amd.comimport zlib 392632Sstever@eecs.umich.edu 408878Ssteve.reinhardt@amd.comfrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 412632Sstever@eecs.umich.edu 42955SN/Aimport SCons 438878Ssteve.reinhardt@amd.com 442632Sstever@eecs.umich.edu# This file defines how to build a particular configuration of gem5 452761Sstever@eecs.umich.edu# based on variable settings in the 'env' build environment. 462632Sstever@eecs.umich.edu 472632Sstever@eecs.umich.eduImport('*') 482632Sstever@eecs.umich.edu 492761Sstever@eecs.umich.edu# Children need to see the environment 502761Sstever@eecs.umich.eduExport('env') 512761Sstever@eecs.umich.edu 528878Ssteve.reinhardt@amd.combuild_env = [(opt, env[opt]) for opt in export_vars] 538878Ssteve.reinhardt@amd.com 542761Sstever@eecs.umich.edufrom m5.util import code_formatter, compareVersions 552761Sstever@eecs.umich.edu 562761Sstever@eecs.umich.edu######################################################################## 572761Sstever@eecs.umich.edu# Code for adding source files of various types 582761Sstever@eecs.umich.edu# 598878Ssteve.reinhardt@amd.com# When specifying a source file of some type, a set of guards can be 608878Ssteve.reinhardt@amd.com# specified for that file. When get() is used to find the files, if 612632Sstever@eecs.umich.edu# get specifies a set of filters, only files that match those filters 622632Sstever@eecs.umich.edu# will be accepted (unspecified filters on files are assumed to be 638878Ssteve.reinhardt@amd.com# false). Current filters are: 648878Ssteve.reinhardt@amd.com# main -- specifies the gem5 main() function 652632Sstever@eecs.umich.edu# skip_lib -- do not put this file into the gem5 library 66955SN/A# skip_no_python -- do not put this file into a no_python library 67955SN/A# as it embeds compiled Python 68955SN/A# <unittest> -- unit tests use filters based on the unit test name 695863Snate@binkert.org# 705863Snate@binkert.org# A parent can now be specified for a source file and default filter 715863Snate@binkert.org# values will be retrieved recursively from parents (children override 725863Snate@binkert.org# parents). 735863Snate@binkert.org# 745863Snate@binkert.orgclass SourceMeta(type): 755863Snate@binkert.org '''Meta class for source files that keeps track of all files of a 765863Snate@binkert.org particular type and has a get function for finding all functions 775863Snate@binkert.org of a certain type that match a set of guards''' 785863Snate@binkert.org def __init__(cls, name, bases, dict): 795863Snate@binkert.org super(SourceMeta, cls).__init__(name, bases, dict) 808878Ssteve.reinhardt@amd.com 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: 925863Snate@binkert.org yield src 935863Snate@binkert.org 945863Snate@binkert.orgclass SourceFile(object): 955863Snate@binkert.org '''Base object that encapsulates the notion of a source file. 968878Ssteve.reinhardt@amd.com This includes, the source node, target node, various manipulations 975863Snate@binkert.org 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 995863Snate@binkert.org also be specified to get default guards from''' 1006654Snate@binkert.org __metaclass__ = SourceMeta 101955SN/A def __init__(self, source, parent=None, **guards): 1025396Ssaidi@eecs.umich.edu self.guards = guards 1035863Snate@binkert.org self.parent = parent 1045863Snate@binkert.org 1054202Sbinkertn@umich.edu tnode = source 1065863Snate@binkert.org if not isinstance(source, SCons.Node.FS.File): 1075863Snate@binkert.org tnode = File(source) 1085863Snate@binkert.org 1095863Snate@binkert.org self.tnode = tnode 110955SN/A self.snode = tnode.srcnode() 1116654Snate@binkert.org 1125273Sstever@gmail.com for base in type(self).__mro__: 1135871Snate@binkert.org if issubclass(base, SourceFile): 1145273Sstever@gmail.com base.all.append(self) 1156655Snate@binkert.org 1168878Ssteve.reinhardt@amd.com @property 1176655Snate@binkert.org def filename(self): 1186655Snate@binkert.org return str(self.tnode) 1196655Snate@binkert.org 1206655Snate@binkert.org @property 1215871Snate@binkert.org def dirname(self): 1226654Snate@binkert.org return dirname(self.filename) 1238947Sandreas.hansson@arm.com 1245396Ssaidi@eecs.umich.edu @property 1258120Sgblack@eecs.umich.edu def basename(self): 1268120Sgblack@eecs.umich.edu return basename(self.filename) 1278120Sgblack@eecs.umich.edu 1288120Sgblack@eecs.umich.edu @property 1298120Sgblack@eecs.umich.edu def extname(self): 1308120Sgblack@eecs.umich.edu index = self.basename.rfind('.') 1318120Sgblack@eecs.umich.edu if index <= 0: 1328120Sgblack@eecs.umich.edu # dot files aren't extensions 1338879Ssteve.reinhardt@amd.com return self.basename, None 1348879Ssteve.reinhardt@amd.com 1358879Ssteve.reinhardt@amd.com return self.basename[:index], self.basename[index+1:] 1368879Ssteve.reinhardt@amd.com 1378879Ssteve.reinhardt@amd.com @property 1388879Ssteve.reinhardt@amd.com def all_guards(self): 1398879Ssteve.reinhardt@amd.com '''find all guards for this object getting default values 1408879Ssteve.reinhardt@amd.com recursively from its parents''' 1418879Ssteve.reinhardt@amd.com guards = {} 1428879Ssteve.reinhardt@amd.com if self.parent: 1438879Ssteve.reinhardt@amd.com guards.update(self.parent.guards) 1448879Ssteve.reinhardt@amd.com guards.update(self.guards) 1458879Ssteve.reinhardt@amd.com return guards 1468120Sgblack@eecs.umich.edu 1478120Sgblack@eecs.umich.edu def __lt__(self, other): return self.filename < other.filename 1488120Sgblack@eecs.umich.edu def __le__(self, other): return self.filename <= other.filename 1498120Sgblack@eecs.umich.edu def __gt__(self, other): return self.filename > other.filename 1508120Sgblack@eecs.umich.edu def __ge__(self, other): return self.filename >= other.filename 1518120Sgblack@eecs.umich.edu def __eq__(self, other): return self.filename == other.filename 1528120Sgblack@eecs.umich.edu def __ne__(self, other): return self.filename != other.filename 1538120Sgblack@eecs.umich.edu 1548120Sgblack@eecs.umich.edu @staticmethod 1558120Sgblack@eecs.umich.edu def done(): 1568120Sgblack@eecs.umich.edu def disabled(cls, name, *ignored): 1578120Sgblack@eecs.umich.edu raise RuntimeError("Additional SourceFile '%s'" % name,\ 1588120Sgblack@eecs.umich.edu "declared, but targets deps are already fixed.") 1598120Sgblack@eecs.umich.edu SourceFile.__init__ = disabled 1608879Ssteve.reinhardt@amd.com 1618879Ssteve.reinhardt@amd.com 1628879Ssteve.reinhardt@amd.comclass Source(SourceFile): 1638879Ssteve.reinhardt@amd.com '''Add a c/c++ source file to the build''' 1648879Ssteve.reinhardt@amd.com def __init__(self, source, Werror=True, swig=False, **guards): 1658879Ssteve.reinhardt@amd.com '''specify the source file, and any guards''' 1668879Ssteve.reinhardt@amd.com super(Source, self).__init__(source, **guards) 1678879Ssteve.reinhardt@amd.com 1688879Ssteve.reinhardt@amd.com self.Werror = Werror 1698879Ssteve.reinhardt@amd.com self.swig = swig 1708879Ssteve.reinhardt@amd.com 1718879Ssteve.reinhardt@amd.comclass PySource(SourceFile): 1728120Sgblack@eecs.umich.edu '''Add a python source file to the named package''' 1738947Sandreas.hansson@arm.com invalid_sym_char = re.compile('[^A-z0-9_]') 1747816Ssteve.reinhardt@amd.com modules = {} 1755871Snate@binkert.org tnodes = {} 1765871Snate@binkert.org symnames = {} 1776121Snate@binkert.org 1785871Snate@binkert.org def __init__(self, package, source, **guards): 1795871Snate@binkert.org '''specify the python package, the source file, and any guards''' 1809119Sandreas.hansson@arm.com super(PySource, self).__init__(source, **guards) 1819119Sandreas.hansson@arm.com 182955SN/A modname,ext = self.extname 1835871Snate@binkert.org assert ext == 'py' 1845871Snate@binkert.org 1855871Snate@binkert.org if package: 1865871Snate@binkert.org path = package.split('.') 187955SN/A else: 1886121Snate@binkert.org path = [] 1898881Smarc.orr@gmail.com 1906121Snate@binkert.org modpath = path[:] 1916121Snate@binkert.org if modname != '__init__': 1921533SN/A modpath += [ modname ] 1936655Snate@binkert.org modpath = '.'.join(modpath) 1946655Snate@binkert.org 1956655Snate@binkert.org arcpath = path + [ self.basename ] 1966655Snate@binkert.org abspath = self.snode.abspath 1975871Snate@binkert.org if not exists(abspath): 1985871Snate@binkert.org abspath = self.tnode.abspath 1995863Snate@binkert.org 2005871Snate@binkert.org self.package = package 2018878Ssteve.reinhardt@amd.com self.modname = modname 2025871Snate@binkert.org self.modpath = modpath 2035871Snate@binkert.org self.arcname = joinpath(*arcpath) 2045871Snate@binkert.org self.abspath = abspath 2055863Snate@binkert.org self.compiled = File(self.filename + 'c') 2066121Snate@binkert.org self.cpp = File(self.filename + '.cc') 2075863Snate@binkert.org self.symname = PySource.invalid_sym_char.sub('_', modpath) 2085871Snate@binkert.org 2098336Ssteve.reinhardt@amd.com PySource.modules[modpath] = self 2108336Ssteve.reinhardt@amd.com PySource.tnodes[self.tnode] = self 2118336Ssteve.reinhardt@amd.com PySource.symnames[self.symname] = self 2128336Ssteve.reinhardt@amd.com 2134678Snate@binkert.orgclass SimObject(PySource): 2148336Ssteve.reinhardt@amd.com '''Add a SimObject python file as a python source object and add 2158336Ssteve.reinhardt@amd.com it to a list of sim object modules''' 2168336Ssteve.reinhardt@amd.com 2174678Snate@binkert.org fixed = False 2184678Snate@binkert.org modnames = [] 2194678Snate@binkert.org 2204678Snate@binkert.org def __init__(self, source, **guards): 2217827Snate@binkert.org '''Specify the source file and any guards (automatically in 2227827Snate@binkert.org the m5.objects package)''' 2238336Ssteve.reinhardt@amd.com super(SimObject, self).__init__('m5.objects', source, **guards) 2244678Snate@binkert.org if self.fixed: 2258336Ssteve.reinhardt@amd.com raise AttributeError, "Too late to call SimObject now." 2268336Ssteve.reinhardt@amd.com 2278336Ssteve.reinhardt@amd.com bisect.insort_right(SimObject.modnames, self.modname) 2288336Ssteve.reinhardt@amd.com 2298336Ssteve.reinhardt@amd.comclass SwigSource(SourceFile): 2308336Ssteve.reinhardt@amd.com '''Add a swig file to build''' 2315871Snate@binkert.org 2325871Snate@binkert.org def __init__(self, package, source, **guards): 2338336Ssteve.reinhardt@amd.com '''Specify the python package, the source file, and any guards''' 2348336Ssteve.reinhardt@amd.com super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 2358336Ssteve.reinhardt@amd.com 2368336Ssteve.reinhardt@amd.com modname,ext = self.extname 2378336Ssteve.reinhardt@amd.com assert ext == 'i' 2385871Snate@binkert.org 2398336Ssteve.reinhardt@amd.com self.module = modname 2408336Ssteve.reinhardt@amd.com cc_file = joinpath(self.dirname, modname + '_wrap.cc') 2418336Ssteve.reinhardt@amd.com py_file = joinpath(self.dirname, modname + '.py') 2428336Ssteve.reinhardt@amd.com 2438336Ssteve.reinhardt@amd.com self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 2444678Snate@binkert.org self.py_source = PySource(package, py_file, parent=self, **guards) 2455871Snate@binkert.org 2464678Snate@binkert.orgclass ProtoBuf(SourceFile): 2478336Ssteve.reinhardt@amd.com '''Add a Protocol Buffer to build''' 2488336Ssteve.reinhardt@amd.com 2498336Ssteve.reinhardt@amd.com def __init__(self, source, **guards): 2508336Ssteve.reinhardt@amd.com '''Specify the source file, and any guards''' 2518336Ssteve.reinhardt@amd.com super(ProtoBuf, self).__init__(source, **guards) 2528336Ssteve.reinhardt@amd.com 2538336Ssteve.reinhardt@amd.com # Get the file name and the extension 2548336Ssteve.reinhardt@amd.com modname,ext = self.extname 2558336Ssteve.reinhardt@amd.com assert ext == 'proto' 2568336Ssteve.reinhardt@amd.com 2578336Ssteve.reinhardt@amd.com # Currently, we stick to generating the C++ headers, so we 2588336Ssteve.reinhardt@amd.com # only need to track the source and header. 2598336Ssteve.reinhardt@amd.com self.cc_file = File(modname + '.pb.cc') 2608336Ssteve.reinhardt@amd.com self.hh_file = File(modname + '.pb.h') 2618336Ssteve.reinhardt@amd.com 2628336Ssteve.reinhardt@amd.comclass UnitTest(object): 2638336Ssteve.reinhardt@amd.com '''Create a UnitTest''' 2645871Snate@binkert.org 2656121Snate@binkert.org all = [] 266955SN/A def __init__(self, target, *sources, **kwargs): 267955SN/A '''Specify the target name and any sources. Sources that are 2682632Sstever@eecs.umich.edu not SourceFiles are evalued with Source(). All files are 2692632Sstever@eecs.umich.edu guarded with a guard of the same name as the UnitTest 270955SN/A target.''' 271955SN/A 272955SN/A srcs = [] 273955SN/A for src in sources: 2748878Ssteve.reinhardt@amd.com if not isinstance(src, SourceFile): 275955SN/A src = Source(src, skip_lib=True) 2762632Sstever@eecs.umich.edu src.guards[target] = True 2772632Sstever@eecs.umich.edu srcs.append(src) 2782632Sstever@eecs.umich.edu 2792632Sstever@eecs.umich.edu self.sources = srcs 2802632Sstever@eecs.umich.edu self.target = target 2812632Sstever@eecs.umich.edu self.main = kwargs.get('main', False) 2822632Sstever@eecs.umich.edu UnitTest.all.append(self) 2838268Ssteve.reinhardt@amd.com 2848268Ssteve.reinhardt@amd.com# Children should have access 2858268Ssteve.reinhardt@amd.comExport('Source') 2868268Ssteve.reinhardt@amd.comExport('PySource') 2878268Ssteve.reinhardt@amd.comExport('SimObject') 2888268Ssteve.reinhardt@amd.comExport('SwigSource') 2898268Ssteve.reinhardt@amd.comExport('ProtoBuf') 2902632Sstever@eecs.umich.eduExport('UnitTest') 2912632Sstever@eecs.umich.edu 2922632Sstever@eecs.umich.edu######################################################################## 2932632Sstever@eecs.umich.edu# 2948268Ssteve.reinhardt@amd.com# Debug Flags 2952632Sstever@eecs.umich.edu# 2968268Ssteve.reinhardt@amd.comdebug_flags = {} 2978268Ssteve.reinhardt@amd.comdef DebugFlag(name, desc=None): 2988268Ssteve.reinhardt@amd.com if name in debug_flags: 2998268Ssteve.reinhardt@amd.com raise AttributeError, "Flag %s already specified" % name 3003718Sstever@eecs.umich.edu debug_flags[name] = (name, (), desc) 3012634Sstever@eecs.umich.edu 3022634Sstever@eecs.umich.edudef CompoundFlag(name, flags, desc=None): 3035863Snate@binkert.org if name in debug_flags: 3042638Sstever@eecs.umich.edu raise AttributeError, "Flag %s already specified" % name 3058268Ssteve.reinhardt@amd.com 3062632Sstever@eecs.umich.edu compound = tuple(flags) 3072632Sstever@eecs.umich.edu debug_flags[name] = (name, compound, desc) 3082632Sstever@eecs.umich.edu 3092632Sstever@eecs.umich.eduExport('DebugFlag') 3102632Sstever@eecs.umich.eduExport('CompoundFlag') 3111858SN/A 3123716Sstever@eecs.umich.edu######################################################################## 3132638Sstever@eecs.umich.edu# 3142638Sstever@eecs.umich.edu# Set some compiler variables 3152638Sstever@eecs.umich.edu# 3162638Sstever@eecs.umich.edu 3172638Sstever@eecs.umich.edu# Include file paths are rooted in this directory. SCons will 3182638Sstever@eecs.umich.edu# automatically expand '.' to refer to both the source directory and 3192638Sstever@eecs.umich.edu# the corresponding build directory to pick up generated include 3205863Snate@binkert.org# files. 3215863Snate@binkert.orgenv.Append(CPPPATH=Dir('.')) 3225863Snate@binkert.org 323955SN/Afor extra_dir in extras_dir_list: 3245341Sstever@gmail.com env.Append(CPPPATH=Dir(extra_dir)) 3255341Sstever@gmail.com 3265863Snate@binkert.org# Workaround for bug in SCons version > 0.97d20071212 3277756SAli.Saidi@ARM.com# Scons bug id: 2006 gem5 Bug id: 308 3285341Sstever@gmail.comfor root, dirs, files in os.walk(base_dir, topdown=True): 3296121Snate@binkert.org Dir(root[len(base_dir) + 1:]) 3304494Ssaidi@eecs.umich.edu 3316121Snate@binkert.org######################################################################## 3321105SN/A# 3332667Sstever@eecs.umich.edu# Walk the tree and execute all SConscripts in subdirectories 3342667Sstever@eecs.umich.edu# 3352667Sstever@eecs.umich.edu 3362667Sstever@eecs.umich.eduhere = Dir('.').srcnode().abspath 3376121Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True): 3382667Sstever@eecs.umich.edu if root == here: 3395341Sstever@gmail.com # we don't want to recurse back into this SConscript 3405863Snate@binkert.org continue 3415341Sstever@gmail.com 3425341Sstever@gmail.com if 'SConscript' in files: 3435341Sstever@gmail.com build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 3448120Sgblack@eecs.umich.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3455341Sstever@gmail.com 3468120Sgblack@eecs.umich.edufor extra_dir in extras_dir_list: 3475341Sstever@gmail.com prefix_len = len(dirname(extra_dir)) + 1 3488120Sgblack@eecs.umich.edu 3496121Snate@binkert.org # Also add the corresponding build directory to pick up generated 3506121Snate@binkert.org # include files. 3518980Ssteve.reinhardt@amd.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 3525397Ssaidi@eecs.umich.edu 3535397Ssaidi@eecs.umich.edu for root, dirs, files in os.walk(extra_dir, topdown=True): 3547727SAli.Saidi@ARM.com # if build lives in the extras directory, don't walk down it 3558268Ssteve.reinhardt@amd.com if 'build' in dirs: 3566168Snate@binkert.org dirs.remove('build') 3575341Sstever@gmail.com 3588120Sgblack@eecs.umich.edu if 'SConscript' in files: 3598120Sgblack@eecs.umich.edu build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 3608120Sgblack@eecs.umich.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3616814Sgblack@eecs.umich.edu 3625863Snate@binkert.orgfor opt in export_vars: 3638120Sgblack@eecs.umich.edu env.ConfigFile(opt) 3645341Sstever@gmail.com 3655863Snate@binkert.orgdef makeTheISA(source, target, env): 3668268Ssteve.reinhardt@amd.com isas = [ src.get_contents() for src in source ] 3676121Snate@binkert.org target_isa = env['TARGET_ISA'] 3686121Snate@binkert.org def define(isa): 3698268Ssteve.reinhardt@amd.com return isa.upper() + '_ISA' 3705742Snate@binkert.org 3715742Snate@binkert.org def namespace(isa): 3725341Sstever@gmail.com return isa[0].upper() + isa[1:].lower() + 'ISA' 3735742Snate@binkert.org 3745742Snate@binkert.org 3755341Sstever@gmail.com code = code_formatter() 3766017Snate@binkert.org code('''\ 3776121Snate@binkert.org#ifndef __CONFIG_THE_ISA_HH__ 3786017Snate@binkert.org#define __CONFIG_THE_ISA_HH__ 3797816Ssteve.reinhardt@amd.com 3807756SAli.Saidi@ARM.com''') 3817756SAli.Saidi@ARM.com 3827756SAli.Saidi@ARM.com # create defines for the preprocessing and compile-time determination 3837756SAli.Saidi@ARM.com for i,isa in enumerate(isas): 3847756SAli.Saidi@ARM.com code('#define $0 $1', define(isa), i + 1) 3857756SAli.Saidi@ARM.com code() 3867756SAli.Saidi@ARM.com 3877756SAli.Saidi@ARM.com # create an enum for any run-time determination of the ISA, we 3887816Ssteve.reinhardt@amd.com # reuse the same name as the namespaces 3897816Ssteve.reinhardt@amd.com code('enum class Arch {') 3907816Ssteve.reinhardt@amd.com for i,isa in enumerate(isas): 3917816Ssteve.reinhardt@amd.com if i + 1 == len(isas): 3927816Ssteve.reinhardt@amd.com code(' $0 = $1', namespace(isa), define(isa)) 3937816Ssteve.reinhardt@amd.com else: 3947816Ssteve.reinhardt@amd.com code(' $0 = $1,', namespace(isa), define(isa)) 3957816Ssteve.reinhardt@amd.com code('};') 3967816Ssteve.reinhardt@amd.com 3977816Ssteve.reinhardt@amd.com code(''' 3987756SAli.Saidi@ARM.com 3997816Ssteve.reinhardt@amd.com#define THE_ISA ${{define(target_isa)}} 4007816Ssteve.reinhardt@amd.com#define TheISA ${{namespace(target_isa)}} 4017816Ssteve.reinhardt@amd.com#define THE_ISA_STR "${{target_isa}}" 4027816Ssteve.reinhardt@amd.com 4037816Ssteve.reinhardt@amd.com#endif // __CONFIG_THE_ISA_HH__''') 4047816Ssteve.reinhardt@amd.com 4057816Ssteve.reinhardt@amd.com code.write(str(target[0])) 4067816Ssteve.reinhardt@amd.com 4077816Ssteve.reinhardt@amd.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 4087816Ssteve.reinhardt@amd.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 4097816Ssteve.reinhardt@amd.com 4107816Ssteve.reinhardt@amd.comdef makeTheGPUISA(source, target, env): 4117816Ssteve.reinhardt@amd.com isas = [ src.get_contents() for src in source ] 4127816Ssteve.reinhardt@amd.com target_gpu_isa = env['TARGET_GPU_ISA'] 4137816Ssteve.reinhardt@amd.com def define(isa): 4147816Ssteve.reinhardt@amd.com return isa.upper() + '_ISA' 4157816Ssteve.reinhardt@amd.com 4167816Ssteve.reinhardt@amd.com def namespace(isa): 4177816Ssteve.reinhardt@amd.com return isa[0].upper() + isa[1:].lower() + 'ISA' 4187816Ssteve.reinhardt@amd.com 4197816Ssteve.reinhardt@amd.com 4207816Ssteve.reinhardt@amd.com code = code_formatter() 4217816Ssteve.reinhardt@amd.com code('''\ 4227816Ssteve.reinhardt@amd.com#ifndef __CONFIG_THE_GPU_ISA_HH__ 4237816Ssteve.reinhardt@amd.com#define __CONFIG_THE_GPU_ISA_HH__ 4247816Ssteve.reinhardt@amd.com 4257816Ssteve.reinhardt@amd.com''') 4267816Ssteve.reinhardt@amd.com 4277816Ssteve.reinhardt@amd.com # create defines for the preprocessing and compile-time determination 4287816Ssteve.reinhardt@amd.com for i,isa in enumerate(isas): 4297816Ssteve.reinhardt@amd.com code('#define $0 $1', define(isa), i + 1) 4307816Ssteve.reinhardt@amd.com code() 4317816Ssteve.reinhardt@amd.com 4327816Ssteve.reinhardt@amd.com # create an enum for any run-time determination of the ISA, we 4337816Ssteve.reinhardt@amd.com # reuse the same name as the namespaces 4347816Ssteve.reinhardt@amd.com code('enum class GPUArch {') 4357816Ssteve.reinhardt@amd.com for i,isa in enumerate(isas): 4367816Ssteve.reinhardt@amd.com if i + 1 == len(isas): 4377816Ssteve.reinhardt@amd.com code(' $0 = $1', namespace(isa), define(isa)) 4387816Ssteve.reinhardt@amd.com else: 4397816Ssteve.reinhardt@amd.com code(' $0 = $1,', namespace(isa), define(isa)) 4407816Ssteve.reinhardt@amd.com code('};') 4417816Ssteve.reinhardt@amd.com 4427816Ssteve.reinhardt@amd.com code(''' 4437816Ssteve.reinhardt@amd.com 4447816Ssteve.reinhardt@amd.com#define THE_GPU_ISA ${{define(target_gpu_isa)}} 4457816Ssteve.reinhardt@amd.com#define TheGpuISA ${{namespace(target_gpu_isa)}} 4467816Ssteve.reinhardt@amd.com#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 4477816Ssteve.reinhardt@amd.com 4487816Ssteve.reinhardt@amd.com#endif // __CONFIG_THE_GPU_ISA_HH__''') 4497816Ssteve.reinhardt@amd.com 4507816Ssteve.reinhardt@amd.com code.write(str(target[0])) 4517816Ssteve.reinhardt@amd.com 4527816Ssteve.reinhardt@amd.comenv.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 4537816Ssteve.reinhardt@amd.com MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 4547816Ssteve.reinhardt@amd.com 4557816Ssteve.reinhardt@amd.com######################################################################## 4567816Ssteve.reinhardt@amd.com# 4577816Ssteve.reinhardt@amd.com# Prevent any SimObjects from being added after this point, they 4587816Ssteve.reinhardt@amd.com# should all have been added in the SConscripts above 4597816Ssteve.reinhardt@amd.com# 4608947Sandreas.hansson@arm.comSimObject.fixed = True 4618947Sandreas.hansson@arm.com 4627756SAli.Saidi@ARM.comclass DictImporter(object): 4638120Sgblack@eecs.umich.edu '''This importer takes a dictionary of arbitrary module names that 4647756SAli.Saidi@ARM.com map to arbitrary filenames.''' 4657756SAli.Saidi@ARM.com def __init__(self, modules): 4667756SAli.Saidi@ARM.com self.modules = modules 4677756SAli.Saidi@ARM.com self.installed = set() 4687816Ssteve.reinhardt@amd.com 4697816Ssteve.reinhardt@amd.com def __del__(self): 4707816Ssteve.reinhardt@amd.com self.unload() 4717816Ssteve.reinhardt@amd.com 4727816Ssteve.reinhardt@amd.com def unload(self): 4737816Ssteve.reinhardt@amd.com import sys 4747816Ssteve.reinhardt@amd.com for module in self.installed: 4757816Ssteve.reinhardt@amd.com del sys.modules[module] 4767816Ssteve.reinhardt@amd.com self.installed = set() 4777816Ssteve.reinhardt@amd.com 4787756SAli.Saidi@ARM.com def find_module(self, fullname, path): 4797756SAli.Saidi@ARM.com if fullname == 'm5.defines': 4806654Snate@binkert.org return self 4816654Snate@binkert.org 4825871Snate@binkert.org if fullname == 'm5.objects': 4836121Snate@binkert.org return self 4846121Snate@binkert.org 4856121Snate@binkert.org if fullname.startswith('m5.internal'): 4868946Sandreas.hansson@arm.com return None 4878737Skoansin.tan@gmail.com 4883940Ssaidi@eecs.umich.edu source = self.modules.get(fullname, None) 4893918Ssaidi@eecs.umich.edu if source is not None and fullname.startswith('m5.objects'): 4903918Ssaidi@eecs.umich.edu return self 4911858SN/A 4926121Snate@binkert.org return None 4937739Sgblack@eecs.umich.edu 4947739Sgblack@eecs.umich.edu def load_module(self, fullname): 4956143Snate@binkert.org mod = imp.new_module(fullname) 4967618SAli.Saidi@arm.com sys.modules[fullname] = mod 4977618SAli.Saidi@arm.com self.installed.add(fullname) 4987618SAli.Saidi@arm.com 4997618SAli.Saidi@arm.com mod.__loader__ = self 5008614Sgblack@eecs.umich.edu if fullname == 'm5.objects': 5017618SAli.Saidi@arm.com mod.__path__ = fullname.split('.') 5027618SAli.Saidi@arm.com return mod 5037618SAli.Saidi@arm.com 5047739Sgblack@eecs.umich.edu if fullname == 'm5.defines': 5058946Sandreas.hansson@arm.com mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 5068946Sandreas.hansson@arm.com return mod 5076121Snate@binkert.org 5083940Ssaidi@eecs.umich.edu source = self.modules[fullname] 5096121Snate@binkert.org if source.modname == '__init__': 5107739Sgblack@eecs.umich.edu mod.__path__ = source.modpath 5117739Sgblack@eecs.umich.edu mod.__file__ = source.abspath 5127739Sgblack@eecs.umich.edu 5137739Sgblack@eecs.umich.edu exec file(source.abspath, 'r') in mod.__dict__ 5147739Sgblack@eecs.umich.edu 5157739Sgblack@eecs.umich.edu return mod 5168737Skoansin.tan@gmail.com 5178737Skoansin.tan@gmail.comimport m5.SimObject 5188737Skoansin.tan@gmail.comimport m5.params 5198737Skoansin.tan@gmail.comfrom m5.util import code_formatter 5208737Skoansin.tan@gmail.com 5218737Skoansin.tan@gmail.comm5.SimObject.clear() 5228737Skoansin.tan@gmail.comm5.params.clear() 5238737Skoansin.tan@gmail.com 5248737Skoansin.tan@gmail.com# install the python importer so we can grab stuff from the source 5258737Skoansin.tan@gmail.com# tree itself. We can't have SimObjects added after this point or 5268737Skoansin.tan@gmail.com# else we won't know about them for the rest of the stuff. 5278737Skoansin.tan@gmail.comimporter = DictImporter(PySource.modules) 5288737Skoansin.tan@gmail.comsys.meta_path[0:0] = [ importer ] 5298737Skoansin.tan@gmail.com 5308737Skoansin.tan@gmail.com# import all sim objects so we can populate the all_objects list 5318737Skoansin.tan@gmail.com# make sure that we're working with a list, then let's sort it 5328737Skoansin.tan@gmail.comfor modname in SimObject.modnames: 5338737Skoansin.tan@gmail.com exec('from m5.objects import %s' % modname) 5348946Sandreas.hansson@arm.com 5358946Sandreas.hansson@arm.com# we need to unload all of the currently imported modules so that they 5368946Sandreas.hansson@arm.com# will be re-imported the next time the sconscript is run 5378946Sandreas.hansson@arm.comimporter.unload() 5388946Sandreas.hansson@arm.comsys.meta_path.remove(importer) 5398946Sandreas.hansson@arm.com 5403918Ssaidi@eecs.umich.edusim_objects = m5.SimObject.allClasses 5419068SAli.Saidi@ARM.comall_enums = m5.params.allEnums 5429068SAli.Saidi@ARM.com 5439068SAli.Saidi@ARM.comif m5.SimObject.noCxxHeader: 5449068SAli.Saidi@ARM.com print >> sys.stderr, \ 5459068SAli.Saidi@ARM.com "warning: At least one SimObject lacks a header specification. " \ 5469068SAli.Saidi@ARM.com "This can cause unexpected results in the generated SWIG " \ 5479068SAli.Saidi@ARM.com "wrappers." 5489068SAli.Saidi@ARM.com 5499068SAli.Saidi@ARM.com# Find param types that need to be explicitly wrapped with swig. 5509068SAli.Saidi@ARM.com# These will be recognized because the ParamDesc will have a 5519068SAli.Saidi@ARM.com# swig_decl() method. Most param types are based on types that don't 5529068SAli.Saidi@ARM.com# need this, either because they're based on native types (like Int) 5539068SAli.Saidi@ARM.com# or because they're SimObjects (which get swigged independently). 5549068SAli.Saidi@ARM.com# For now the only things handled here are VectorParam types. 5559068SAli.Saidi@ARM.comparams_to_swig = {} 5569068SAli.Saidi@ARM.comfor name,obj in sorted(sim_objects.iteritems()): 5573918Ssaidi@eecs.umich.edu for param in obj._params.local.values(): 5583918Ssaidi@eecs.umich.edu # load the ptype attribute now because it depends on the 5596157Snate@binkert.org # current version of SimObject.allClasses, but when scons 5606157Snate@binkert.org # actually uses the value, all versions of 5616157Snate@binkert.org # SimObject.allClasses will have been loaded 5626157Snate@binkert.org param.ptype 5635397Ssaidi@eecs.umich.edu 5645397Ssaidi@eecs.umich.edu if not hasattr(param, 'swig_decl'): 5656121Snate@binkert.org continue 5666121Snate@binkert.org pname = param.ptype_str 5676121Snate@binkert.org if pname not in params_to_swig: 5686121Snate@binkert.org params_to_swig[pname] = param 5696121Snate@binkert.org 5706121Snate@binkert.org######################################################################## 5715397Ssaidi@eecs.umich.edu# 5721851SN/A# calculate extra dependencies 5731851SN/A# 5747739Sgblack@eecs.umich.edumodule_depends = ["m5", "m5.SimObject", "m5.params"] 575955SN/Adepends = [ PySource.modules[dep].snode for dep in module_depends ] 5763053Sstever@eecs.umich.edudepends.sort(key = lambda x: x.name) 5776121Snate@binkert.org 5783053Sstever@eecs.umich.edu######################################################################## 5793053Sstever@eecs.umich.edu# 5803053Sstever@eecs.umich.edu# Commands for the basic automatically generated python files 5813053Sstever@eecs.umich.edu# 5823053Sstever@eecs.umich.edu 5839072Sandreas.hansson@arm.com# Generate Python file containing a dict specifying the current 5843053Sstever@eecs.umich.edu# buildEnv flags. 5854742Sstever@eecs.umich.edudef makeDefinesPyFile(target, source, env): 5864742Sstever@eecs.umich.edu build_env = source[0].get_contents() 5873053Sstever@eecs.umich.edu 5883053Sstever@eecs.umich.edu code = code_formatter() 5893053Sstever@eecs.umich.edu code(""" 5908960Ssteve.reinhardt@amd.comimport m5.internal 5916654Snate@binkert.orgimport m5.util 5923053Sstever@eecs.umich.edu 5933053Sstever@eecs.umich.edubuildEnv = m5.util.SmartDict($build_env) 5943053Sstever@eecs.umich.edu 5953053Sstever@eecs.umich.educompileDate = m5.internal.core.compileDate 5962667Sstever@eecs.umich.edu_globals = globals() 5974554Sbinkertn@umich.edufor key,val in m5.internal.core.__dict__.iteritems(): 5986121Snate@binkert.org if key.startswith('flag_'): 5992667Sstever@eecs.umich.edu flag = key[5:] 6004554Sbinkertn@umich.edu _globals[flag] = val 6014554Sbinkertn@umich.edudel _globals 6024554Sbinkertn@umich.edu""") 6036121Snate@binkert.org code.write(target[0].abspath) 6044554Sbinkertn@umich.edu 6054554Sbinkertn@umich.edudefines_info = Value(build_env) 6064554Sbinkertn@umich.edu# Generate a file with all of the compile options in it 6074781Snate@binkert.orgenv.Command('python/m5/defines.py', defines_info, 6084554Sbinkertn@umich.edu MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 6094554Sbinkertn@umich.eduPySource('m5', 'python/m5/defines.py') 6102667Sstever@eecs.umich.edu 6114554Sbinkertn@umich.edu# Generate python file containing info about the M5 source code 6124554Sbinkertn@umich.edudef makeInfoPyFile(target, source, env): 6134554Sbinkertn@umich.edu code = code_formatter() 6144554Sbinkertn@umich.edu for src in source: 6152667Sstever@eecs.umich.edu data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 6164554Sbinkertn@umich.edu code('$src = ${{repr(data)}}') 6172667Sstever@eecs.umich.edu code.write(str(target[0])) 6184554Sbinkertn@umich.edu 6196121Snate@binkert.org# Generate a file that wraps the basic top level files 6202667Sstever@eecs.umich.eduenv.Command('python/m5/info.py', 6215522Snate@binkert.org [ '#/COPYING', '#/LICENSE', '#/README', ], 6225522Snate@binkert.org MakeAction(makeInfoPyFile, Transform("INFO"))) 6235522Snate@binkert.orgPySource('m5', 'python/m5/info.py') 6245522Snate@binkert.org 6255522Snate@binkert.org######################################################################## 6265522Snate@binkert.org# 6275522Snate@binkert.org# Create all of the SimObject param headers and enum headers 6285522Snate@binkert.org# 6295522Snate@binkert.org 6305522Snate@binkert.orgdef createSimObjectParamStruct(target, source, env): 6315522Snate@binkert.org assert len(target) == 1 and len(source) == 1 6325522Snate@binkert.org 6335522Snate@binkert.org name = str(source[0].get_contents()) 6345522Snate@binkert.org obj = sim_objects[name] 6355522Snate@binkert.org 6365522Snate@binkert.org code = code_formatter() 6375522Snate@binkert.org obj.cxx_param_decl(code) 6385522Snate@binkert.org code.write(target[0].abspath) 6395522Snate@binkert.org 6405522Snate@binkert.orgdef createSimObjectCxxConfig(is_header): 6415522Snate@binkert.org def body(target, source, env): 6425522Snate@binkert.org assert len(target) == 1 and len(source) == 1 6435522Snate@binkert.org 6445522Snate@binkert.org name = str(source[0].get_contents()) 6455522Snate@binkert.org obj = sim_objects[name] 6465522Snate@binkert.org 6472638Sstever@eecs.umich.edu code = code_formatter() 6482638Sstever@eecs.umich.edu obj.cxx_config_param_file(code, is_header) 6496121Snate@binkert.org code.write(target[0].abspath) 6503716Sstever@eecs.umich.edu return body 6515522Snate@binkert.org 6525522Snate@binkert.orgdef createParamSwigWrapper(target, source, env): 6535522Snate@binkert.org assert len(target) == 1 and len(source) == 1 6545522Snate@binkert.org 6555522Snate@binkert.org name = str(source[0].get_contents()) 6565522Snate@binkert.org param = params_to_swig[name] 6571858SN/A 6585227Ssaidi@eecs.umich.edu code = code_formatter() 6595227Ssaidi@eecs.umich.edu param.swig_decl(code) 6605227Ssaidi@eecs.umich.edu code.write(target[0].abspath) 6615227Ssaidi@eecs.umich.edu 6626654Snate@binkert.orgdef createEnumStrings(target, source, env): 6636654Snate@binkert.org assert len(target) == 1 and len(source) == 1 6647769SAli.Saidi@ARM.com 6657769SAli.Saidi@ARM.com name = str(source[0].get_contents()) 6667769SAli.Saidi@ARM.com obj = all_enums[name] 6677769SAli.Saidi@ARM.com 6685227Ssaidi@eecs.umich.edu code = code_formatter() 6695227Ssaidi@eecs.umich.edu obj.cxx_def(code) 6705227Ssaidi@eecs.umich.edu code.write(target[0].abspath) 6715204Sstever@gmail.com 6725204Sstever@gmail.comdef createEnumDecls(target, source, env): 6735204Sstever@gmail.com assert len(target) == 1 and len(source) == 1 6745204Sstever@gmail.com 6755204Sstever@gmail.com name = str(source[0].get_contents()) 6765204Sstever@gmail.com obj = all_enums[name] 6775204Sstever@gmail.com 6785204Sstever@gmail.com code = code_formatter() 6795204Sstever@gmail.com obj.cxx_decl(code) 6805204Sstever@gmail.com code.write(target[0].abspath) 6815204Sstever@gmail.com 6825204Sstever@gmail.comdef createEnumSwigWrapper(target, source, env): 6835204Sstever@gmail.com assert len(target) == 1 and len(source) == 1 6845204Sstever@gmail.com 6855204Sstever@gmail.com name = str(source[0].get_contents()) 6865204Sstever@gmail.com obj = all_enums[name] 6875204Sstever@gmail.com 6886121Snate@binkert.org code = code_formatter() 6895204Sstever@gmail.com obj.swig_decl(code) 6903118Sstever@eecs.umich.edu code.write(target[0].abspath) 6913118Sstever@eecs.umich.edu 6923118Sstever@eecs.umich.edudef createSimObjectSwigWrapper(target, source, env): 6933118Sstever@eecs.umich.edu name = source[0].get_contents() 6943118Sstever@eecs.umich.edu obj = sim_objects[name] 6955863Snate@binkert.org 6963118Sstever@eecs.umich.edu code = code_formatter() 6975863Snate@binkert.org obj.swig_decl(code) 6983118Sstever@eecs.umich.edu code.write(target[0].abspath) 6997457Snate@binkert.org 7007457Snate@binkert.org# dummy target for generated code 7015863Snate@binkert.org# we start out with all the Source files so they get copied to build/*/ also. 7025863Snate@binkert.orgSWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 7035863Snate@binkert.org 7045863Snate@binkert.org# Generate all of the SimObject param C++ struct header files 7055863Snate@binkert.orgparams_hh_files = [] 7065863Snate@binkert.orgfor name,simobj in sorted(sim_objects.iteritems()): 7075863Snate@binkert.org py_source = PySource.modules[simobj.__module__] 7086003Snate@binkert.org extra_deps = [ py_source.tnode ] 7095863Snate@binkert.org 7105863Snate@binkert.org hh_file = File('params/%s.hh' % name) 7115863Snate@binkert.org params_hh_files.append(hh_file) 7126120Snate@binkert.org env.Command(hh_file, Value(name), 7135863Snate@binkert.org MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 7145863Snate@binkert.org env.Depends(hh_file, depends + extra_deps) 7155863Snate@binkert.org env.Depends(SWIG, hh_file) 7168655Sandreas.hansson@arm.com 7178655Sandreas.hansson@arm.com# C++ parameter description files 7188655Sandreas.hansson@arm.comif GetOption('with_cxx_config'): 7198655Sandreas.hansson@arm.com for name,simobj in sorted(sim_objects.iteritems()): 7208655Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 7218655Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 7228655Sandreas.hansson@arm.com 7238655Sandreas.hansson@arm.com cxx_config_hh_file = File('cxx_config/%s.hh' % name) 7246120Snate@binkert.org cxx_config_cc_file = File('cxx_config/%s.cc' % name) 7255863Snate@binkert.org env.Command(cxx_config_hh_file, Value(name), 7266121Snate@binkert.org MakeAction(createSimObjectCxxConfig(True), 7276121Snate@binkert.org Transform("CXXCPRHH"))) 7285863Snate@binkert.org env.Command(cxx_config_cc_file, Value(name), 7297727SAli.Saidi@ARM.com MakeAction(createSimObjectCxxConfig(False), 7307727SAli.Saidi@ARM.com Transform("CXXCPRCC"))) 7317727SAli.Saidi@ARM.com env.Depends(cxx_config_hh_file, depends + extra_deps + 7327727SAli.Saidi@ARM.com [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 7337727SAli.Saidi@ARM.com env.Depends(cxx_config_cc_file, depends + extra_deps + 7347727SAli.Saidi@ARM.com [cxx_config_hh_file]) 7355863Snate@binkert.org Source(cxx_config_cc_file) 7363118Sstever@eecs.umich.edu 7375863Snate@binkert.org cxx_config_init_cc_file = File('cxx_config/init.cc') 7383118Sstever@eecs.umich.edu 7393118Sstever@eecs.umich.edu def createCxxConfigInitCC(target, source, env): 7405863Snate@binkert.org assert len(target) == 1 and len(source) == 1 7415863Snate@binkert.org 7425863Snate@binkert.org code = code_formatter() 7435863Snate@binkert.org 7443118Sstever@eecs.umich.edu for name,simobj in sorted(sim_objects.iteritems()): 7453483Ssaidi@eecs.umich.edu if not hasattr(simobj, 'abstract') or not simobj.abstract: 7463494Ssaidi@eecs.umich.edu code('#include "cxx_config/${name}.hh"') 7473494Ssaidi@eecs.umich.edu code() 7483483Ssaidi@eecs.umich.edu code('void cxxConfigInit()') 7493483Ssaidi@eecs.umich.edu code('{') 7503483Ssaidi@eecs.umich.edu code.indent() 7513053Sstever@eecs.umich.edu for name,simobj in sorted(sim_objects.iteritems()): 7523053Sstever@eecs.umich.edu not_abstract = not hasattr(simobj, 'abstract') or \ 7533918Ssaidi@eecs.umich.edu not simobj.abstract 7543053Sstever@eecs.umich.edu if not_abstract and 'type' in simobj.__dict__: 7553053Sstever@eecs.umich.edu code('cxx_config_directory["${name}"] = ' 7563053Sstever@eecs.umich.edu '${name}CxxConfigParams::makeDirectoryEntry();') 7573053Sstever@eecs.umich.edu code.dedent() 7583053Sstever@eecs.umich.edu code('}') 7597840Snate@binkert.org code.write(target[0].abspath) 7607865Sgblack@eecs.umich.edu 7617865Sgblack@eecs.umich.edu py_source = PySource.modules[simobj.__module__] 7627865Sgblack@eecs.umich.edu extra_deps = [ py_source.tnode ] 7637865Sgblack@eecs.umich.edu env.Command(cxx_config_init_cc_file, Value(name), 7647865Sgblack@eecs.umich.edu MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 7657840Snate@binkert.org cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 7669045SAli.Saidi@ARM.com for name,simobj in sorted(sim_objects.iteritems()) 7679045SAli.Saidi@ARM.com if not hasattr(simobj, 'abstract') or not simobj.abstract] 7689045SAli.Saidi@ARM.com Depends(cxx_config_init_cc_file, cxx_param_hh_files + 7699045SAli.Saidi@ARM.com [File('sim/cxx_config.hh')]) 7709045SAli.Saidi@ARM.com Source(cxx_config_init_cc_file) 7719045SAli.Saidi@ARM.com 7729071Sandreas.hansson@arm.com# Generate any needed param SWIG wrapper files 7739071Sandreas.hansson@arm.comparams_i_files = [] 7749045SAli.Saidi@ARM.comfor name,param in sorted(params_to_swig.iteritems()): 7757840Snate@binkert.org i_file = File('python/m5/internal/%s.i' % (param.swig_module_name())) 7767840Snate@binkert.org params_i_files.append(i_file) 7777840Snate@binkert.org env.Command(i_file, Value(name), 7781858SN/A MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 7791858SN/A env.Depends(i_file, depends) 7801858SN/A env.Depends(SWIG, i_file) 7811858SN/A SwigSource('m5.internal', i_file) 7821858SN/A 7831858SN/A# Generate all enum header files 7845863Snate@binkert.orgfor name,enum in sorted(all_enums.iteritems()): 7855863Snate@binkert.org py_source = PySource.modules[enum.__module__] 7865863Snate@binkert.org extra_deps = [ py_source.tnode ] 7875863Snate@binkert.org 7886121Snate@binkert.org cc_file = File('enums/%s.cc' % name) 7891858SN/A env.Command(cc_file, Value(name), 7905863Snate@binkert.org MakeAction(createEnumStrings, Transform("ENUM STR"))) 7915863Snate@binkert.org env.Depends(cc_file, depends + extra_deps) 7925863Snate@binkert.org env.Depends(SWIG, cc_file) 7935863Snate@binkert.org Source(cc_file) 7945863Snate@binkert.org 7952139SN/A hh_file = File('enums/%s.hh' % name) 7964202Sbinkertn@umich.edu env.Command(hh_file, Value(name), 7974202Sbinkertn@umich.edu MakeAction(createEnumDecls, Transform("ENUMDECL"))) 7982139SN/A env.Depends(hh_file, depends + extra_deps) 7996994Snate@binkert.org env.Depends(SWIG, hh_file) 8006994Snate@binkert.org 8016994Snate@binkert.org i_file = File('python/m5/internal/enum_%s.i' % name) 8026994Snate@binkert.org env.Command(i_file, Value(name), 8036994Snate@binkert.org MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 8046994Snate@binkert.org env.Depends(i_file, depends + extra_deps) 8056994Snate@binkert.org env.Depends(SWIG, i_file) 8066994Snate@binkert.org SwigSource('m5.internal', i_file) 8076994Snate@binkert.org 8086994Snate@binkert.org# Generate SimObject SWIG wrapper files 8096994Snate@binkert.orgfor name,simobj in sorted(sim_objects.iteritems()): 8106994Snate@binkert.org py_source = PySource.modules[simobj.__module__] 8116994Snate@binkert.org extra_deps = [ py_source.tnode ] 8126994Snate@binkert.org i_file = File('python/m5/internal/param_%s.i' % name) 8136994Snate@binkert.org env.Command(i_file, Value(name), 8146994Snate@binkert.org MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 8156994Snate@binkert.org env.Depends(i_file, depends + extra_deps) 8166994Snate@binkert.org SwigSource('m5.internal', i_file) 8176994Snate@binkert.org 8186994Snate@binkert.org# Generate the main swig init file 8196994Snate@binkert.orgdef makeEmbeddedSwigInit(target, source, env): 8206994Snate@binkert.org code = code_formatter() 8216994Snate@binkert.org module = source[0].get_contents() 8226994Snate@binkert.org code('''\ 8236994Snate@binkert.org#include "sim/init.hh" 8246994Snate@binkert.org 8256994Snate@binkert.orgextern "C" { 8266994Snate@binkert.org void init_${module}(); 8272155SN/A} 8285863Snate@binkert.org 8291869SN/AEmbeddedSwig embed_swig_${module}(init_${module}); 8301869SN/A''') 8315863Snate@binkert.org code.write(str(target[0])) 8325863Snate@binkert.org 8334202Sbinkertn@umich.edu# Build all swig modules 8346108Snate@binkert.orgfor swig in SwigSource.all: 8356108Snate@binkert.org env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 8366108Snate@binkert.org MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 8376108Snate@binkert.org '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 8384202Sbinkertn@umich.edu cc_file = str(swig.tnode) 8395863Snate@binkert.org init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 8408474Sgblack@eecs.umich.edu env.Command(init_file, Value(swig.module), 8418474Sgblack@eecs.umich.edu MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) 8425742Snate@binkert.org env.Depends(SWIG, init_file) 8438268Ssteve.reinhardt@amd.com Source(init_file, **swig.guards) 8448268Ssteve.reinhardt@amd.com 8458268Ssteve.reinhardt@amd.com# Build all protocol buffers if we have got protoc and protobuf available 8465742Snate@binkert.orgif env['HAVE_PROTOBUF']: 8475341Sstever@gmail.com for proto in ProtoBuf.all: 8488474Sgblack@eecs.umich.edu # Use both the source and header as the target, and the .proto 8498474Sgblack@eecs.umich.edu # file as the source. When executing the protoc compiler, also 8505342Sstever@gmail.com # specify the proto_path to avoid having the generated files 8514202Sbinkertn@umich.edu # include the path. 8524202Sbinkertn@umich.edu env.Command([proto.cc_file, proto.hh_file], proto.tnode, 8534202Sbinkertn@umich.edu MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 8545863Snate@binkert.org '--proto_path ${SOURCE.dir} $SOURCE', 8555863Snate@binkert.org Transform("PROTOC"))) 8566994Snate@binkert.org 8576994Snate@binkert.org env.Depends(SWIG, [proto.cc_file, proto.hh_file]) 8586994Snate@binkert.org # Add the C++ source file 8595863Snate@binkert.org Source(proto.cc_file, **proto.guards) 8605863Snate@binkert.orgelif ProtoBuf.all: 8615863Snate@binkert.org print 'Got protobuf to build, but lacks support!' 8625863Snate@binkert.org Exit(1) 8635863Snate@binkert.org 8645863Snate@binkert.org# 8655863Snate@binkert.org# Handle debug flags 8665863Snate@binkert.org# 8677840Snate@binkert.orgdef makeDebugFlagCC(target, source, env): 8685863Snate@binkert.org assert(len(target) == 1 and len(source) == 1) 8695952Ssaidi@eecs.umich.edu 8701869SN/A code = code_formatter() 8711858SN/A 8725863Snate@binkert.org # delay definition of CompoundFlags until after all the definition 8739044SAli.Saidi@ARM.com # of all constituent SimpleFlags 8748805Sgblack@eecs.umich.edu comp_code = code_formatter() 8751858SN/A 876955SN/A # file header 877955SN/A code(''' 8781869SN/A/* 8791869SN/A * DO NOT EDIT THIS FILE! Automatically generated by SCons. 8801869SN/A */ 8811869SN/A 8821869SN/A#include "base/debug.hh" 8835863Snate@binkert.org 8845863Snate@binkert.orgnamespace Debug { 8855863Snate@binkert.org 8861869SN/A''') 8875863Snate@binkert.org 8881869SN/A for name, flag in sorted(source[0].read().iteritems()): 8895863Snate@binkert.org n, compound, desc = flag 8901869SN/A assert n == name 8911869SN/A 8921869SN/A if not compound: 8931869SN/A code('SimpleFlag $name("$name", "$desc");') 8948483Sgblack@eecs.umich.edu else: 8951869SN/A comp_code('CompoundFlag $name("$name", "$desc",') 8961869SN/A comp_code.indent() 8971869SN/A last = len(compound) - 1 8981869SN/A for i,flag in enumerate(compound): 8995863Snate@binkert.org if i != last: 9005863Snate@binkert.org comp_code('&$flag,') 9011869SN/A else: 9025863Snate@binkert.org comp_code('&$flag);') 9035863Snate@binkert.org comp_code.dedent() 9043356Sbinkertn@umich.edu 9053356Sbinkertn@umich.edu code.append(comp_code) 9063356Sbinkertn@umich.edu code() 9073356Sbinkertn@umich.edu code('} // namespace Debug') 9083356Sbinkertn@umich.edu 9094781Snate@binkert.org code.write(str(target[0])) 9105863Snate@binkert.org 9115863Snate@binkert.orgdef makeDebugFlagHH(target, source, env): 9121869SN/A assert(len(target) == 1 and len(source) == 1) 9131869SN/A 9141869SN/A val = eval(source[0].get_contents()) 9156121Snate@binkert.org name, compound, desc = val 9161869SN/A 9172638Sstever@eecs.umich.edu code = code_formatter() 9186121Snate@binkert.org 9196121Snate@binkert.org # file header boilerplate 9202638Sstever@eecs.umich.edu code('''\ 9215749Scws3k@cs.virginia.edu/* 9226121Snate@binkert.org * DO NOT EDIT THIS FILE! Automatically generated by SCons. 9236121Snate@binkert.org */ 9245749Scws3k@cs.virginia.edu 9251869SN/A#ifndef __DEBUG_${name}_HH__ 9261869SN/A#define __DEBUG_${name}_HH__ 9273546Sgblack@eecs.umich.edu 9283546Sgblack@eecs.umich.edunamespace Debug { 9293546Sgblack@eecs.umich.edu''') 9303546Sgblack@eecs.umich.edu 9316121Snate@binkert.org if compound: 9325863Snate@binkert.org code('class CompoundFlag;') 9333546Sgblack@eecs.umich.edu code('class SimpleFlag;') 9343546Sgblack@eecs.umich.edu 9353546Sgblack@eecs.umich.edu if compound: 9363546Sgblack@eecs.umich.edu code('extern CompoundFlag $name;') 9374781Snate@binkert.org for flag in compound: 9384781Snate@binkert.org code('extern SimpleFlag $flag;') 9396658Snate@binkert.org else: 9406658Snate@binkert.org code('extern SimpleFlag $name;') 9414781Snate@binkert.org 9423546Sgblack@eecs.umich.edu code(''' 9433546Sgblack@eecs.umich.edu} 9443546Sgblack@eecs.umich.edu 9453546Sgblack@eecs.umich.edu#endif // __DEBUG_${name}_HH__ 9467756SAli.Saidi@ARM.com''') 9477816Ssteve.reinhardt@amd.com 9483546Sgblack@eecs.umich.edu code.write(str(target[0])) 9493546Sgblack@eecs.umich.edu 9503546Sgblack@eecs.umich.edufor name,flag in sorted(debug_flags.iteritems()): 9513546Sgblack@eecs.umich.edu n, compound, desc = flag 9524202Sbinkertn@umich.edu assert n == name 9533546Sgblack@eecs.umich.edu 9543546Sgblack@eecs.umich.edu hh_file = 'debug/%s.hh' % name 9553546Sgblack@eecs.umich.edu env.Command(hh_file, Value(flag), 956955SN/A MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 957955SN/A env.Depends(SWIG, hh_file) 958955SN/A 959955SN/Aenv.Command('debug/flags.cc', Value(debug_flags), 9605863Snate@binkert.org MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 9615863Snate@binkert.orgenv.Depends(SWIG, 'debug/flags.cc') 9625343Sstever@gmail.comSource('debug/flags.cc') 9635343Sstever@gmail.com 9646121Snate@binkert.org# version tags 9655863Snate@binkert.orgtags = \ 9664773Snate@binkert.orgenv.Command('sim/tags.cc', None, 9675863Snate@binkert.org MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 9682632Sstever@eecs.umich.edu Transform("VER TAGS"))) 9695863Snate@binkert.orgenv.AlwaysBuild(tags) 9702023SN/A 9715863Snate@binkert.org# Embed python files. All .py files that have been indicated by a 9725863Snate@binkert.org# PySource() call in a SConscript need to be embedded into the M5 9735863Snate@binkert.org# library. To do that, we compile the file to byte code, marshal the 9745863Snate@binkert.org# byte code, compress it, and then generate a c++ file that 9755863Snate@binkert.org# inserts the result into an array. 9765863Snate@binkert.orgdef embedPyFile(target, source, env): 9775863Snate@binkert.org def c_str(string): 9785863Snate@binkert.org if string is None: 9795863Snate@binkert.org return "0" 9802632Sstever@eecs.umich.edu return '"%s"' % string 9815863Snate@binkert.org 9822023SN/A '''Action function to compile a .py into a code object, marshal 9832632Sstever@eecs.umich.edu it, compress it, and stick it into an asm file so the code appears 9845863Snate@binkert.org as just bytes with a label in the data section''' 9855342Sstever@gmail.com 9865863Snate@binkert.org src = file(str(source[0]), 'r').read() 9872632Sstever@eecs.umich.edu 9885863Snate@binkert.org pysource = PySource.tnodes[source[0]] 9895863Snate@binkert.org compiled = compile(src, pysource.abspath, 'exec') 9908267Ssteve.reinhardt@amd.com marshalled = marshal.dumps(compiled) 9918120Sgblack@eecs.umich.edu compressed = zlib.compress(marshalled) 9928267Ssteve.reinhardt@amd.com data = compressed 9938267Ssteve.reinhardt@amd.com sym = pysource.symname 9948267Ssteve.reinhardt@amd.com 9958267Ssteve.reinhardt@amd.com code = code_formatter() 9968267Ssteve.reinhardt@amd.com code('''\ 9978267Ssteve.reinhardt@amd.com#include "sim/init.hh" 9988267Ssteve.reinhardt@amd.com 9998267Ssteve.reinhardt@amd.comnamespace { 10008267Ssteve.reinhardt@amd.com 10015863Snate@binkert.orgconst uint8_t data_${sym}[] = { 10025863Snate@binkert.org''') 10035863Snate@binkert.org code.indent() 10042632Sstever@eecs.umich.edu step = 16 10058267Ssteve.reinhardt@amd.com for i in xrange(0, len(data), step): 10068267Ssteve.reinhardt@amd.com x = array.array('B', data[i:i+step]) 10078267Ssteve.reinhardt@amd.com code(''.join('%d,' % d for d in x)) 10082632Sstever@eecs.umich.edu code.dedent() 10091888SN/A 10105863Snate@binkert.org code('''}; 10115863Snate@binkert.org 10121858SN/AEmbeddedPython embedded_${sym}( 10138120Sgblack@eecs.umich.edu ${{c_str(pysource.arcname)}}, 10148120Sgblack@eecs.umich.edu ${{c_str(pysource.abspath)}}, 10157756SAli.Saidi@ARM.com ${{c_str(pysource.modpath)}}, 10162598SN/A data_${sym}, 10175863Snate@binkert.org ${{len(data)}}, 10181858SN/A ${{len(marshalled)}}); 10191858SN/A 10201858SN/A} // anonymous namespace 10215863Snate@binkert.org''') 10221858SN/A code.write(str(target[0])) 10231858SN/A 10241858SN/Afor source in PySource.all: 10255863Snate@binkert.org env.Command(source.cpp, source.tnode, 10261871SN/A MakeAction(embedPyFile, Transform("EMBED PY"))) 10271858SN/A env.Depends(SWIG, source.cpp) 10281858SN/A Source(source.cpp, skip_no_python=True) 10291858SN/A 10301858SN/A######################################################################## 10315863Snate@binkert.org# 10325863Snate@binkert.org# Define binaries. Each different build type (debug, opt, etc.) gets 10331869SN/A# a slightly different build environment. 10341965SN/A# 10357739Sgblack@eecs.umich.edu 10361965SN/A# List of constructed environments to pass back to SConstruct 10379045SAli.Saidi@ARM.comdate_source = Source('base/date.cc', skip_lib=True) 10389045SAli.Saidi@ARM.com 10399045SAli.Saidi@ARM.com# Capture this directory for the closure makeEnv, otherwise when it is 10402761Sstever@eecs.umich.edu# called, it won't know what directory it should use. 10415863Snate@binkert.orgvariant_dir = Dir('.').path 10421869SN/Adef variant(*path): 10435863Snate@binkert.org return os.path.join(variant_dir, *path) 10442667Sstever@eecs.umich.edudef variantd(*path): 10451869SN/A return variant(*path)+'/' 10461869SN/A 10472929Sktlim@umich.edu# Function to create a new build environment as clone of current 10482929Sktlim@umich.edu# environment 'env' with modified object suffix and optional stripped 10495863Snate@binkert.org# binary. Additional keyword arguments are appended to corresponding 10502929Sktlim@umich.edu# build environment vars. 1051955SN/Adef makeEnv(env, label, objsfx, strip = False, **kwargs): 10528120Sgblack@eecs.umich.edu # SCons doesn't know to append a library suffix when there is a '.' in the 10538120Sgblack@eecs.umich.edu # name. Use '_' instead. 10548120Sgblack@eecs.umich.edu libname = variant('gem5_' + label) 10558120Sgblack@eecs.umich.edu exename = variant('gem5.' + label) 10568120Sgblack@eecs.umich.edu secondary_exename = variant('m5.' + label) 10578120Sgblack@eecs.umich.edu 10588120Sgblack@eecs.umich.edu new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 10598120Sgblack@eecs.umich.edu new_env.Label = label 10608120Sgblack@eecs.umich.edu new_env.Append(**kwargs) 10618120Sgblack@eecs.umich.edu 10628120Sgblack@eecs.umich.edu swig_env = new_env.Clone() 10638120Sgblack@eecs.umich.edu 1064 # Both gcc and clang have issues with unused labels and values in 1065 # the SWIG generated code 1066 swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 1067 1068 if env['GCC']: 1069 # Depending on the SWIG version, we also need to supress 1070 # warnings about uninitialized variables and missing field 1071 # initializers. 1072 swig_env.Append(CCFLAGS=['-Wno-uninitialized', 1073 '-Wno-missing-field-initializers', 1074 '-Wno-unused-but-set-variable', 1075 '-Wno-maybe-uninitialized', 1076 '-Wno-type-limits']) 1077 1078 # Only gcc >= 4.9 supports UBSan, so check both the version 1079 # and the command-line option before adding the compiler and 1080 # linker flags. 1081 if GetOption('with_ubsan') and \ 1082 compareVersions(env['GCC_VERSION'], '4.9') >= 0: 1083 new_env.Append(CCFLAGS='-fsanitize=undefined') 1084 new_env.Append(LINKFLAGS='-fsanitize=undefined') 1085 1086 # The address sanitizer is available for gcc >= 4.8 1087 if GetOption('with_asan') and \ 1088 compareVersions(env['GCC_VERSION'], '4.8') >= 0: 1089 new_env.Append(CCFLAGS='-fsanitize=address') 1090 new_env.Append(LINKFLAGS='-fsanitize=address') 1091 1092 if env['CLANG']: 1093 swig_env.Append(CCFLAGS=['-Wno-sometimes-uninitialized', 1094 '-Wno-deprecated-register', 1095 '-Wno-tautological-compare']) 1096 1097 # We require clang >= 3.1, so there is no need to check any 1098 # versions here. 1099 if GetOption('with_ubsan'): 1100 new_env.Append(CCFLAGS='-fsanitize=undefined') 1101 new_env.Append(LINKFLAGS='-fsanitize=undefined') 1102 1103 if GetOption('with_asan'): 1104 new_env.Append(CCFLAGS='-fsanitize=address') 1105 new_env.Append(LINKFLAGS='-fsanitize=address') 1106 1107 werror_env = new_env.Clone() 1108 # Treat warnings as errors but white list some warnings that we 1109 # want to allow (e.g., deprecation warnings). 1110 werror_env.Append(CCFLAGS=['-Werror', 1111 '-Wno-error=deprecated-declarations', 1112 '-Wno-error=deprecated', 1113 ]) 1114 1115 def make_obj(source, static, extra_deps = None): 1116 '''This function adds the specified source to the correct 1117 build environment, and returns the corresponding SCons Object 1118 nodes''' 1119 1120 if source.swig: 1121 env = swig_env 1122 elif source.Werror: 1123 env = werror_env 1124 else: 1125 env = new_env 1126 1127 if static: 1128 obj = env.StaticObject(source.tnode) 1129 else: 1130 obj = env.SharedObject(source.tnode) 1131 1132 if extra_deps: 1133 env.Depends(obj, extra_deps) 1134 1135 return obj 1136 1137 lib_guards = {'main': False, 'skip_lib': False} 1138 1139 # Without Python, leave out all SWIG and Python content from the 1140 # library builds. The option doesn't affect gem5 built as a program 1141 if GetOption('without_python'): 1142 lib_guards['skip_no_python'] = False 1143 1144 static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] 1145 shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] 1146 1147 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 1148 static_objs.append(static_date) 1149 1150 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 1151 shared_objs.append(shared_date) 1152 1153 # First make a library of everything but main() so other programs can 1154 # link against m5. 1155 static_lib = new_env.StaticLibrary(libname, static_objs) 1156 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1157 1158 # Now link a stub with main() and the static library. 1159 main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 1160 1161 for test in UnitTest.all: 1162 flags = { test.target : True } 1163 test_sources = Source.get(**flags) 1164 test_objs = [ make_obj(s, static=True) for s in test_sources ] 1165 if test.main: 1166 test_objs += main_objs 1167 path = variant('unittest/%s.%s' % (test.target, label)) 1168 new_env.Program(path, test_objs + static_objs) 1169 1170 progname = exename 1171 if strip: 1172 progname += '.unstripped' 1173 1174 targets = new_env.Program(progname, main_objs + static_objs) 1175 1176 if strip: 1177 if sys.platform == 'sunos5': 1178 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1179 else: 1180 cmd = 'strip $SOURCE -o $TARGET' 1181 targets = new_env.Command(exename, progname, 1182 MakeAction(cmd, Transform("STRIP"))) 1183 1184 new_env.Command(secondary_exename, exename, 1185 MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 1186 1187 new_env.M5Binary = targets[0] 1188 return new_env 1189 1190# Start out with the compiler flags common to all compilers, 1191# i.e. they all use -g for opt and -g -pg for prof 1192ccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 1193 'perf' : ['-g']} 1194 1195# Start out with the linker flags common to all linkers, i.e. -pg for 1196# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 1197# no-as-needed and as-needed as the binutils linker is too clever and 1198# simply doesn't link to the library otherwise. 1199ldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 1200 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 1201 1202# For Link Time Optimization, the optimisation flags used to compile 1203# individual files are decoupled from those used at link time 1204# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 1205# to also update the linker flags based on the target. 1206if env['GCC']: 1207 if sys.platform == 'sunos5': 1208 ccflags['debug'] += ['-gstabs+'] 1209 else: 1210 ccflags['debug'] += ['-ggdb3'] 1211 ldflags['debug'] += ['-O0'] 1212 # opt, fast, prof and perf all share the same cc flags, also add 1213 # the optimization to the ldflags as LTO defers the optimization 1214 # to link time 1215 for target in ['opt', 'fast', 'prof', 'perf']: 1216 ccflags[target] += ['-O3'] 1217 ldflags[target] += ['-O3'] 1218 1219 ccflags['fast'] += env['LTO_CCFLAGS'] 1220 ldflags['fast'] += env['LTO_LDFLAGS'] 1221elif env['CLANG']: 1222 ccflags['debug'] += ['-g', '-O0'] 1223 # opt, fast, prof and perf all share the same cc flags 1224 for target in ['opt', 'fast', 'prof', 'perf']: 1225 ccflags[target] += ['-O3'] 1226else: 1227 print 'Unknown compiler, please fix compiler options' 1228 Exit(1) 1229 1230 1231# To speed things up, we only instantiate the build environments we 1232# need. We try to identify the needed environment for each target; if 1233# we can't, we fall back on instantiating all the environments just to 1234# be safe. 1235target_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 1236obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 1237 'gpo' : 'perf'} 1238 1239def identifyTarget(t): 1240 ext = t.split('.')[-1] 1241 if ext in target_types: 1242 return ext 1243 if obj2target.has_key(ext): 1244 return obj2target[ext] 1245 match = re.search(r'/tests/([^/]+)/', t) 1246 if match and match.group(1) in target_types: 1247 return match.group(1) 1248 return 'all' 1249 1250needed_envs = [identifyTarget(target) for target in BUILD_TARGETS] 1251if 'all' in needed_envs: 1252 needed_envs += target_types 1253 1254def makeEnvirons(target, source, env): 1255 # cause any later Source() calls to be fatal, as a diagnostic. 1256 Source.done() 1257 1258 envList = [] 1259 1260 # Debug binary 1261 if 'debug' in needed_envs: 1262 envList.append( 1263 makeEnv(env, 'debug', '.do', 1264 CCFLAGS = Split(ccflags['debug']), 1265 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 1266 LINKFLAGS = Split(ldflags['debug']))) 1267 1268 # Optimized binary 1269 if 'opt' in needed_envs: 1270 envList.append( 1271 makeEnv(env, 'opt', '.o', 1272 CCFLAGS = Split(ccflags['opt']), 1273 CPPDEFINES = ['TRACING_ON=1'], 1274 LINKFLAGS = Split(ldflags['opt']))) 1275 1276 # "Fast" binary 1277 if 'fast' in needed_envs: 1278 envList.append( 1279 makeEnv(env, 'fast', '.fo', strip = True, 1280 CCFLAGS = Split(ccflags['fast']), 1281 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1282 LINKFLAGS = Split(ldflags['fast']))) 1283 1284 # Profiled binary using gprof 1285 if 'prof' in needed_envs: 1286 envList.append( 1287 makeEnv(env, 'prof', '.po', 1288 CCFLAGS = Split(ccflags['prof']), 1289 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1290 LINKFLAGS = Split(ldflags['prof']))) 1291 1292 # Profiled binary using google-pprof 1293 if 'perf' in needed_envs: 1294 envList.append( 1295 makeEnv(env, 'perf', '.gpo', 1296 CCFLAGS = Split(ccflags['perf']), 1297 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1298 LINKFLAGS = Split(ldflags['perf']))) 1299 1300 # Set up the regression tests for each build. 1301 for e in envList: 1302 SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 1303 variant_dir = variantd('tests', e.Label), 1304 exports = { 'env' : e }, duplicate = False) 1305 1306# The MakeEnvirons Builder defers the full dependency collection until 1307# after processing the ISA definition (due to dynamically generated 1308# source files). Add this dependency to all targets so they will wait 1309# until the environments are completely set up. Otherwise, a second 1310# process (e.g. -j2 or higher) will try to compile the requested target, 1311# not know how, and fail. 1312env.Append(BUILDERS = {'MakeEnvirons' : 1313 Builder(action=MakeAction(makeEnvirons, 1314 Transform("ENVIRONS", 1)))}) 1315 1316isa_target = env['PHONY_BASE'] + '-deps' 1317environs = env['PHONY_BASE'] + '-environs' 1318env.Depends('#all-deps', isa_target) 1319env.Depends('#all-environs', environs) 1320env.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 1321envSetup = env.MakeEnvirons(environs, isa_target) 1322 1323# make sure no -deps targets occur before all ISAs are complete 1324env.Depends(isa_target, '#all-isas') 1325# likewise for -environs targets and all the -deps targets 1326env.Depends(environs, '#all-deps') 1327