SConscript revision 12063:06cd2c297b04
1955SN/A# -*- mode:python -*- 2955SN/A 39812Sandreas.hansson@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 subprocess 38955SN/Aimport sys 39955SN/Aimport zlib 40955SN/A 41955SN/Afrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 422665Ssaidi@eecs.umich.edu 432665Ssaidi@eecs.umich.eduimport SCons 445863Snate@binkert.org 45955SN/A# This file defines how to build a particular configuration of gem5 46955SN/A# based on variable settings in the 'env' build environment. 47955SN/A 48955SN/AImport('*') 49955SN/A 508878Ssteve.reinhardt@amd.com# Children need to see the environment 512632Sstever@eecs.umich.eduExport('env') 528878Ssteve.reinhardt@amd.com 532632Sstever@eecs.umich.edubuild_env = [(opt, env[opt]) for opt in export_vars] 54955SN/A 558878Ssteve.reinhardt@amd.comfrom m5.util import code_formatter, compareVersions 562632Sstever@eecs.umich.edu 572761Sstever@eecs.umich.edu######################################################################## 582632Sstever@eecs.umich.edu# Code for adding source files of various types 592632Sstever@eecs.umich.edu# 602632Sstever@eecs.umich.edu# When specifying a source file of some type, a set of guards can be 612761Sstever@eecs.umich.edu# specified for that file. When get() is used to find the files, if 622761Sstever@eecs.umich.edu# get specifies a set of filters, only files that match those filters 632761Sstever@eecs.umich.edu# will be accepted (unspecified filters on files are assumed to be 648878Ssteve.reinhardt@amd.com# false). Current filters are: 658878Ssteve.reinhardt@amd.com# main -- specifies the gem5 main() function 662761Sstever@eecs.umich.edu# skip_lib -- do not put this file into the gem5 library 672761Sstever@eecs.umich.edu# skip_no_python -- do not put this file into a no_python library 682761Sstever@eecs.umich.edu# as it embeds compiled Python 692761Sstever@eecs.umich.edu# <unittest> -- unit tests use filters based on the unit test name 702761Sstever@eecs.umich.edu# 718878Ssteve.reinhardt@amd.com# A parent can now be specified for a source file and default filter 728878Ssteve.reinhardt@amd.com# values will be retrieved recursively from parents (children override 732632Sstever@eecs.umich.edu# parents). 742632Sstever@eecs.umich.edu# 758878Ssteve.reinhardt@amd.comdef guarded_source_iterator(sources, **guards): 768878Ssteve.reinhardt@amd.com '''Iterate over a set of sources, gated by a set of guards.''' 772632Sstever@eecs.umich.edu for src in sources: 78955SN/A for flag,value in guards.iteritems(): 79955SN/A # if the flag is found and has a different value, skip 80955SN/A # this file 815863Snate@binkert.org if src.all_guards.get(flag, False) != value: 825863Snate@binkert.org break 835863Snate@binkert.org else: 845863Snate@binkert.org yield src 855863Snate@binkert.org 865863Snate@binkert.orgclass SourceMeta(type): 875863Snate@binkert.org '''Meta class for source files that keeps track of all files of a 885863Snate@binkert.org particular type and has a get function for finding all functions 895863Snate@binkert.org of a certain type that match a set of guards''' 905863Snate@binkert.org def __init__(cls, name, bases, dict): 915863Snate@binkert.org super(SourceMeta, cls).__init__(name, bases, dict) 928878Ssteve.reinhardt@amd.com cls.all = [] 935863Snate@binkert.org 945863Snate@binkert.org def get(cls, **guards): 955863Snate@binkert.org '''Find all files that match the specified guards. If a source 969812Sandreas.hansson@arm.com file does not specify a flag, the default is False''' 979812Sandreas.hansson@arm.com for s in guarded_source_iterator(cls.all, **guards): 985863Snate@binkert.org yield s 999812Sandreas.hansson@arm.com 1005863Snate@binkert.orgclass SourceFile(object): 1015863Snate@binkert.org '''Base object that encapsulates the notion of a source file. 1025863Snate@binkert.org This includes, the source node, target node, various manipulations 1039812Sandreas.hansson@arm.com of those. A source file also specifies a set of guards which 1049812Sandreas.hansson@arm.com describing which builds the source file applies to. A parent can 1055863Snate@binkert.org also be specified to get default guards from''' 1065863Snate@binkert.org __metaclass__ = SourceMeta 1078878Ssteve.reinhardt@amd.com def __init__(self, source, parent=None, **guards): 1085863Snate@binkert.org self.guards = guards 1095863Snate@binkert.org self.parent = parent 1105863Snate@binkert.org 1116654Snate@binkert.org tnode = source 11210196SCurtis.Dunham@arm.com if not isinstance(source, SCons.Node.FS.File): 113955SN/A tnode = File(source) 1145396Ssaidi@eecs.umich.edu 1155863Snate@binkert.org self.tnode = tnode 1165863Snate@binkert.org self.snode = tnode.srcnode() 1174202Sbinkertn@umich.edu 1185863Snate@binkert.org for base in type(self).__mro__: 1195863Snate@binkert.org if issubclass(base, SourceFile): 1205863Snate@binkert.org base.all.append(self) 1215863Snate@binkert.org 122955SN/A @property 1236654Snate@binkert.org def filename(self): 1245273Sstever@gmail.com return str(self.tnode) 1255871Snate@binkert.org 1265273Sstever@gmail.com @property 1276655Snate@binkert.org def dirname(self): 1288878Ssteve.reinhardt@amd.com return dirname(self.filename) 1296655Snate@binkert.org 1306655Snate@binkert.org @property 1319219Spower.jg@gmail.com def basename(self): 1326655Snate@binkert.org return basename(self.filename) 1335871Snate@binkert.org 1346654Snate@binkert.org @property 1358947Sandreas.hansson@arm.com def extname(self): 1365396Ssaidi@eecs.umich.edu index = self.basename.rfind('.') 1378120Sgblack@eecs.umich.edu if index <= 0: 1388120Sgblack@eecs.umich.edu # dot files aren't extensions 1398120Sgblack@eecs.umich.edu return self.basename, None 1408120Sgblack@eecs.umich.edu 1418120Sgblack@eecs.umich.edu return self.basename[:index], self.basename[index+1:] 1428120Sgblack@eecs.umich.edu 1438120Sgblack@eecs.umich.edu @property 1448120Sgblack@eecs.umich.edu def all_guards(self): 1458879Ssteve.reinhardt@amd.com '''find all guards for this object getting default values 1468879Ssteve.reinhardt@amd.com recursively from its parents''' 1478879Ssteve.reinhardt@amd.com guards = {} 1488879Ssteve.reinhardt@amd.com if self.parent: 1498879Ssteve.reinhardt@amd.com guards.update(self.parent.guards) 1508879Ssteve.reinhardt@amd.com guards.update(self.guards) 1518879Ssteve.reinhardt@amd.com return guards 1528879Ssteve.reinhardt@amd.com 1538879Ssteve.reinhardt@amd.com def __lt__(self, other): return self.filename < other.filename 1548879Ssteve.reinhardt@amd.com def __le__(self, other): return self.filename <= other.filename 1558879Ssteve.reinhardt@amd.com def __gt__(self, other): return self.filename > other.filename 1568879Ssteve.reinhardt@amd.com def __ge__(self, other): return self.filename >= other.filename 1578879Ssteve.reinhardt@amd.com def __eq__(self, other): return self.filename == other.filename 1588120Sgblack@eecs.umich.edu def __ne__(self, other): return self.filename != other.filename 1598120Sgblack@eecs.umich.edu 1608120Sgblack@eecs.umich.edu @staticmethod 1618120Sgblack@eecs.umich.edu def done(): 1628120Sgblack@eecs.umich.edu def disabled(cls, name, *ignored): 1638120Sgblack@eecs.umich.edu raise RuntimeError("Additional SourceFile '%s'" % name,\ 1648120Sgblack@eecs.umich.edu "declared, but targets deps are already fixed.") 1658120Sgblack@eecs.umich.edu SourceFile.__init__ = disabled 1668120Sgblack@eecs.umich.edu 1678120Sgblack@eecs.umich.edu 1688120Sgblack@eecs.umich.educlass Source(SourceFile): 1698120Sgblack@eecs.umich.edu current_group = None 1708120Sgblack@eecs.umich.edu source_groups = { None : [] } 1718120Sgblack@eecs.umich.edu 1728879Ssteve.reinhardt@amd.com @classmethod 1738879Ssteve.reinhardt@amd.com def set_group(cls, group): 1748879Ssteve.reinhardt@amd.com if not group in Source.source_groups: 1758879Ssteve.reinhardt@amd.com Source.source_groups[group] = [] 17610458Sandreas.hansson@arm.com Source.current_group = group 17710458Sandreas.hansson@arm.com 17810458Sandreas.hansson@arm.com '''Add a c/c++ source file to the build''' 1798879Ssteve.reinhardt@amd.com def __init__(self, source, Werror=True, **guards): 1808879Ssteve.reinhardt@amd.com '''specify the source file, and any guards''' 1818879Ssteve.reinhardt@amd.com super(Source, self).__init__(source, **guards) 1828879Ssteve.reinhardt@amd.com 1839227Sandreas.hansson@arm.com self.Werror = Werror 1849227Sandreas.hansson@arm.com 1858879Ssteve.reinhardt@amd.com Source.source_groups[Source.current_group].append(self) 1868879Ssteve.reinhardt@amd.com 1878879Ssteve.reinhardt@amd.comclass PySource(SourceFile): 1888879Ssteve.reinhardt@amd.com '''Add a python source file to the named package''' 18910453SAndrew.Bardsley@arm.com invalid_sym_char = re.compile('[^A-z0-9_]') 19010453SAndrew.Bardsley@arm.com modules = {} 19110453SAndrew.Bardsley@arm.com tnodes = {} 19210456SCurtis.Dunham@arm.com symnames = {} 19310456SCurtis.Dunham@arm.com 19410456SCurtis.Dunham@arm.com def __init__(self, package, source, **guards): 19510457Sandreas.hansson@arm.com '''specify the python package, the source file, and any guards''' 19610457Sandreas.hansson@arm.com super(PySource, self).__init__(source, **guards) 1978120Sgblack@eecs.umich.edu 1988947Sandreas.hansson@arm.com modname,ext = self.extname 1997816Ssteve.reinhardt@amd.com assert ext == 'py' 2005871Snate@binkert.org 2015871Snate@binkert.org if package: 2026121Snate@binkert.org path = package.split('.') 2035871Snate@binkert.org else: 2045871Snate@binkert.org path = [] 2059926Sstan.czerniawski@arm.com 2069926Sstan.czerniawski@arm.com modpath = path[:] 2079119Sandreas.hansson@arm.com if modname != '__init__': 20810068Sandreas.hansson@arm.com modpath += [ modname ] 20910068Sandreas.hansson@arm.com modpath = '.'.join(modpath) 210955SN/A 2119416SAndreas.Sandberg@ARM.com arcpath = path + [ self.basename ] 2129416SAndreas.Sandberg@ARM.com abspath = self.snode.abspath 2139416SAndreas.Sandberg@ARM.com if not exists(abspath): 2149416SAndreas.Sandberg@ARM.com abspath = self.tnode.abspath 2159416SAndreas.Sandberg@ARM.com 2169416SAndreas.Sandberg@ARM.com self.package = package 2179416SAndreas.Sandberg@ARM.com self.modname = modname 2185871Snate@binkert.org self.modpath = modpath 21910584Sandreas.hansson@arm.com self.arcname = joinpath(*arcpath) 2209416SAndreas.Sandberg@ARM.com self.abspath = abspath 2219416SAndreas.Sandberg@ARM.com self.compiled = File(self.filename + 'c') 2225871Snate@binkert.org self.cpp = File(self.filename + '.cc') 223955SN/A self.symname = PySource.invalid_sym_char.sub('_', modpath) 22410671Sandreas.hansson@arm.com 22510671Sandreas.hansson@arm.com PySource.modules[modpath] = self 22610671Sandreas.hansson@arm.com PySource.tnodes[self.tnode] = self 22710671Sandreas.hansson@arm.com PySource.symnames[self.symname] = self 2288881Smarc.orr@gmail.com 2296121Snate@binkert.orgclass SimObject(PySource): 2306121Snate@binkert.org '''Add a SimObject python file as a python source object and add 2311533SN/A it to a list of sim object modules''' 2329239Sandreas.hansson@arm.com 2339239Sandreas.hansson@arm.com fixed = False 2349239Sandreas.hansson@arm.com modnames = [] 2359239Sandreas.hansson@arm.com 2369239Sandreas.hansson@arm.com def __init__(self, source, **guards): 2379239Sandreas.hansson@arm.com '''Specify the source file and any guards (automatically in 2389239Sandreas.hansson@arm.com the m5.objects package)''' 2399239Sandreas.hansson@arm.com super(SimObject, self).__init__('m5.objects', source, **guards) 2409239Sandreas.hansson@arm.com if self.fixed: 2419239Sandreas.hansson@arm.com raise AttributeError, "Too late to call SimObject now." 2429239Sandreas.hansson@arm.com 2439239Sandreas.hansson@arm.com bisect.insort_right(SimObject.modnames, self.modname) 2446655Snate@binkert.org 2456655Snate@binkert.orgclass ProtoBuf(SourceFile): 2466655Snate@binkert.org '''Add a Protocol Buffer to build''' 2476655Snate@binkert.org 2485871Snate@binkert.org def __init__(self, source, **guards): 2495871Snate@binkert.org '''Specify the source file, and any guards''' 2505863Snate@binkert.org super(ProtoBuf, self).__init__(source, **guards) 2515871Snate@binkert.org 2528878Ssteve.reinhardt@amd.com # Get the file name and the extension 2535871Snate@binkert.org modname,ext = self.extname 2545871Snate@binkert.org assert ext == 'proto' 2555871Snate@binkert.org 2565863Snate@binkert.org # Currently, we stick to generating the C++ headers, so we 2576121Snate@binkert.org # only need to track the source and header. 2585863Snate@binkert.org self.cc_file = File(modname + '.pb.cc') 2595871Snate@binkert.org self.hh_file = File(modname + '.pb.h') 2608336Ssteve.reinhardt@amd.com 2618336Ssteve.reinhardt@amd.comclass UnitTest(object): 2628336Ssteve.reinhardt@amd.com '''Create a UnitTest''' 2638336Ssteve.reinhardt@amd.com 2644678Snate@binkert.org all = [] 2658336Ssteve.reinhardt@amd.com def __init__(self, target, *sources, **kwargs): 2668336Ssteve.reinhardt@amd.com '''Specify the target name and any sources. Sources that are 2678336Ssteve.reinhardt@amd.com not SourceFiles are evalued with Source(). All files are 2684678Snate@binkert.org guarded with a guard of the same name as the UnitTest 2694678Snate@binkert.org target.''' 2704678Snate@binkert.org 2714678Snate@binkert.org srcs = [] 2727827Snate@binkert.org for src in sources: 2737827Snate@binkert.org if not isinstance(src, SourceFile): 2748336Ssteve.reinhardt@amd.com src = Source(src, skip_lib=True) 2754678Snate@binkert.org src.guards[target] = True 2768336Ssteve.reinhardt@amd.com srcs.append(src) 2778336Ssteve.reinhardt@amd.com 2788336Ssteve.reinhardt@amd.com self.sources = srcs 2798336Ssteve.reinhardt@amd.com self.target = target 2808336Ssteve.reinhardt@amd.com self.main = kwargs.get('main', False) 2818336Ssteve.reinhardt@amd.com UnitTest.all.append(self) 2825871Snate@binkert.org 2835871Snate@binkert.org# Children should have access 2848336Ssteve.reinhardt@amd.comExport('Source') 2858336Ssteve.reinhardt@amd.comExport('PySource') 2868336Ssteve.reinhardt@amd.comExport('SimObject') 2878336Ssteve.reinhardt@amd.comExport('ProtoBuf') 2888336Ssteve.reinhardt@amd.comExport('UnitTest') 2895871Snate@binkert.org 2908336Ssteve.reinhardt@amd.com######################################################################## 2918336Ssteve.reinhardt@amd.com# 2928336Ssteve.reinhardt@amd.com# Debug Flags 2938336Ssteve.reinhardt@amd.com# 2948336Ssteve.reinhardt@amd.comdebug_flags = {} 2954678Snate@binkert.orgdef DebugFlag(name, desc=None): 2965871Snate@binkert.org if name in debug_flags: 2974678Snate@binkert.org raise AttributeError, "Flag %s already specified" % name 2988336Ssteve.reinhardt@amd.com debug_flags[name] = (name, (), desc) 2998336Ssteve.reinhardt@amd.com 3008336Ssteve.reinhardt@amd.comdef CompoundFlag(name, flags, desc=None): 3018336Ssteve.reinhardt@amd.com if name in debug_flags: 3028336Ssteve.reinhardt@amd.com raise AttributeError, "Flag %s already specified" % name 3038336Ssteve.reinhardt@amd.com 3048336Ssteve.reinhardt@amd.com compound = tuple(flags) 3058336Ssteve.reinhardt@amd.com debug_flags[name] = (name, compound, desc) 3068336Ssteve.reinhardt@amd.com 3078336Ssteve.reinhardt@amd.comExport('DebugFlag') 3088336Ssteve.reinhardt@amd.comExport('CompoundFlag') 3098336Ssteve.reinhardt@amd.com 3108336Ssteve.reinhardt@amd.com######################################################################## 3118336Ssteve.reinhardt@amd.com# 3128336Ssteve.reinhardt@amd.com# Set some compiler variables 3138336Ssteve.reinhardt@amd.com# 3148336Ssteve.reinhardt@amd.com 3155871Snate@binkert.org# Include file paths are rooted in this directory. SCons will 3166121Snate@binkert.org# automatically expand '.' to refer to both the source directory and 317955SN/A# the corresponding build directory to pick up generated include 318955SN/A# files. 3192632Sstever@eecs.umich.eduenv.Append(CPPPATH=Dir('.')) 3202632Sstever@eecs.umich.edu 321955SN/Afor extra_dir in extras_dir_list: 322955SN/A env.Append(CPPPATH=Dir(extra_dir)) 323955SN/A 324955SN/A# Workaround for bug in SCons version > 0.97d20071212 3258878Ssteve.reinhardt@amd.com# Scons bug id: 2006 gem5 Bug id: 308 326955SN/Afor root, dirs, files in os.walk(base_dir, topdown=True): 3272632Sstever@eecs.umich.edu Dir(root[len(base_dir) + 1:]) 3282632Sstever@eecs.umich.edu 3292632Sstever@eecs.umich.edu######################################################################## 3302632Sstever@eecs.umich.edu# 3312632Sstever@eecs.umich.edu# Walk the tree and execute all SConscripts in subdirectories 3322632Sstever@eecs.umich.edu# 3332632Sstever@eecs.umich.edu 3348268Ssteve.reinhardt@amd.comhere = Dir('.').srcnode().abspath 3358268Ssteve.reinhardt@amd.comfor root, dirs, files in os.walk(base_dir, topdown=True): 3368268Ssteve.reinhardt@amd.com if root == here: 3378268Ssteve.reinhardt@amd.com # we don't want to recurse back into this SConscript 3388268Ssteve.reinhardt@amd.com continue 3398268Ssteve.reinhardt@amd.com 3408268Ssteve.reinhardt@amd.com if 'SConscript' in files: 3412632Sstever@eecs.umich.edu build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 3422632Sstever@eecs.umich.edu Source.set_group(build_dir) 3432632Sstever@eecs.umich.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3442632Sstever@eecs.umich.edu 3458268Ssteve.reinhardt@amd.comfor extra_dir in extras_dir_list: 3462632Sstever@eecs.umich.edu prefix_len = len(dirname(extra_dir)) + 1 3478268Ssteve.reinhardt@amd.com 3488268Ssteve.reinhardt@amd.com # Also add the corresponding build directory to pick up generated 3498268Ssteve.reinhardt@amd.com # include files. 3508268Ssteve.reinhardt@amd.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 3513718Sstever@eecs.umich.edu 3522634Sstever@eecs.umich.edu for root, dirs, files in os.walk(extra_dir, topdown=True): 3532634Sstever@eecs.umich.edu # if build lives in the extras directory, don't walk down it 3545863Snate@binkert.org if 'build' in dirs: 3552638Sstever@eecs.umich.edu dirs.remove('build') 3568268Ssteve.reinhardt@amd.com 3572632Sstever@eecs.umich.edu if 'SConscript' in files: 3582632Sstever@eecs.umich.edu build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 3592632Sstever@eecs.umich.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3602632Sstever@eecs.umich.edu 3612632Sstever@eecs.umich.edufor opt in export_vars: 3621858SN/A env.ConfigFile(opt) 3633716Sstever@eecs.umich.edu 3642638Sstever@eecs.umich.edudef makeTheISA(source, target, env): 3652638Sstever@eecs.umich.edu isas = [ src.get_contents() for src in source ] 3662638Sstever@eecs.umich.edu target_isa = env['TARGET_ISA'] 3672638Sstever@eecs.umich.edu def define(isa): 3682638Sstever@eecs.umich.edu return isa.upper() + '_ISA' 3692638Sstever@eecs.umich.edu 3702638Sstever@eecs.umich.edu def namespace(isa): 3715863Snate@binkert.org return isa[0].upper() + isa[1:].lower() + 'ISA' 3725863Snate@binkert.org 3735863Snate@binkert.org 374955SN/A code = code_formatter() 3755341Sstever@gmail.com code('''\ 3765341Sstever@gmail.com#ifndef __CONFIG_THE_ISA_HH__ 3775863Snate@binkert.org#define __CONFIG_THE_ISA_HH__ 3787756SAli.Saidi@ARM.com 3795341Sstever@gmail.com''') 3806121Snate@binkert.org 3814494Ssaidi@eecs.umich.edu # create defines for the preprocessing and compile-time determination 3826121Snate@binkert.org for i,isa in enumerate(isas): 3831105SN/A code('#define $0 $1', define(isa), i + 1) 3842667Sstever@eecs.umich.edu code() 3852667Sstever@eecs.umich.edu 3862667Sstever@eecs.umich.edu # create an enum for any run-time determination of the ISA, we 3872667Sstever@eecs.umich.edu # reuse the same name as the namespaces 3886121Snate@binkert.org code('enum class Arch {') 3892667Sstever@eecs.umich.edu for i,isa in enumerate(isas): 3905341Sstever@gmail.com if i + 1 == len(isas): 3915863Snate@binkert.org code(' $0 = $1', namespace(isa), define(isa)) 3925341Sstever@gmail.com else: 3935341Sstever@gmail.com code(' $0 = $1,', namespace(isa), define(isa)) 3945341Sstever@gmail.com code('};') 3958120Sgblack@eecs.umich.edu 3965341Sstever@gmail.com code(''' 3978120Sgblack@eecs.umich.edu 3985341Sstever@gmail.com#define THE_ISA ${{define(target_isa)}} 3998120Sgblack@eecs.umich.edu#define TheISA ${{namespace(target_isa)}} 4006121Snate@binkert.org#define THE_ISA_STR "${{target_isa}}" 4016121Snate@binkert.org 4028980Ssteve.reinhardt@amd.com#endif // __CONFIG_THE_ISA_HH__''') 4039396Sandreas.hansson@arm.com 4045397Ssaidi@eecs.umich.edu code.write(str(target[0])) 4055397Ssaidi@eecs.umich.edu 4067727SAli.Saidi@ARM.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 4078268Ssteve.reinhardt@amd.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 4086168Snate@binkert.org 4095341Sstever@gmail.comdef makeTheGPUISA(source, target, env): 4108120Sgblack@eecs.umich.edu isas = [ src.get_contents() for src in source ] 4118120Sgblack@eecs.umich.edu target_gpu_isa = env['TARGET_GPU_ISA'] 4128120Sgblack@eecs.umich.edu def define(isa): 4136814Sgblack@eecs.umich.edu return isa.upper() + '_ISA' 4145863Snate@binkert.org 4158120Sgblack@eecs.umich.edu def namespace(isa): 4165341Sstever@gmail.com return isa[0].upper() + isa[1:].lower() + 'ISA' 4175863Snate@binkert.org 4188268Ssteve.reinhardt@amd.com 4196121Snate@binkert.org code = code_formatter() 4206121Snate@binkert.org code('''\ 4218268Ssteve.reinhardt@amd.com#ifndef __CONFIG_THE_GPU_ISA_HH__ 4225742Snate@binkert.org#define __CONFIG_THE_GPU_ISA_HH__ 4235742Snate@binkert.org 4245341Sstever@gmail.com''') 4255742Snate@binkert.org 4265742Snate@binkert.org # create defines for the preprocessing and compile-time determination 4275341Sstever@gmail.com for i,isa in enumerate(isas): 4286017Snate@binkert.org code('#define $0 $1', define(isa), i + 1) 4296121Snate@binkert.org code() 4306017Snate@binkert.org 4317816Ssteve.reinhardt@amd.com # create an enum for any run-time determination of the ISA, we 4327756SAli.Saidi@ARM.com # reuse the same name as the namespaces 4337756SAli.Saidi@ARM.com code('enum class GPUArch {') 4347756SAli.Saidi@ARM.com for i,isa in enumerate(isas): 4357756SAli.Saidi@ARM.com if i + 1 == len(isas): 4367756SAli.Saidi@ARM.com code(' $0 = $1', namespace(isa), define(isa)) 4377756SAli.Saidi@ARM.com else: 4387756SAli.Saidi@ARM.com code(' $0 = $1,', namespace(isa), define(isa)) 4397756SAli.Saidi@ARM.com code('};') 4407816Ssteve.reinhardt@amd.com 4417816Ssteve.reinhardt@amd.com code(''' 4427816Ssteve.reinhardt@amd.com 4437816Ssteve.reinhardt@amd.com#define THE_GPU_ISA ${{define(target_gpu_isa)}} 4447816Ssteve.reinhardt@amd.com#define TheGpuISA ${{namespace(target_gpu_isa)}} 4457816Ssteve.reinhardt@amd.com#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 4467816Ssteve.reinhardt@amd.com 4477816Ssteve.reinhardt@amd.com#endif // __CONFIG_THE_GPU_ISA_HH__''') 4487816Ssteve.reinhardt@amd.com 4497816Ssteve.reinhardt@amd.com code.write(str(target[0])) 4507756SAli.Saidi@ARM.com 4517816Ssteve.reinhardt@amd.comenv.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 4527816Ssteve.reinhardt@amd.com MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 4537816Ssteve.reinhardt@amd.com 4547816Ssteve.reinhardt@amd.com######################################################################## 4557816Ssteve.reinhardt@amd.com# 4567816Ssteve.reinhardt@amd.com# Prevent any SimObjects from being added after this point, they 4577816Ssteve.reinhardt@amd.com# should all have been added in the SConscripts above 4587816Ssteve.reinhardt@amd.com# 4597816Ssteve.reinhardt@amd.comSimObject.fixed = True 4607816Ssteve.reinhardt@amd.com 4617816Ssteve.reinhardt@amd.comclass DictImporter(object): 4627816Ssteve.reinhardt@amd.com '''This importer takes a dictionary of arbitrary module names that 4637816Ssteve.reinhardt@amd.com map to arbitrary filenames.''' 4647816Ssteve.reinhardt@amd.com def __init__(self, modules): 4657816Ssteve.reinhardt@amd.com self.modules = modules 4667816Ssteve.reinhardt@amd.com self.installed = set() 4677816Ssteve.reinhardt@amd.com 4687816Ssteve.reinhardt@amd.com def __del__(self): 4697816Ssteve.reinhardt@amd.com self.unload() 4707816Ssteve.reinhardt@amd.com 4717816Ssteve.reinhardt@amd.com def unload(self): 4727816Ssteve.reinhardt@amd.com import sys 4737816Ssteve.reinhardt@amd.com for module in self.installed: 4747816Ssteve.reinhardt@amd.com del sys.modules[module] 4757816Ssteve.reinhardt@amd.com self.installed = set() 4767816Ssteve.reinhardt@amd.com 4777816Ssteve.reinhardt@amd.com def find_module(self, fullname, path): 4787816Ssteve.reinhardt@amd.com if fullname == 'm5.defines': 4797816Ssteve.reinhardt@amd.com return self 4807816Ssteve.reinhardt@amd.com 4817816Ssteve.reinhardt@amd.com if fullname == 'm5.objects': 4827816Ssteve.reinhardt@amd.com return self 4837816Ssteve.reinhardt@amd.com 4847816Ssteve.reinhardt@amd.com if fullname.startswith('_m5'): 4857816Ssteve.reinhardt@amd.com return None 4867816Ssteve.reinhardt@amd.com 4877816Ssteve.reinhardt@amd.com source = self.modules.get(fullname, None) 4887816Ssteve.reinhardt@amd.com if source is not None and fullname.startswith('m5.objects'): 4897816Ssteve.reinhardt@amd.com return self 4907816Ssteve.reinhardt@amd.com 4917816Ssteve.reinhardt@amd.com return None 4927816Ssteve.reinhardt@amd.com 4937816Ssteve.reinhardt@amd.com def load_module(self, fullname): 4947816Ssteve.reinhardt@amd.com mod = imp.new_module(fullname) 4957816Ssteve.reinhardt@amd.com sys.modules[fullname] = mod 4967816Ssteve.reinhardt@amd.com self.installed.add(fullname) 4977816Ssteve.reinhardt@amd.com 4987816Ssteve.reinhardt@amd.com mod.__loader__ = self 4997816Ssteve.reinhardt@amd.com if fullname == 'm5.objects': 5007816Ssteve.reinhardt@amd.com mod.__path__ = fullname.split('.') 5017816Ssteve.reinhardt@amd.com return mod 5027816Ssteve.reinhardt@amd.com 5037816Ssteve.reinhardt@amd.com if fullname == 'm5.defines': 5047816Ssteve.reinhardt@amd.com mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 5057816Ssteve.reinhardt@amd.com return mod 5067816Ssteve.reinhardt@amd.com 5077816Ssteve.reinhardt@amd.com source = self.modules[fullname] 5087816Ssteve.reinhardt@amd.com if source.modname == '__init__': 5097816Ssteve.reinhardt@amd.com mod.__path__ = source.modpath 5107816Ssteve.reinhardt@amd.com mod.__file__ = source.abspath 5117816Ssteve.reinhardt@amd.com 5128947Sandreas.hansson@arm.com exec file(source.abspath, 'r') in mod.__dict__ 5138947Sandreas.hansson@arm.com 5147756SAli.Saidi@ARM.com return mod 5158120Sgblack@eecs.umich.edu 5167756SAli.Saidi@ARM.comimport m5.SimObject 5177756SAli.Saidi@ARM.comimport m5.params 5187756SAli.Saidi@ARM.comfrom m5.util import code_formatter 5197756SAli.Saidi@ARM.com 5207816Ssteve.reinhardt@amd.comm5.SimObject.clear() 5217816Ssteve.reinhardt@amd.comm5.params.clear() 5227816Ssteve.reinhardt@amd.com 5237816Ssteve.reinhardt@amd.com# install the python importer so we can grab stuff from the source 5247816Ssteve.reinhardt@amd.com# tree itself. We can't have SimObjects added after this point or 5257816Ssteve.reinhardt@amd.com# else we won't know about them for the rest of the stuff. 5267816Ssteve.reinhardt@amd.comimporter = DictImporter(PySource.modules) 5277816Ssteve.reinhardt@amd.comsys.meta_path[0:0] = [ importer ] 5287816Ssteve.reinhardt@amd.com 5297816Ssteve.reinhardt@amd.com# import all sim objects so we can populate the all_objects list 5307756SAli.Saidi@ARM.com# make sure that we're working with a list, then let's sort it 5317756SAli.Saidi@ARM.comfor modname in SimObject.modnames: 5329227Sandreas.hansson@arm.com exec('from m5.objects import %s' % modname) 5339227Sandreas.hansson@arm.com 5349227Sandreas.hansson@arm.com# we need to unload all of the currently imported modules so that they 5359227Sandreas.hansson@arm.com# will be re-imported the next time the sconscript is run 5369590Sandreas@sandberg.pp.seimporter.unload() 5379590Sandreas@sandberg.pp.sesys.meta_path.remove(importer) 5389590Sandreas@sandberg.pp.se 5399590Sandreas@sandberg.pp.sesim_objects = m5.SimObject.allClasses 5409590Sandreas@sandberg.pp.seall_enums = m5.params.allEnums 5419590Sandreas@sandberg.pp.se 5426654Snate@binkert.orgfor name,obj in sorted(sim_objects.iteritems()): 5436654Snate@binkert.org for param in obj._params.local.values(): 5445871Snate@binkert.org # load the ptype attribute now because it depends on the 5456121Snate@binkert.org # current version of SimObject.allClasses, but when scons 5468946Sandreas.hansson@arm.com # actually uses the value, all versions of 5479419Sandreas.hansson@arm.com # SimObject.allClasses will have been loaded 5483940Ssaidi@eecs.umich.edu param.ptype 5493918Ssaidi@eecs.umich.edu 5503918Ssaidi@eecs.umich.edu######################################################################## 5511858SN/A# 5529556Sandreas.hansson@arm.com# calculate extra dependencies 5539556Sandreas.hansson@arm.com# 5549556Sandreas.hansson@arm.commodule_depends = ["m5", "m5.SimObject", "m5.params"] 5559556Sandreas.hansson@arm.comdepends = [ PySource.modules[dep].snode for dep in module_depends ] 5569556Sandreas.hansson@arm.comdepends.sort(key = lambda x: x.name) 5579556Sandreas.hansson@arm.com 5589556Sandreas.hansson@arm.com######################################################################## 5599556Sandreas.hansson@arm.com# 5609556Sandreas.hansson@arm.com# Commands for the basic automatically generated python files 5619556Sandreas.hansson@arm.com# 5629556Sandreas.hansson@arm.com 5639556Sandreas.hansson@arm.com# Generate Python file containing a dict specifying the current 5649556Sandreas.hansson@arm.com# buildEnv flags. 5659556Sandreas.hansson@arm.comdef makeDefinesPyFile(target, source, env): 5669556Sandreas.hansson@arm.com build_env = source[0].get_contents() 5679556Sandreas.hansson@arm.com 5689556Sandreas.hansson@arm.com code = code_formatter() 5699556Sandreas.hansson@arm.com code(""" 5709556Sandreas.hansson@arm.comimport _m5.core 5719556Sandreas.hansson@arm.comimport m5.util 5729556Sandreas.hansson@arm.com 5739556Sandreas.hansson@arm.combuildEnv = m5.util.SmartDict($build_env) 5749556Sandreas.hansson@arm.com 5759556Sandreas.hansson@arm.comcompileDate = _m5.core.compileDate 5769556Sandreas.hansson@arm.com_globals = globals() 5779556Sandreas.hansson@arm.comfor key,val in _m5.core.__dict__.iteritems(): 5789556Sandreas.hansson@arm.com if key.startswith('flag_'): 5799556Sandreas.hansson@arm.com flag = key[5:] 5809556Sandreas.hansson@arm.com _globals[flag] = val 5819556Sandreas.hansson@arm.comdel _globals 5829556Sandreas.hansson@arm.com""") 5839556Sandreas.hansson@arm.com code.write(target[0].abspath) 5846121Snate@binkert.org 58510238Sandreas.hansson@arm.comdefines_info = Value(build_env) 58610238Sandreas.hansson@arm.com# Generate a file with all of the compile options in it 58710238Sandreas.hansson@arm.comenv.Command('python/m5/defines.py', defines_info, 58810238Sandreas.hansson@arm.com MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 5899420Sandreas.hansson@arm.comPySource('m5', 'python/m5/defines.py') 59010238Sandreas.hansson@arm.com 59110238Sandreas.hansson@arm.com# Generate python file containing info about the M5 source code 5929420Sandreas.hansson@arm.comdef makeInfoPyFile(target, source, env): 5939420Sandreas.hansson@arm.com code = code_formatter() 5949420Sandreas.hansson@arm.com for src in source: 5959420Sandreas.hansson@arm.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 5969420Sandreas.hansson@arm.com code('$src = ${{repr(data)}}') 59710264Sandreas.hansson@arm.com code.write(str(target[0])) 59810264Sandreas.hansson@arm.com 59910264Sandreas.hansson@arm.com# Generate a file that wraps the basic top level files 60010264Sandreas.hansson@arm.comenv.Command('python/m5/info.py', 60110264Sandreas.hansson@arm.com [ '#/COPYING', '#/LICENSE', '#/README', ], 60210264Sandreas.hansson@arm.com MakeAction(makeInfoPyFile, Transform("INFO"))) 60310264Sandreas.hansson@arm.comPySource('m5', 'python/m5/info.py') 60410264Sandreas.hansson@arm.com 60510264Sandreas.hansson@arm.com######################################################################## 60610264Sandreas.hansson@arm.com# 60710264Sandreas.hansson@arm.com# Create all of the SimObject param headers and enum headers 60810264Sandreas.hansson@arm.com# 60910264Sandreas.hansson@arm.com 61010264Sandreas.hansson@arm.comdef createSimObjectParamStruct(target, source, env): 61110264Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 61210264Sandreas.hansson@arm.com 61310457Sandreas.hansson@arm.com name = source[0].get_text_contents() 61410457Sandreas.hansson@arm.com obj = sim_objects[name] 61510457Sandreas.hansson@arm.com 61610457Sandreas.hansson@arm.com code = code_formatter() 61710457Sandreas.hansson@arm.com obj.cxx_param_decl(code) 61810457Sandreas.hansson@arm.com code.write(target[0].abspath) 61910457Sandreas.hansson@arm.com 62010457Sandreas.hansson@arm.comdef createSimObjectCxxConfig(is_header): 62110457Sandreas.hansson@arm.com def body(target, source, env): 62210238Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 62310238Sandreas.hansson@arm.com 62410238Sandreas.hansson@arm.com name = str(source[0].get_contents()) 62510238Sandreas.hansson@arm.com obj = sim_objects[name] 62610238Sandreas.hansson@arm.com 62710238Sandreas.hansson@arm.com code = code_formatter() 62810416Sandreas.hansson@arm.com obj.cxx_config_param_file(code, is_header) 62910238Sandreas.hansson@arm.com code.write(target[0].abspath) 6309227Sandreas.hansson@arm.com return body 63110238Sandreas.hansson@arm.com 63210416Sandreas.hansson@arm.comdef createEnumStrings(target, source, env): 63310416Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 2 6349227Sandreas.hansson@arm.com 6359590Sandreas@sandberg.pp.se name = source[0].get_text_contents() 6369590Sandreas@sandberg.pp.se use_python = source[1].read() 6379590Sandreas@sandberg.pp.se obj = all_enums[name] 6388737Skoansin.tan@gmail.com 63910238Sandreas.hansson@arm.com code = code_formatter() 64010238Sandreas.hansson@arm.com obj.cxx_def(code) 6419420Sandreas.hansson@arm.com if use_python: 6428737Skoansin.tan@gmail.com obj.pybind_def(code) 64310106SMitch.Hayenga@arm.com code.write(target[0].abspath) 6448737Skoansin.tan@gmail.com 6458737Skoansin.tan@gmail.comdef createEnumDecls(target, source, env): 64610238Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 64710238Sandreas.hansson@arm.com 6488737Skoansin.tan@gmail.com name = source[0].get_text_contents() 6498737Skoansin.tan@gmail.com obj = all_enums[name] 6508737Skoansin.tan@gmail.com 6518737Skoansin.tan@gmail.com code = code_formatter() 6528737Skoansin.tan@gmail.com obj.cxx_decl(code) 6538737Skoansin.tan@gmail.com code.write(target[0].abspath) 6549556Sandreas.hansson@arm.com 6559556Sandreas.hansson@arm.comdef createSimObjectPyBindWrapper(target, source, env): 6569556Sandreas.hansson@arm.com name = source[0].get_text_contents() 6579556Sandreas.hansson@arm.com obj = sim_objects[name] 6589556Sandreas.hansson@arm.com 6599556Sandreas.hansson@arm.com code = code_formatter() 6609556Sandreas.hansson@arm.com obj.pybind_decl(code) 6619556Sandreas.hansson@arm.com code.write(target[0].abspath) 66210278SAndreas.Sandberg@ARM.com 66310278SAndreas.Sandberg@ARM.com# Generate all of the SimObject param C++ struct header files 66410278SAndreas.Sandberg@ARM.comparams_hh_files = [] 66510278SAndreas.Sandberg@ARM.comfor name,simobj in sorted(sim_objects.iteritems()): 66610278SAndreas.Sandberg@ARM.com py_source = PySource.modules[simobj.__module__] 66710278SAndreas.Sandberg@ARM.com extra_deps = [ py_source.tnode ] 6689556Sandreas.hansson@arm.com 6699590Sandreas@sandberg.pp.se hh_file = File('params/%s.hh' % name) 6709590Sandreas@sandberg.pp.se params_hh_files.append(hh_file) 6719420Sandreas.hansson@arm.com env.Command(hh_file, Value(name), 6729846Sandreas.hansson@arm.com MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 6739846Sandreas.hansson@arm.com env.Depends(hh_file, depends + extra_deps) 6749846Sandreas.hansson@arm.com 6759846Sandreas.hansson@arm.com# C++ parameter description files 6768946Sandreas.hansson@arm.comif GetOption('with_cxx_config'): 6773918Ssaidi@eecs.umich.edu for name,simobj in sorted(sim_objects.iteritems()): 6789068SAli.Saidi@ARM.com py_source = PySource.modules[simobj.__module__] 6799068SAli.Saidi@ARM.com extra_deps = [ py_source.tnode ] 6809068SAli.Saidi@ARM.com 6819068SAli.Saidi@ARM.com cxx_config_hh_file = File('cxx_config/%s.hh' % name) 6829068SAli.Saidi@ARM.com cxx_config_cc_file = File('cxx_config/%s.cc' % name) 6839068SAli.Saidi@ARM.com env.Command(cxx_config_hh_file, Value(name), 6849068SAli.Saidi@ARM.com MakeAction(createSimObjectCxxConfig(True), 6859068SAli.Saidi@ARM.com Transform("CXXCPRHH"))) 6869068SAli.Saidi@ARM.com env.Command(cxx_config_cc_file, Value(name), 6879419Sandreas.hansson@arm.com MakeAction(createSimObjectCxxConfig(False), 6889068SAli.Saidi@ARM.com Transform("CXXCPRCC"))) 6899068SAli.Saidi@ARM.com env.Depends(cxx_config_hh_file, depends + extra_deps + 6909068SAli.Saidi@ARM.com [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 6919068SAli.Saidi@ARM.com env.Depends(cxx_config_cc_file, depends + extra_deps + 6929068SAli.Saidi@ARM.com [cxx_config_hh_file]) 6939068SAli.Saidi@ARM.com Source(cxx_config_cc_file) 6943918Ssaidi@eecs.umich.edu 6953918Ssaidi@eecs.umich.edu cxx_config_init_cc_file = File('cxx_config/init.cc') 6966157Snate@binkert.org 6976157Snate@binkert.org def createCxxConfigInitCC(target, source, env): 6986157Snate@binkert.org assert len(target) == 1 and len(source) == 1 6996157Snate@binkert.org 7005397Ssaidi@eecs.umich.edu code = code_formatter() 7015397Ssaidi@eecs.umich.edu 7026121Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 7036121Snate@binkert.org if not hasattr(simobj, 'abstract') or not simobj.abstract: 7046121Snate@binkert.org code('#include "cxx_config/${name}.hh"') 7056121Snate@binkert.org code() 7066121Snate@binkert.org code('void cxxConfigInit()') 7076121Snate@binkert.org code('{') 7085397Ssaidi@eecs.umich.edu code.indent() 7091851SN/A for name,simobj in sorted(sim_objects.iteritems()): 7101851SN/A not_abstract = not hasattr(simobj, 'abstract') or \ 7117739Sgblack@eecs.umich.edu not simobj.abstract 712955SN/A if not_abstract and 'type' in simobj.__dict__: 7139396Sandreas.hansson@arm.com code('cxx_config_directory["${name}"] = ' 7149396Sandreas.hansson@arm.com '${name}CxxConfigParams::makeDirectoryEntry();') 7159396Sandreas.hansson@arm.com code.dedent() 7169396Sandreas.hansson@arm.com code('}') 7179396Sandreas.hansson@arm.com code.write(target[0].abspath) 7189396Sandreas.hansson@arm.com 7199396Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 7209396Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 7219396Sandreas.hansson@arm.com env.Command(cxx_config_init_cc_file, Value(name), 7229396Sandreas.hansson@arm.com MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 7239396Sandreas.hansson@arm.com cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 7249396Sandreas.hansson@arm.com for name,simobj in sorted(sim_objects.iteritems()) 7259396Sandreas.hansson@arm.com if not hasattr(simobj, 'abstract') or not simobj.abstract] 7269396Sandreas.hansson@arm.com Depends(cxx_config_init_cc_file, cxx_param_hh_files + 7279396Sandreas.hansson@arm.com [File('sim/cxx_config.hh')]) 7289396Sandreas.hansson@arm.com Source(cxx_config_init_cc_file) 7299477Sandreas.hansson@arm.com 7309477Sandreas.hansson@arm.com# Generate all enum header files 7319477Sandreas.hansson@arm.comfor name,enum in sorted(all_enums.iteritems()): 7329477Sandreas.hansson@arm.com py_source = PySource.modules[enum.__module__] 7339477Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 7349477Sandreas.hansson@arm.com 7359477Sandreas.hansson@arm.com cc_file = File('enums/%s.cc' % name) 7369477Sandreas.hansson@arm.com env.Command(cc_file, [Value(name), Value(env['USE_PYTHON'])], 7379477Sandreas.hansson@arm.com MakeAction(createEnumStrings, Transform("ENUM STR"))) 7389477Sandreas.hansson@arm.com env.Depends(cc_file, depends + extra_deps) 7399477Sandreas.hansson@arm.com Source(cc_file) 7409477Sandreas.hansson@arm.com 7419477Sandreas.hansson@arm.com hh_file = File('enums/%s.hh' % name) 7429477Sandreas.hansson@arm.com env.Command(hh_file, Value(name), 7439477Sandreas.hansson@arm.com MakeAction(createEnumDecls, Transform("ENUMDECL"))) 7449477Sandreas.hansson@arm.com env.Depends(hh_file, depends + extra_deps) 7459477Sandreas.hansson@arm.com 7469477Sandreas.hansson@arm.com# Generate SimObject Python bindings wrapper files 7479477Sandreas.hansson@arm.comif env['USE_PYTHON']: 7489477Sandreas.hansson@arm.com for name,simobj in sorted(sim_objects.iteritems()): 7499477Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 7509477Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 7519396Sandreas.hansson@arm.com cc_file = File('python/_m5/param_%s.cc' % name) 7523053Sstever@eecs.umich.edu env.Command(cc_file, Value(name), 7536121Snate@binkert.org MakeAction(createSimObjectPyBindWrapper, 7543053Sstever@eecs.umich.edu Transform("SO PyBind"))) 7553053Sstever@eecs.umich.edu env.Depends(cc_file, depends + extra_deps) 7563053Sstever@eecs.umich.edu Source(cc_file) 7573053Sstever@eecs.umich.edu 7583053Sstever@eecs.umich.edu# Build all protocol buffers if we have got protoc and protobuf available 7599072Sandreas.hansson@arm.comif env['HAVE_PROTOBUF']: 7603053Sstever@eecs.umich.edu for proto in ProtoBuf.all: 7614742Sstever@eecs.umich.edu # Use both the source and header as the target, and the .proto 7624742Sstever@eecs.umich.edu # file as the source. When executing the protoc compiler, also 7633053Sstever@eecs.umich.edu # specify the proto_path to avoid having the generated files 7643053Sstever@eecs.umich.edu # include the path. 7653053Sstever@eecs.umich.edu env.Command([proto.cc_file, proto.hh_file], proto.tnode, 76610181SCurtis.Dunham@arm.com MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 7676654Snate@binkert.org '--proto_path ${SOURCE.dir} $SOURCE', 7683053Sstever@eecs.umich.edu Transform("PROTOC"))) 7693053Sstever@eecs.umich.edu 7703053Sstever@eecs.umich.edu # Add the C++ source file 7713053Sstever@eecs.umich.edu Source(proto.cc_file, **proto.guards) 77210425Sandreas.hansson@arm.comelif ProtoBuf.all: 77310425Sandreas.hansson@arm.com print 'Got protobuf to build, but lacks support!' 77410425Sandreas.hansson@arm.com Exit(1) 77510425Sandreas.hansson@arm.com 77610425Sandreas.hansson@arm.com# 77710425Sandreas.hansson@arm.com# Handle debug flags 77810425Sandreas.hansson@arm.com# 77910425Sandreas.hansson@arm.comdef makeDebugFlagCC(target, source, env): 78010425Sandreas.hansson@arm.com assert(len(target) == 1 and len(source) == 1) 78110425Sandreas.hansson@arm.com 78210425Sandreas.hansson@arm.com code = code_formatter() 7832667Sstever@eecs.umich.edu 7844554Sbinkertn@umich.edu # delay definition of CompoundFlags until after all the definition 7856121Snate@binkert.org # of all constituent SimpleFlags 7862667Sstever@eecs.umich.edu comp_code = code_formatter() 78710384SCurtis.Dunham@arm.com 78810384SCurtis.Dunham@arm.com # file header 78910384SCurtis.Dunham@arm.com code(''' 79010384SCurtis.Dunham@arm.com/* 79110384SCurtis.Dunham@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 7924554Sbinkertn@umich.edu */ 7934554Sbinkertn@umich.edu 7944554Sbinkertn@umich.edu#include "base/debug.hh" 7956121Snate@binkert.org 7964554Sbinkertn@umich.edunamespace Debug { 7974554Sbinkertn@umich.edu 7984554Sbinkertn@umich.edu''') 7994781Snate@binkert.org 8004554Sbinkertn@umich.edu for name, flag in sorted(source[0].read().iteritems()): 8014554Sbinkertn@umich.edu n, compound, desc = flag 8022667Sstever@eecs.umich.edu assert n == name 8034554Sbinkertn@umich.edu 8044554Sbinkertn@umich.edu if not compound: 8054554Sbinkertn@umich.edu code('SimpleFlag $name("$name", "$desc");') 8064554Sbinkertn@umich.edu else: 8072667Sstever@eecs.umich.edu comp_code('CompoundFlag $name("$name", "$desc",') 8084554Sbinkertn@umich.edu comp_code.indent() 8092667Sstever@eecs.umich.edu last = len(compound) - 1 8104554Sbinkertn@umich.edu for i,flag in enumerate(compound): 8116121Snate@binkert.org if i != last: 8122667Sstever@eecs.umich.edu comp_code('&$flag,') 8135522Snate@binkert.org else: 8145522Snate@binkert.org comp_code('&$flag);') 8155522Snate@binkert.org comp_code.dedent() 8165522Snate@binkert.org 8175522Snate@binkert.org code.append(comp_code) 8185522Snate@binkert.org code() 8195522Snate@binkert.org code('} // namespace Debug') 8205522Snate@binkert.org 8215522Snate@binkert.org code.write(str(target[0])) 8225522Snate@binkert.org 8235522Snate@binkert.orgdef makeDebugFlagHH(target, source, env): 8245522Snate@binkert.org assert(len(target) == 1 and len(source) == 1) 8255522Snate@binkert.org 8265522Snate@binkert.org val = eval(source[0].get_contents()) 8275522Snate@binkert.org name, compound, desc = val 8285522Snate@binkert.org 8295522Snate@binkert.org code = code_formatter() 8305522Snate@binkert.org 8315522Snate@binkert.org # file header boilerplate 8325522Snate@binkert.org code('''\ 8335522Snate@binkert.org/* 8345522Snate@binkert.org * DO NOT EDIT THIS FILE! Automatically generated by SCons. 8355522Snate@binkert.org */ 8365522Snate@binkert.org 8375522Snate@binkert.org#ifndef __DEBUG_${name}_HH__ 8385522Snate@binkert.org#define __DEBUG_${name}_HH__ 8399986Sandreas@sandberg.pp.se 8409986Sandreas@sandberg.pp.senamespace Debug { 8419986Sandreas@sandberg.pp.se''') 8429986Sandreas@sandberg.pp.se 8439986Sandreas@sandberg.pp.se if compound: 8449986Sandreas@sandberg.pp.se code('class CompoundFlag;') 8459986Sandreas@sandberg.pp.se code('class SimpleFlag;') 8469986Sandreas@sandberg.pp.se 8479986Sandreas@sandberg.pp.se if compound: 8489986Sandreas@sandberg.pp.se code('extern CompoundFlag $name;') 8499986Sandreas@sandberg.pp.se for flag in compound: 8509986Sandreas@sandberg.pp.se code('extern SimpleFlag $flag;') 8519986Sandreas@sandberg.pp.se else: 8529986Sandreas@sandberg.pp.se code('extern SimpleFlag $name;') 8539986Sandreas@sandberg.pp.se 8549986Sandreas@sandberg.pp.se code(''' 8559986Sandreas@sandberg.pp.se} 8569986Sandreas@sandberg.pp.se 8579986Sandreas@sandberg.pp.se#endif // __DEBUG_${name}_HH__ 8589986Sandreas@sandberg.pp.se''') 8592638Sstever@eecs.umich.edu 8602638Sstever@eecs.umich.edu code.write(str(target[0])) 8616121Snate@binkert.org 8623716Sstever@eecs.umich.edufor name,flag in sorted(debug_flags.iteritems()): 8635522Snate@binkert.org n, compound, desc = flag 8649986Sandreas@sandberg.pp.se assert n == name 8659986Sandreas@sandberg.pp.se 8669986Sandreas@sandberg.pp.se hh_file = 'debug/%s.hh' % name 8679986Sandreas@sandberg.pp.se env.Command(hh_file, Value(flag), 8685522Snate@binkert.org MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 8695522Snate@binkert.org 8705522Snate@binkert.orgenv.Command('debug/flags.cc', Value(debug_flags), 8715522Snate@binkert.org MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 8721858SN/ASource('debug/flags.cc') 8735227Ssaidi@eecs.umich.edu 8745227Ssaidi@eecs.umich.edu# version tags 8755227Ssaidi@eecs.umich.edutags = \ 8765227Ssaidi@eecs.umich.eduenv.Command('sim/tags.cc', None, 8776654Snate@binkert.org MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 8786654Snate@binkert.org Transform("VER TAGS"))) 8797769SAli.Saidi@ARM.comenv.AlwaysBuild(tags) 8807769SAli.Saidi@ARM.com 8817769SAli.Saidi@ARM.com# Embed python files. All .py files that have been indicated by a 8827769SAli.Saidi@ARM.com# PySource() call in a SConscript need to be embedded into the M5 8835227Ssaidi@eecs.umich.edu# library. To do that, we compile the file to byte code, marshal the 8845227Ssaidi@eecs.umich.edu# byte code, compress it, and then generate a c++ file that 8855227Ssaidi@eecs.umich.edu# inserts the result into an array. 8865204Sstever@gmail.comdef embedPyFile(target, source, env): 8875204Sstever@gmail.com def c_str(string): 8885204Sstever@gmail.com if string is None: 8895204Sstever@gmail.com return "0" 8905204Sstever@gmail.com return '"%s"' % string 8915204Sstever@gmail.com 8925204Sstever@gmail.com '''Action function to compile a .py into a code object, marshal 8935204Sstever@gmail.com it, compress it, and stick it into an asm file so the code appears 8945204Sstever@gmail.com as just bytes with a label in the data section''' 8955204Sstever@gmail.com 8965204Sstever@gmail.com src = file(str(source[0]), 'r').read() 8975204Sstever@gmail.com 8985204Sstever@gmail.com pysource = PySource.tnodes[source[0]] 8995204Sstever@gmail.com compiled = compile(src, pysource.abspath, 'exec') 9005204Sstever@gmail.com marshalled = marshal.dumps(compiled) 9015204Sstever@gmail.com compressed = zlib.compress(marshalled) 9025204Sstever@gmail.com data = compressed 9036121Snate@binkert.org sym = pysource.symname 9045204Sstever@gmail.com 9057727SAli.Saidi@ARM.com code = code_formatter() 9067727SAli.Saidi@ARM.com code('''\ 9077727SAli.Saidi@ARM.com#include "sim/init.hh" 9087727SAli.Saidi@ARM.com 9097727SAli.Saidi@ARM.comnamespace { 91010453SAndrew.Bardsley@arm.com 91110453SAndrew.Bardsley@arm.comconst uint8_t data_${sym}[] = { 91210453SAndrew.Bardsley@arm.com''') 91310453SAndrew.Bardsley@arm.com code.indent() 91410453SAndrew.Bardsley@arm.com step = 16 91510453SAndrew.Bardsley@arm.com for i in xrange(0, len(data), step): 91610453SAndrew.Bardsley@arm.com x = array.array('B', data[i:i+step]) 91710453SAndrew.Bardsley@arm.com code(''.join('%d,' % d for d in x)) 91810453SAndrew.Bardsley@arm.com code.dedent() 91910453SAndrew.Bardsley@arm.com 92010453SAndrew.Bardsley@arm.com code('''}; 92110160Sandreas.hansson@arm.com 92210453SAndrew.Bardsley@arm.comEmbeddedPython embedded_${sym}( 92310453SAndrew.Bardsley@arm.com ${{c_str(pysource.arcname)}}, 92410453SAndrew.Bardsley@arm.com ${{c_str(pysource.abspath)}}, 92510453SAndrew.Bardsley@arm.com ${{c_str(pysource.modpath)}}, 92610453SAndrew.Bardsley@arm.com data_${sym}, 92710453SAndrew.Bardsley@arm.com ${{len(data)}}, 92810453SAndrew.Bardsley@arm.com ${{len(marshalled)}}); 92910453SAndrew.Bardsley@arm.com 9309812Sandreas.hansson@arm.com} // anonymous namespace 93110453SAndrew.Bardsley@arm.com''') 93210453SAndrew.Bardsley@arm.com code.write(str(target[0])) 93310453SAndrew.Bardsley@arm.com 93410453SAndrew.Bardsley@arm.comfor source in PySource.all: 93510453SAndrew.Bardsley@arm.com env.Command(source.cpp, source.tnode, 93610453SAndrew.Bardsley@arm.com MakeAction(embedPyFile, Transform("EMBED PY"))) 93710453SAndrew.Bardsley@arm.com Source(source.cpp, skip_no_python=True) 93810453SAndrew.Bardsley@arm.com 93910453SAndrew.Bardsley@arm.com######################################################################## 94010453SAndrew.Bardsley@arm.com# 94110453SAndrew.Bardsley@arm.com# Define binaries. Each different build type (debug, opt, etc.) gets 94210453SAndrew.Bardsley@arm.com# a slightly different build environment. 9437727SAli.Saidi@ARM.com# 94410453SAndrew.Bardsley@arm.com 94510453SAndrew.Bardsley@arm.com# List of constructed environments to pass back to SConstruct 94610453SAndrew.Bardsley@arm.comdate_source = Source('base/date.cc', skip_lib=True) 94710453SAndrew.Bardsley@arm.com 94810453SAndrew.Bardsley@arm.com# Capture this directory for the closure makeEnv, otherwise when it is 9493118Sstever@eecs.umich.edu# called, it won't know what directory it should use. 95010453SAndrew.Bardsley@arm.comvariant_dir = Dir('.').path 95110453SAndrew.Bardsley@arm.comdef variant(*path): 95210453SAndrew.Bardsley@arm.com return os.path.join(variant_dir, *path) 95310453SAndrew.Bardsley@arm.comdef variantd(*path): 9543118Sstever@eecs.umich.edu return variant(*path)+'/' 9553483Ssaidi@eecs.umich.edu 9563494Ssaidi@eecs.umich.edu# Function to create a new build environment as clone of current 9573494Ssaidi@eecs.umich.edu# environment 'env' with modified object suffix and optional stripped 9583483Ssaidi@eecs.umich.edu# binary. Additional keyword arguments are appended to corresponding 9593483Ssaidi@eecs.umich.edu# build environment vars. 9603483Ssaidi@eecs.umich.edudef makeEnv(env, label, objsfx, strip=False, disable_partial=False, **kwargs): 9613053Sstever@eecs.umich.edu # SCons doesn't know to append a library suffix when there is a '.' in the 9623053Sstever@eecs.umich.edu # name. Use '_' instead. 9633918Ssaidi@eecs.umich.edu libname = variant('gem5_' + label) 9643053Sstever@eecs.umich.edu exename = variant('gem5.' + label) 9653053Sstever@eecs.umich.edu secondary_exename = variant('m5.' + label) 9663053Sstever@eecs.umich.edu 9673053Sstever@eecs.umich.edu new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 9683053Sstever@eecs.umich.edu new_env.Label = label 9699396Sandreas.hansson@arm.com new_env.Append(**kwargs) 9709396Sandreas.hansson@arm.com 9719396Sandreas.hansson@arm.com if env['GCC']: 9729396Sandreas.hansson@arm.com # The address sanitizer is available for gcc >= 4.8 9739396Sandreas.hansson@arm.com if GetOption('with_asan'): 9749396Sandreas.hansson@arm.com if GetOption('with_ubsan') and \ 9759396Sandreas.hansson@arm.com compareVersions(env['GCC_VERSION'], '4.9') >= 0: 9769396Sandreas.hansson@arm.com new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 9779396Sandreas.hansson@arm.com '-fno-omit-frame-pointer']) 9789477Sandreas.hansson@arm.com new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 9799396Sandreas.hansson@arm.com else: 9809477Sandreas.hansson@arm.com new_env.Append(CCFLAGS=['-fsanitize=address', 9819477Sandreas.hansson@arm.com '-fno-omit-frame-pointer']) 9829477Sandreas.hansson@arm.com new_env.Append(LINKFLAGS='-fsanitize=address') 9839477Sandreas.hansson@arm.com # Only gcc >= 4.9 supports UBSan, so check both the version 9849396Sandreas.hansson@arm.com # and the command-line option before adding the compiler and 9857840Snate@binkert.org # linker flags. 9867865Sgblack@eecs.umich.edu elif GetOption('with_ubsan') and \ 9877865Sgblack@eecs.umich.edu compareVersions(env['GCC_VERSION'], '4.9') >= 0: 9887865Sgblack@eecs.umich.edu new_env.Append(CCFLAGS='-fsanitize=undefined') 9897865Sgblack@eecs.umich.edu new_env.Append(LINKFLAGS='-fsanitize=undefined') 9907865Sgblack@eecs.umich.edu 9917840Snate@binkert.org 9929900Sandreas@sandberg.pp.se if env['CLANG']: 9939900Sandreas@sandberg.pp.se # We require clang >= 3.1, so there is no need to check any 9949900Sandreas@sandberg.pp.se # versions here. 9959900Sandreas@sandberg.pp.se if GetOption('with_ubsan'): 99610456SCurtis.Dunham@arm.com if GetOption('with_asan'): 99710456SCurtis.Dunham@arm.com new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 99810456SCurtis.Dunham@arm.com '-fno-omit-frame-pointer']) 99910456SCurtis.Dunham@arm.com new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 100010456SCurtis.Dunham@arm.com else: 100110456SCurtis.Dunham@arm.com new_env.Append(CCFLAGS='-fsanitize=undefined') 100210456SCurtis.Dunham@arm.com new_env.Append(LINKFLAGS='-fsanitize=undefined') 100310456SCurtis.Dunham@arm.com 100410456SCurtis.Dunham@arm.com elif GetOption('with_asan'): 100510456SCurtis.Dunham@arm.com new_env.Append(CCFLAGS=['-fsanitize=address', 10069045SAli.Saidi@ARM.com '-fno-omit-frame-pointer']) 10077840Snate@binkert.org new_env.Append(LINKFLAGS='-fsanitize=address') 10087840Snate@binkert.org 10097840Snate@binkert.org werror_env = new_env.Clone() 10101858SN/A # Treat warnings as errors but white list some warnings that we 10111858SN/A # want to allow (e.g., deprecation warnings). 10121858SN/A werror_env.Append(CCFLAGS=['-Werror', 10131858SN/A '-Wno-error=deprecated-declarations', 10141858SN/A '-Wno-error=deprecated', 10151858SN/A ]) 10169903Sandreas.hansson@arm.com 10179903Sandreas.hansson@arm.com def make_obj(source, static, extra_deps = None): 10189903Sandreas.hansson@arm.com '''This function adds the specified source to the correct 10199903Sandreas.hansson@arm.com build environment, and returns the corresponding SCons Object 10209903Sandreas.hansson@arm.com nodes''' 10219903Sandreas.hansson@arm.com 10229651SAndreas.Sandberg@ARM.com if source.Werror: 10239903Sandreas.hansson@arm.com env = werror_env 10249651SAndreas.Sandberg@ARM.com else: 10259651SAndreas.Sandberg@ARM.com env = new_env 10269651SAndreas.Sandberg@ARM.com 10279651SAndreas.Sandberg@ARM.com if static: 10289651SAndreas.Sandberg@ARM.com obj = env.StaticObject(source.tnode) 10299657Sandreas.sandberg@arm.com else: 10309883Sandreas@sandberg.pp.se obj = env.SharedObject(source.tnode) 10319651SAndreas.Sandberg@ARM.com 10329651SAndreas.Sandberg@ARM.com if extra_deps: 10339651SAndreas.Sandberg@ARM.com env.Depends(obj, extra_deps) 10349651SAndreas.Sandberg@ARM.com 10359651SAndreas.Sandberg@ARM.com return obj 10369651SAndreas.Sandberg@ARM.com 10379651SAndreas.Sandberg@ARM.com lib_guards = {'main': False, 'skip_lib': False} 10389651SAndreas.Sandberg@ARM.com 10399651SAndreas.Sandberg@ARM.com # Without Python, leave out all Python content from the library 10409651SAndreas.Sandberg@ARM.com # builds. The option doesn't affect gem5 built as a program 10419651SAndreas.Sandberg@ARM.com if GetOption('without_python'): 10429986Sandreas@sandberg.pp.se lib_guards['skip_no_python'] = False 10439986Sandreas@sandberg.pp.se 10449986Sandreas@sandberg.pp.se static_objs = [] 10459986Sandreas@sandberg.pp.se shared_objs = [] 10469986Sandreas@sandberg.pp.se for s in guarded_source_iterator(Source.source_groups[None], **lib_guards): 10479986Sandreas@sandberg.pp.se static_objs.append(make_obj(s, True)) 10485863Snate@binkert.org shared_objs.append(make_obj(s, False)) 10495863Snate@binkert.org 10505863Snate@binkert.org partial_objs = [] 10515863Snate@binkert.org for group, all_srcs in Source.source_groups.iteritems(): 10526121Snate@binkert.org # If these are the ungrouped source files, skip them. 10531858SN/A if not group: 10545863Snate@binkert.org continue 10555863Snate@binkert.org 10565863Snate@binkert.org # Get a list of the source files compatible with the current guards. 10575863Snate@binkert.org srcs = [ s for s in guarded_source_iterator(all_srcs, **lib_guards) ] 10585863Snate@binkert.org # If there aren't any left, skip this group. 10592139SN/A if not srcs: 10604202Sbinkertn@umich.edu continue 10614202Sbinkertn@umich.edu 10622139SN/A # If partial linking is disabled, add these sources to the build 10636994Snate@binkert.org # directly, and short circuit this loop. 10646994Snate@binkert.org if disable_partial: 10656994Snate@binkert.org for s in srcs: 10666994Snate@binkert.org static_objs.append(make_obj(s, True)) 10676994Snate@binkert.org shared_objs.append(make_obj(s, False)) 10686994Snate@binkert.org continue 10696994Snate@binkert.org 10706994Snate@binkert.org # Set up the static partially linked objects. 107110319SAndreas.Sandberg@ARM.com source_objs = [ make_obj(s, True) for s in srcs ] 10726994Snate@binkert.org file_name = new_env.subst("${OBJPREFIX}lib${OBJSUFFIX}.partial") 10736994Snate@binkert.org target = File(joinpath(group, file_name)) 10746994Snate@binkert.org partial = env.PartialStatic(target=target, source=source_objs) 10756994Snate@binkert.org static_objs.append(partial) 10766994Snate@binkert.org 10776994Snate@binkert.org # Set up the shared partially linked objects. 10786994Snate@binkert.org source_objs = [ make_obj(s, False) for s in srcs ] 10796994Snate@binkert.org file_name = new_env.subst("${SHOBJPREFIX}lib${SHOBJSUFFIX}.partial") 10806994Snate@binkert.org target = File(joinpath(group, file_name)) 10816994Snate@binkert.org partial = env.PartialShared(target=target, source=source_objs) 10826994Snate@binkert.org shared_objs.append(partial) 10832155SN/A 10845863Snate@binkert.org static_date = make_obj(date_source, static=True, extra_deps=static_objs) 10851869SN/A static_objs.append(static_date) 10861869SN/A 10875863Snate@binkert.org shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 10885863Snate@binkert.org shared_objs.append(shared_date) 10894202Sbinkertn@umich.edu 10906108Snate@binkert.org # First make a library of everything but main() so other programs can 10916108Snate@binkert.org # link against m5. 10926108Snate@binkert.org static_lib = new_env.StaticLibrary(libname, static_objs) 10936108Snate@binkert.org shared_lib = new_env.SharedLibrary(libname, shared_objs) 10949219Spower.jg@gmail.com 10959219Spower.jg@gmail.com # Now link a stub with main() and the static library. 10969219Spower.jg@gmail.com main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 10979219Spower.jg@gmail.com 10989219Spower.jg@gmail.com for test in UnitTest.all: 10999219Spower.jg@gmail.com flags = { test.target : True } 11009219Spower.jg@gmail.com test_sources = Source.get(**flags) 11019219Spower.jg@gmail.com test_objs = [ make_obj(s, static=True) for s in test_sources ] 11024202Sbinkertn@umich.edu if test.main: 11035863Snate@binkert.org test_objs += main_objs 110410135SCurtis.Dunham@arm.com path = variant('unittest/%s.%s' % (test.target, label)) 11058474Sgblack@eecs.umich.edu new_env.Program(path, test_objs + static_objs) 11065742Snate@binkert.org 11078268Ssteve.reinhardt@amd.com progname = exename 11088268Ssteve.reinhardt@amd.com if strip: 11098268Ssteve.reinhardt@amd.com progname += '.unstripped' 11105742Snate@binkert.org 11115341Sstever@gmail.com targets = new_env.Program(progname, main_objs + static_objs) 11128474Sgblack@eecs.umich.edu 11138474Sgblack@eecs.umich.edu if strip: 11145342Sstever@gmail.com if sys.platform == 'sunos5': 11154202Sbinkertn@umich.edu cmd = 'cp $SOURCE $TARGET; strip $TARGET' 11164202Sbinkertn@umich.edu else: 11174202Sbinkertn@umich.edu cmd = 'strip $SOURCE -o $TARGET' 11185863Snate@binkert.org targets = new_env.Command(exename, progname, 11195863Snate@binkert.org MakeAction(cmd, Transform("STRIP"))) 11206994Snate@binkert.org 11216994Snate@binkert.org new_env.Command(secondary_exename, exename, 112210319SAndreas.Sandberg@ARM.com MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 11235863Snate@binkert.org 11245863Snate@binkert.org new_env.M5Binary = targets[0] 11255863Snate@binkert.org 11265863Snate@binkert.org # Set up regression tests. 11275863Snate@binkert.org SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 11285863Snate@binkert.org variant_dir=variantd('tests', new_env.Label), 11295863Snate@binkert.org exports={ 'env' : new_env }, duplicate=False) 11305863Snate@binkert.org 11317840Snate@binkert.org# Start out with the compiler flags common to all compilers, 11325863Snate@binkert.org# i.e. they all use -g for opt and -g -pg for prof 11335952Ssaidi@eecs.umich.educcflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 11349651SAndreas.Sandberg@ARM.com 'perf' : ['-g']} 11359219Spower.jg@gmail.com 11369219Spower.jg@gmail.com# Start out with the linker flags common to all linkers, i.e. -pg for 11371869SN/A# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 11381858SN/A# no-as-needed and as-needed as the binutils linker is too clever and 11395863Snate@binkert.org# simply doesn't link to the library otherwise. 11409420Sandreas.hansson@arm.comldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 114110607Sgabeblack@google.com 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 11429986Sandreas@sandberg.pp.se 11431858SN/A# For Link Time Optimization, the optimisation flags used to compile 1144955SN/A# individual files are decoupled from those used at link time 1145955SN/A# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 11461869SN/A# to also update the linker flags based on the target. 11471869SN/Aif env['GCC']: 11481869SN/A if sys.platform == 'sunos5': 11491869SN/A ccflags['debug'] += ['-gstabs+'] 11501869SN/A else: 11515863Snate@binkert.org ccflags['debug'] += ['-ggdb3'] 11525863Snate@binkert.org ldflags['debug'] += ['-O0'] 11535863Snate@binkert.org # opt, fast, prof and perf all share the same cc flags, also add 11541869SN/A # the optimization to the ldflags as LTO defers the optimization 11555863Snate@binkert.org # to link time 11561869SN/A for target in ['opt', 'fast', 'prof', 'perf']: 11575863Snate@binkert.org ccflags[target] += ['-O3'] 11581869SN/A ldflags[target] += ['-O3'] 11591869SN/A 11601869SN/A ccflags['fast'] += env['LTO_CCFLAGS'] 11611869SN/A ldflags['fast'] += env['LTO_LDFLAGS'] 11628483Sgblack@eecs.umich.eduelif env['CLANG']: 11631869SN/A ccflags['debug'] += ['-g', '-O0'] 11641869SN/A # opt, fast, prof and perf all share the same cc flags 11651869SN/A for target in ['opt', 'fast', 'prof', 'perf']: 11661869SN/A ccflags[target] += ['-O3'] 11675863Snate@binkert.orgelse: 11685863Snate@binkert.org print 'Unknown compiler, please fix compiler options' 11691869SN/A Exit(1) 11705863Snate@binkert.org 11715863Snate@binkert.org 11723356Sbinkertn@umich.edu# To speed things up, we only instantiate the build environments we 11733356Sbinkertn@umich.edu# need. We try to identify the needed environment for each target; if 11743356Sbinkertn@umich.edu# we can't, we fall back on instantiating all the environments just to 11753356Sbinkertn@umich.edu# be safe. 11763356Sbinkertn@umich.edutarget_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 11774781Snate@binkert.orgobj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 11785863Snate@binkert.org 'gpo' : 'perf'} 11795863Snate@binkert.org 11801869SN/Adef identifyTarget(t): 11811869SN/A ext = t.split('.')[-1] 11821869SN/A if ext in target_types: 11836121Snate@binkert.org return ext 11841869SN/A if obj2target.has_key(ext): 11852638Sstever@eecs.umich.edu return obj2target[ext] 11866121Snate@binkert.org match = re.search(r'/tests/([^/]+)/', t) 11876121Snate@binkert.org if match and match.group(1) in target_types: 11882638Sstever@eecs.umich.edu return match.group(1) 11895749Scws3k@cs.virginia.edu return 'all' 11906121Snate@binkert.org 11916121Snate@binkert.orgneeded_envs = [identifyTarget(target) for target in BUILD_TARGETS] 11925749Scws3k@cs.virginia.eduif 'all' in needed_envs: 11939537Satgutier@umich.edu needed_envs += target_types 11949537Satgutier@umich.edu 11959537Satgutier@umich.edudef makeEnvirons(target, source, env): 11969537Satgutier@umich.edu # cause any later Source() calls to be fatal, as a diagnostic. 11979888Sandreas@sandberg.pp.se Source.done() 11989888Sandreas@sandberg.pp.se 11999888Sandreas@sandberg.pp.se # Debug binary 12009888Sandreas@sandberg.pp.se if 'debug' in needed_envs: 120110066Sandreas.hansson@arm.com makeEnv(env, 'debug', '.do', 120210066Sandreas.hansson@arm.com CCFLAGS = Split(ccflags['debug']), 120310066Sandreas.hansson@arm.com CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 120410066Sandreas.hansson@arm.com LINKFLAGS = Split(ldflags['debug'])) 120510428Sandreas.hansson@arm.com 120610428Sandreas.hansson@arm.com # Optimized binary 120710428Sandreas.hansson@arm.com if 'opt' in needed_envs: 120810428Sandreas.hansson@arm.com makeEnv(env, 'opt', '.o', 12091869SN/A CCFLAGS = Split(ccflags['opt']), 12101869SN/A CPPDEFINES = ['TRACING_ON=1'], 12113546Sgblack@eecs.umich.edu LINKFLAGS = Split(ldflags['opt'])) 12123546Sgblack@eecs.umich.edu 12133546Sgblack@eecs.umich.edu # "Fast" binary 12143546Sgblack@eecs.umich.edu if 'fast' in needed_envs: 12156121Snate@binkert.org disable_partial = \ 121610196SCurtis.Dunham@arm.com env.get('BROKEN_INCREMENTAL_LTO', False) and \ 12175863Snate@binkert.org GetOption('force_lto') 12183546Sgblack@eecs.umich.edu makeEnv(env, 'fast', '.fo', strip = True, 12193546Sgblack@eecs.umich.edu CCFLAGS = Split(ccflags['fast']), 12203546Sgblack@eecs.umich.edu CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 12213546Sgblack@eecs.umich.edu LINKFLAGS = Split(ldflags['fast']), 12224781Snate@binkert.org disable_partial=disable_partial) 12236658Snate@binkert.org 122410196SCurtis.Dunham@arm.com # Profiled binary using gprof 122510196SCurtis.Dunham@arm.com if 'prof' in needed_envs: 122610196SCurtis.Dunham@arm.com makeEnv(env, 'prof', '.po', 122710196SCurtis.Dunham@arm.com CCFLAGS = Split(ccflags['prof']), 122810196SCurtis.Dunham@arm.com CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 122910196SCurtis.Dunham@arm.com LINKFLAGS = Split(ldflags['prof'])) 123010196SCurtis.Dunham@arm.com 12313546Sgblack@eecs.umich.edu # Profiled binary using google-pprof 12323546Sgblack@eecs.umich.edu if 'perf' in needed_envs: 12333546Sgblack@eecs.umich.edu makeEnv(env, 'perf', '.gpo', 12343546Sgblack@eecs.umich.edu CCFLAGS = Split(ccflags['perf']), 12357756SAli.Saidi@ARM.com CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 12367816Ssteve.reinhardt@amd.com LINKFLAGS = Split(ldflags['perf'])) 12373546Sgblack@eecs.umich.edu 12383546Sgblack@eecs.umich.edu# The MakeEnvirons Builder defers the full dependency collection until 12393546Sgblack@eecs.umich.edu# after processing the ISA definition (due to dynamically generated 12403546Sgblack@eecs.umich.edu# source files). Add this dependency to all targets so they will wait 124110196SCurtis.Dunham@arm.com# until the environments are completely set up. Otherwise, a second 124210196SCurtis.Dunham@arm.com# process (e.g. -j2 or higher) will try to compile the requested target, 124310196SCurtis.Dunham@arm.com# not know how, and fail. 124410196SCurtis.Dunham@arm.comenv.Append(BUILDERS = {'MakeEnvirons' : 124510196SCurtis.Dunham@arm.com Builder(action=MakeAction(makeEnvirons, 12464202Sbinkertn@umich.edu Transform("ENVIRONS", 1)))}) 12473546Sgblack@eecs.umich.edu 124810196SCurtis.Dunham@arm.comisa_target = '#${VARIANT_NAME}-deps' 124910196SCurtis.Dunham@arm.comenvirons = '#${VARIANT_NAME}-environs' 125010196SCurtis.Dunham@arm.comenv.Depends('#all-deps', isa_target) 125110196SCurtis.Dunham@arm.comenv.Depends('#all-environs', environs) 125210196SCurtis.Dunham@arm.comenv.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 125310196SCurtis.Dunham@arm.comenvSetup = env.MakeEnvirons(environs, isa_target) 125410196SCurtis.Dunham@arm.com 125510196SCurtis.Dunham@arm.com# make sure no -deps targets occur before all ISAs are complete 125610196SCurtis.Dunham@arm.comenv.Depends(isa_target, '#all-isas') 125710196SCurtis.Dunham@arm.com# likewise for -environs targets and all the -deps targets 125810196SCurtis.Dunham@arm.comenv.Depends(environs, '#all-deps') 125910196SCurtis.Dunham@arm.com