SConscript revision 10584
1955SN/A# -*- mode:python -*- 2955SN/A 31762SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 4955SN/A# All rights reserved. 5955SN/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. 282665Ssaidi@eecs.umich.edu# 294762Snate@binkert.org# Authors: Nathan Binkert 30955SN/A 315522Snate@binkert.orgimport array 326143Snate@binkert.orgimport bisect 334762Snate@binkert.orgimport imp 345522Snate@binkert.orgimport marshal 35955SN/Aimport os 365522Snate@binkert.orgimport re 3711974Sgabeblack@google.comimport sys 38955SN/Aimport zlib 395522Snate@binkert.org 404202Sbinkertn@umich.edufrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 415742Snate@binkert.org 42955SN/Aimport SCons 434381Sbinkertn@umich.edu 444381Sbinkertn@umich.edu# This file defines how to build a particular configuration of gem5 458334Snate@binkert.org# based on variable settings in the 'env' build environment. 46955SN/A 47955SN/AImport('*') 484202Sbinkertn@umich.edu 49955SN/A# Children need to see the environment 504382Sbinkertn@umich.eduExport('env') 514382Sbinkertn@umich.edu 524382Sbinkertn@umich.edubuild_env = [(opt, env[opt]) for opt in export_vars] 536654Snate@binkert.org 545517Snate@binkert.orgfrom m5.util import code_formatter, compareVersions 558614Sgblack@eecs.umich.edu 567674Snate@binkert.org######################################################################## 576143Snate@binkert.org# Code for adding source files of various types 586143Snate@binkert.org# 596143Snate@binkert.org# When specifying a source file of some type, a set of guards can be 608233Snate@binkert.org# specified for that file. When get() is used to find the files, if 618233Snate@binkert.org# get specifies a set of filters, only files that match those filters 628233Snate@binkert.org# will be accepted (unspecified filters on files are assumed to be 638233Snate@binkert.org# false). Current filters are: 648233Snate@binkert.org# main -- specifies the gem5 main() function 658334Snate@binkert.org# skip_lib -- do not put this file into the gem5 library 668334Snate@binkert.org# skip_no_python -- do not put this file into a no_python library 6710453SAndrew.Bardsley@arm.com# as it embeds compiled Python 6810453SAndrew.Bardsley@arm.com# <unittest> -- unit tests use filters based on the unit test name 698233Snate@binkert.org# 708233Snate@binkert.org# A parent can now be specified for a source file and default filter 718233Snate@binkert.org# values will be retrieved recursively from parents (children override 728233Snate@binkert.org# parents). 738233Snate@binkert.org# 748233Snate@binkert.orgclass SourceMeta(type): 7511983Sgabeblack@google.com '''Meta class for source files that keeps track of all files of a 7611983Sgabeblack@google.com particular type and has a get function for finding all functions 7711983Sgabeblack@google.com of a certain type that match a set of guards''' 7811983Sgabeblack@google.com def __init__(cls, name, bases, dict): 7911983Sgabeblack@google.com super(SourceMeta, cls).__init__(name, bases, dict) 8011983Sgabeblack@google.com cls.all = [] 8111983Sgabeblack@google.com 8211983Sgabeblack@google.com def get(cls, **guards): 8311983Sgabeblack@google.com '''Find all files that match the specified guards. If a source 8411983Sgabeblack@google.com file does not specify a flag, the default is False''' 8511983Sgabeblack@google.com for src in cls.all: 866143Snate@binkert.org for flag,value in guards.iteritems(): 878233Snate@binkert.org # if the flag is found and has a different value, skip 888233Snate@binkert.org # this file 898233Snate@binkert.org if src.all_guards.get(flag, False) != value: 906143Snate@binkert.org break 916143Snate@binkert.org else: 926143Snate@binkert.org yield src 9311308Santhony.gutierrez@amd.com 948233Snate@binkert.orgclass SourceFile(object): 958233Snate@binkert.org '''Base object that encapsulates the notion of a source file. 968233Snate@binkert.org This includes, the source node, target node, various manipulations 9711983Sgabeblack@google.com of those. A source file also specifies a set of guards which 9811983Sgabeblack@google.com describing which builds the source file applies to. A parent can 994762Snate@binkert.org also be specified to get default guards from''' 1006143Snate@binkert.org __metaclass__ = SourceMeta 1018233Snate@binkert.org def __init__(self, source, parent=None, **guards): 1028233Snate@binkert.org self.guards = guards 1038233Snate@binkert.org self.parent = parent 1048233Snate@binkert.org 1058233Snate@binkert.org tnode = source 1066143Snate@binkert.org if not isinstance(source, SCons.Node.FS.File): 1078233Snate@binkert.org tnode = File(source) 1088233Snate@binkert.org 1098233Snate@binkert.org self.tnode = tnode 1108233Snate@binkert.org self.snode = tnode.srcnode() 1116143Snate@binkert.org 1126143Snate@binkert.org for base in type(self).__mro__: 1136143Snate@binkert.org if issubclass(base, SourceFile): 1146143Snate@binkert.org base.all.append(self) 1156143Snate@binkert.org 1166143Snate@binkert.org @property 1176143Snate@binkert.org def filename(self): 1186143Snate@binkert.org return str(self.tnode) 1196143Snate@binkert.org 1207065Snate@binkert.org @property 1216143Snate@binkert.org def dirname(self): 1228233Snate@binkert.org return dirname(self.filename) 1238233Snate@binkert.org 1248233Snate@binkert.org @property 1258233Snate@binkert.org def basename(self): 1268233Snate@binkert.org return basename(self.filename) 1278233Snate@binkert.org 1288233Snate@binkert.org @property 1298233Snate@binkert.org def extname(self): 1308233Snate@binkert.org index = self.basename.rfind('.') 1318233Snate@binkert.org if index <= 0: 1328233Snate@binkert.org # dot files aren't extensions 1338233Snate@binkert.org return self.basename, None 1348233Snate@binkert.org 1358233Snate@binkert.org return self.basename[:index], self.basename[index+1:] 1368233Snate@binkert.org 1378233Snate@binkert.org @property 1388233Snate@binkert.org def all_guards(self): 1398233Snate@binkert.org '''find all guards for this object getting default values 1408233Snate@binkert.org recursively from its parents''' 1418233Snate@binkert.org guards = {} 1428233Snate@binkert.org if self.parent: 1438233Snate@binkert.org guards.update(self.parent.guards) 1448233Snate@binkert.org guards.update(self.guards) 1458233Snate@binkert.org return guards 1468233Snate@binkert.org 1478233Snate@binkert.org def __lt__(self, other): return self.filename < other.filename 1488233Snate@binkert.org def __le__(self, other): return self.filename <= other.filename 1498233Snate@binkert.org def __gt__(self, other): return self.filename > other.filename 1508233Snate@binkert.org def __ge__(self, other): return self.filename >= other.filename 1518233Snate@binkert.org def __eq__(self, other): return self.filename == other.filename 1528233Snate@binkert.org def __ne__(self, other): return self.filename != other.filename 1536143Snate@binkert.org 1546143Snate@binkert.org @staticmethod 1556143Snate@binkert.org def done(): 1566143Snate@binkert.org def disabled(cls, name, *ignored): 1576143Snate@binkert.org raise RuntimeError("Additional SourceFile '%s'" % name,\ 1586143Snate@binkert.org "declared, but targets deps are already fixed.") 1599982Satgutier@umich.edu SourceFile.__init__ = disabled 16010196SCurtis.Dunham@arm.com 16110196SCurtis.Dunham@arm.com 16210196SCurtis.Dunham@arm.comclass Source(SourceFile): 16310196SCurtis.Dunham@arm.com '''Add a c/c++ source file to the build''' 16410196SCurtis.Dunham@arm.com def __init__(self, source, Werror=True, swig=False, **guards): 16510196SCurtis.Dunham@arm.com '''specify the source file, and any guards''' 16610196SCurtis.Dunham@arm.com super(Source, self).__init__(source, **guards) 16710196SCurtis.Dunham@arm.com 1686143Snate@binkert.org self.Werror = Werror 16911983Sgabeblack@google.com self.swig = swig 17011983Sgabeblack@google.com 17111983Sgabeblack@google.comclass PySource(SourceFile): 17211983Sgabeblack@google.com '''Add a python source file to the named package''' 17311983Sgabeblack@google.com invalid_sym_char = re.compile('[^A-z0-9_]') 17411983Sgabeblack@google.com modules = {} 17511983Sgabeblack@google.com tnodes = {} 17611983Sgabeblack@google.com symnames = {} 17711983Sgabeblack@google.com 1786143Snate@binkert.org def __init__(self, package, source, **guards): 1798945Ssteve.reinhardt@amd.com '''specify the python package, the source file, and any guards''' 1808233Snate@binkert.org super(PySource, self).__init__(source, **guards) 1818233Snate@binkert.org 1826143Snate@binkert.org modname,ext = self.extname 1838945Ssteve.reinhardt@amd.com assert ext == 'py' 1846143Snate@binkert.org 1856143Snate@binkert.org if package: 18611983Sgabeblack@google.com path = package.split('.') 18711983Sgabeblack@google.com else: 1886143Snate@binkert.org path = [] 1896143Snate@binkert.org 1905522Snate@binkert.org modpath = path[:] 1916143Snate@binkert.org if modname != '__init__': 1926143Snate@binkert.org modpath += [ modname ] 1936143Snate@binkert.org modpath = '.'.join(modpath) 1949982Satgutier@umich.edu 1958233Snate@binkert.org arcpath = path + [ self.basename ] 1968233Snate@binkert.org abspath = self.snode.abspath 1978233Snate@binkert.org if not exists(abspath): 1986143Snate@binkert.org abspath = self.tnode.abspath 1996143Snate@binkert.org 2006143Snate@binkert.org self.package = package 2016143Snate@binkert.org self.modname = modname 2025522Snate@binkert.org self.modpath = modpath 2035522Snate@binkert.org self.arcname = joinpath(*arcpath) 2045522Snate@binkert.org self.abspath = abspath 2055522Snate@binkert.org self.compiled = File(self.filename + 'c') 2065604Snate@binkert.org self.cpp = File(self.filename + '.cc') 2075604Snate@binkert.org self.symname = PySource.invalid_sym_char.sub('_', modpath) 2086143Snate@binkert.org 2096143Snate@binkert.org PySource.modules[modpath] = self 2104762Snate@binkert.org PySource.tnodes[self.tnode] = self 2114762Snate@binkert.org PySource.symnames[self.symname] = self 2126143Snate@binkert.org 2136727Ssteve.reinhardt@amd.comclass SimObject(PySource): 2146727Ssteve.reinhardt@amd.com '''Add a SimObject python file as a python source object and add 2156727Ssteve.reinhardt@amd.com it to a list of sim object modules''' 2164762Snate@binkert.org 2176143Snate@binkert.org fixed = False 2186143Snate@binkert.org modnames = [] 2196143Snate@binkert.org 2206143Snate@binkert.org def __init__(self, source, **guards): 2216727Ssteve.reinhardt@amd.com '''Specify the source file and any guards (automatically in 2226143Snate@binkert.org the m5.objects package)''' 2237674Snate@binkert.org super(SimObject, self).__init__('m5.objects', source, **guards) 2247674Snate@binkert.org if self.fixed: 2255604Snate@binkert.org raise AttributeError, "Too late to call SimObject now." 2266143Snate@binkert.org 2276143Snate@binkert.org bisect.insort_right(SimObject.modnames, self.modname) 2286143Snate@binkert.org 2294762Snate@binkert.orgclass SwigSource(SourceFile): 2306143Snate@binkert.org '''Add a swig file to build''' 2314762Snate@binkert.org 2324762Snate@binkert.org def __init__(self, package, source, **guards): 2334762Snate@binkert.org '''Specify the python package, the source file, and any guards''' 2346143Snate@binkert.org super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 2356143Snate@binkert.org 2364762Snate@binkert.org modname,ext = self.extname 2378233Snate@binkert.org assert ext == 'i' 2388233Snate@binkert.org 2398233Snate@binkert.org self.module = modname 2408233Snate@binkert.org cc_file = joinpath(self.dirname, modname + '_wrap.cc') 2416143Snate@binkert.org py_file = joinpath(self.dirname, modname + '.py') 2426143Snate@binkert.org 2434762Snate@binkert.org self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 2446143Snate@binkert.org self.py_source = PySource(package, py_file, parent=self, **guards) 2454762Snate@binkert.org 2466143Snate@binkert.orgclass ProtoBuf(SourceFile): 2474762Snate@binkert.org '''Add a Protocol Buffer to build''' 2486143Snate@binkert.org 2498233Snate@binkert.org def __init__(self, source, **guards): 2508233Snate@binkert.org '''Specify the source file, and any guards''' 25110453SAndrew.Bardsley@arm.com super(ProtoBuf, self).__init__(source, **guards) 2526143Snate@binkert.org 2536143Snate@binkert.org # Get the file name and the extension 2546143Snate@binkert.org modname,ext = self.extname 2556143Snate@binkert.org assert ext == 'proto' 25611548Sandreas.hansson@arm.com 2576143Snate@binkert.org # Currently, we stick to generating the C++ headers, so we 2586143Snate@binkert.org # only need to track the source and header. 2596143Snate@binkert.org self.cc_file = File(modname + '.pb.cc') 2606143Snate@binkert.org self.hh_file = File(modname + '.pb.h') 26110453SAndrew.Bardsley@arm.com 26210453SAndrew.Bardsley@arm.comclass UnitTest(object): 263955SN/A '''Create a UnitTest''' 2649396Sandreas.hansson@arm.com 2659396Sandreas.hansson@arm.com all = [] 2669396Sandreas.hansson@arm.com def __init__(self, target, *sources, **kwargs): 2679396Sandreas.hansson@arm.com '''Specify the target name and any sources. Sources that are 2689396Sandreas.hansson@arm.com not SourceFiles are evalued with Source(). All files are 2699396Sandreas.hansson@arm.com guarded with a guard of the same name as the UnitTest 2709396Sandreas.hansson@arm.com target.''' 2719396Sandreas.hansson@arm.com 2729396Sandreas.hansson@arm.com srcs = [] 2739396Sandreas.hansson@arm.com for src in sources: 2749396Sandreas.hansson@arm.com if not isinstance(src, SourceFile): 2759396Sandreas.hansson@arm.com src = Source(src, skip_lib=True) 2769396Sandreas.hansson@arm.com src.guards[target] = True 2779930Sandreas.hansson@arm.com srcs.append(src) 2789930Sandreas.hansson@arm.com 2799396Sandreas.hansson@arm.com self.sources = srcs 2808235Snate@binkert.org self.target = target 2818235Snate@binkert.org self.main = kwargs.get('main', False) 2826143Snate@binkert.org UnitTest.all.append(self) 2838235Snate@binkert.org 2849003SAli.Saidi@ARM.com# Children should have access 2858235Snate@binkert.orgExport('Source') 2868235Snate@binkert.orgExport('PySource') 2878235Snate@binkert.orgExport('SimObject') 2888235Snate@binkert.orgExport('SwigSource') 2898235Snate@binkert.orgExport('ProtoBuf') 2908235Snate@binkert.orgExport('UnitTest') 2918235Snate@binkert.org 2928235Snate@binkert.org######################################################################## 2938235Snate@binkert.org# 2948235Snate@binkert.org# Debug Flags 2958235Snate@binkert.org# 2968235Snate@binkert.orgdebug_flags = {} 2978235Snate@binkert.orgdef DebugFlag(name, desc=None): 2988235Snate@binkert.org if name in debug_flags: 2999003SAli.Saidi@ARM.com raise AttributeError, "Flag %s already specified" % name 3008235Snate@binkert.org debug_flags[name] = (name, (), desc) 3015584Snate@binkert.org 3024382Sbinkertn@umich.edudef CompoundFlag(name, flags, desc=None): 3034202Sbinkertn@umich.edu if name in debug_flags: 3044382Sbinkertn@umich.edu raise AttributeError, "Flag %s already specified" % name 3054382Sbinkertn@umich.edu 3064382Sbinkertn@umich.edu compound = tuple(flags) 3079396Sandreas.hansson@arm.com debug_flags[name] = (name, compound, desc) 3085584Snate@binkert.org 3094382Sbinkertn@umich.eduExport('DebugFlag') 3104382Sbinkertn@umich.eduExport('CompoundFlag') 3114382Sbinkertn@umich.edu 3128232Snate@binkert.org######################################################################## 3135192Ssaidi@eecs.umich.edu# 3148232Snate@binkert.org# Set some compiler variables 3158232Snate@binkert.org# 3168232Snate@binkert.org 3175192Ssaidi@eecs.umich.edu# Include file paths are rooted in this directory. SCons will 3188232Snate@binkert.org# automatically expand '.' to refer to both the source directory and 3195192Ssaidi@eecs.umich.edu# the corresponding build directory to pick up generated include 3205799Snate@binkert.org# files. 3218232Snate@binkert.orgenv.Append(CPPPATH=Dir('.')) 3225192Ssaidi@eecs.umich.edu 3235192Ssaidi@eecs.umich.edufor extra_dir in extras_dir_list: 3245192Ssaidi@eecs.umich.edu env.Append(CPPPATH=Dir(extra_dir)) 3258232Snate@binkert.org 3265192Ssaidi@eecs.umich.edu# Workaround for bug in SCons version > 0.97d20071212 3278232Snate@binkert.org# Scons bug id: 2006 gem5 Bug id: 308 3285192Ssaidi@eecs.umich.edufor root, dirs, files in os.walk(base_dir, topdown=True): 3295192Ssaidi@eecs.umich.edu Dir(root[len(base_dir) + 1:]) 3305192Ssaidi@eecs.umich.edu 3315192Ssaidi@eecs.umich.edu######################################################################## 3324382Sbinkertn@umich.edu# 3334382Sbinkertn@umich.edu# Walk the tree and execute all SConscripts in subdirectories 3344382Sbinkertn@umich.edu# 3352667Sstever@eecs.umich.edu 3362667Sstever@eecs.umich.eduhere = Dir('.').srcnode().abspath 3372667Sstever@eecs.umich.edufor root, dirs, files in os.walk(base_dir, topdown=True): 3382667Sstever@eecs.umich.edu if root == here: 3392667Sstever@eecs.umich.edu # we don't want to recurse back into this SConscript 3402667Sstever@eecs.umich.edu continue 3415742Snate@binkert.org 3425742Snate@binkert.org if 'SConscript' in files: 3435742Snate@binkert.org build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 3445793Snate@binkert.org SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3458334Snate@binkert.org 3465793Snate@binkert.orgfor extra_dir in extras_dir_list: 3475793Snate@binkert.org prefix_len = len(dirname(extra_dir)) + 1 3485793Snate@binkert.org 3494382Sbinkertn@umich.edu # Also add the corresponding build directory to pick up generated 3504762Snate@binkert.org # include files. 3515344Sstever@gmail.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 3524382Sbinkertn@umich.edu 3535341Sstever@gmail.com for root, dirs, files in os.walk(extra_dir, topdown=True): 3545742Snate@binkert.org # if build lives in the extras directory, don't walk down it 3555742Snate@binkert.org if 'build' in dirs: 3565742Snate@binkert.org dirs.remove('build') 3575742Snate@binkert.org 3585742Snate@binkert.org if 'SConscript' in files: 3594762Snate@binkert.org build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 3605742Snate@binkert.org SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3615742Snate@binkert.org 36211984Sgabeblack@google.comfor opt in export_vars: 3637722Sgblack@eecs.umich.edu env.ConfigFile(opt) 3645742Snate@binkert.org 3655742Snate@binkert.orgdef makeTheISA(source, target, env): 3665742Snate@binkert.org isas = [ src.get_contents() for src in source ] 3679930Sandreas.hansson@arm.com target_isa = env['TARGET_ISA'] 3689930Sandreas.hansson@arm.com def define(isa): 3699930Sandreas.hansson@arm.com return isa.upper() + '_ISA' 3709930Sandreas.hansson@arm.com 3719930Sandreas.hansson@arm.com def namespace(isa): 3725742Snate@binkert.org return isa[0].upper() + isa[1:].lower() + 'ISA' 3738242Sbradley.danofsky@amd.com 3748242Sbradley.danofsky@amd.com 3758242Sbradley.danofsky@amd.com code = code_formatter() 3768242Sbradley.danofsky@amd.com code('''\ 3775341Sstever@gmail.com#ifndef __CONFIG_THE_ISA_HH__ 3785742Snate@binkert.org#define __CONFIG_THE_ISA_HH__ 3797722Sgblack@eecs.umich.edu 3804773Snate@binkert.org''') 3816108Snate@binkert.org 3821858SN/A # create defines for the preprocessing and compile-time determination 3831085SN/A for i,isa in enumerate(isas): 3846658Snate@binkert.org code('#define $0 $1', define(isa), i + 1) 3856658Snate@binkert.org code() 3867673Snate@binkert.org 3876658Snate@binkert.org # create an enum for any run-time determination of the ISA, we 3886658Snate@binkert.org # reuse the same name as the namespaces 38911308Santhony.gutierrez@amd.com code('enum class Arch {') 3906658Snate@binkert.org for i,isa in enumerate(isas): 39111308Santhony.gutierrez@amd.com if i + 1 == len(isas): 3926658Snate@binkert.org code(' $0 = $1', namespace(isa), define(isa)) 3936658Snate@binkert.org else: 3947673Snate@binkert.org code(' $0 = $1,', namespace(isa), define(isa)) 3957673Snate@binkert.org code('};') 3967673Snate@binkert.org 3977673Snate@binkert.org code(''' 3987673Snate@binkert.org 3997673Snate@binkert.org#define THE_ISA ${{define(target_isa)}} 4007673Snate@binkert.org#define TheISA ${{namespace(target_isa)}} 40110467Sandreas.hansson@arm.com#define THE_ISA_STR "${{target_isa}}" 4026658Snate@binkert.org 4037673Snate@binkert.org#endif // __CONFIG_THE_ISA_HH__''') 40410467Sandreas.hansson@arm.com 40510467Sandreas.hansson@arm.com code.write(str(target[0])) 40610467Sandreas.hansson@arm.com 40710467Sandreas.hansson@arm.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 40810467Sandreas.hansson@arm.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 40910467Sandreas.hansson@arm.com 41010467Sandreas.hansson@arm.com######################################################################## 41110467Sandreas.hansson@arm.com# 41210467Sandreas.hansson@arm.com# Prevent any SimObjects from being added after this point, they 41310467Sandreas.hansson@arm.com# should all have been added in the SConscripts above 41410467Sandreas.hansson@arm.com# 4157673Snate@binkert.orgSimObject.fixed = True 4167673Snate@binkert.org 4177673Snate@binkert.orgclass DictImporter(object): 4187673Snate@binkert.org '''This importer takes a dictionary of arbitrary module names that 4197673Snate@binkert.org map to arbitrary filenames.''' 4209048SAli.Saidi@ARM.com def __init__(self, modules): 4217673Snate@binkert.org self.modules = modules 4227673Snate@binkert.org self.installed = set() 4237673Snate@binkert.org 4247673Snate@binkert.org def __del__(self): 4256658Snate@binkert.org self.unload() 4267756SAli.Saidi@ARM.com 4277816Ssteve.reinhardt@amd.com def unload(self): 4286658Snate@binkert.org import sys 42911308Santhony.gutierrez@amd.com for module in self.installed: 43011308Santhony.gutierrez@amd.com del sys.modules[module] 43111308Santhony.gutierrez@amd.com self.installed = set() 43211308Santhony.gutierrez@amd.com 43311308Santhony.gutierrez@amd.com def find_module(self, fullname, path): 43411308Santhony.gutierrez@amd.com if fullname == 'm5.defines': 43511308Santhony.gutierrez@amd.com return self 43611308Santhony.gutierrez@amd.com 43711308Santhony.gutierrez@amd.com if fullname == 'm5.objects': 43811308Santhony.gutierrez@amd.com return self 43911308Santhony.gutierrez@amd.com 44011308Santhony.gutierrez@amd.com if fullname.startswith('m5.internal'): 44111308Santhony.gutierrez@amd.com return None 44211308Santhony.gutierrez@amd.com 44311308Santhony.gutierrez@amd.com source = self.modules.get(fullname, None) 44411308Santhony.gutierrez@amd.com if source is not None and fullname.startswith('m5.objects'): 44511308Santhony.gutierrez@amd.com return self 44611308Santhony.gutierrez@amd.com 44711308Santhony.gutierrez@amd.com return None 44811308Santhony.gutierrez@amd.com 44911308Santhony.gutierrez@amd.com def load_module(self, fullname): 45011308Santhony.gutierrez@amd.com mod = imp.new_module(fullname) 45111308Santhony.gutierrez@amd.com sys.modules[fullname] = mod 45211308Santhony.gutierrez@amd.com self.installed.add(fullname) 45311308Santhony.gutierrez@amd.com 45411308Santhony.gutierrez@amd.com mod.__loader__ = self 45511308Santhony.gutierrez@amd.com if fullname == 'm5.objects': 45611308Santhony.gutierrez@amd.com mod.__path__ = fullname.split('.') 45711308Santhony.gutierrez@amd.com return mod 45811308Santhony.gutierrez@amd.com 45911308Santhony.gutierrez@amd.com if fullname == 'm5.defines': 46011308Santhony.gutierrez@amd.com mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 46111308Santhony.gutierrez@amd.com return mod 46211308Santhony.gutierrez@amd.com 46311308Santhony.gutierrez@amd.com source = self.modules[fullname] 46411308Santhony.gutierrez@amd.com if source.modname == '__init__': 46511308Santhony.gutierrez@amd.com mod.__path__ = source.modpath 46611308Santhony.gutierrez@amd.com mod.__file__ = source.abspath 46711308Santhony.gutierrez@amd.com 46811308Santhony.gutierrez@amd.com exec file(source.abspath, 'r') in mod.__dict__ 46911308Santhony.gutierrez@amd.com 47011308Santhony.gutierrez@amd.com return mod 47111308Santhony.gutierrez@amd.com 47211308Santhony.gutierrez@amd.comimport m5.SimObject 47311308Santhony.gutierrez@amd.comimport m5.params 4744382Sbinkertn@umich.edufrom m5.util import code_formatter 4754382Sbinkertn@umich.edu 4764762Snate@binkert.orgm5.SimObject.clear() 4774762Snate@binkert.orgm5.params.clear() 4784762Snate@binkert.org 4796654Snate@binkert.org# install the python importer so we can grab stuff from the source 4806654Snate@binkert.org# tree itself. We can't have SimObjects added after this point or 4815517Snate@binkert.org# else we won't know about them for the rest of the stuff. 4825517Snate@binkert.orgimporter = DictImporter(PySource.modules) 4835517Snate@binkert.orgsys.meta_path[0:0] = [ importer ] 4845517Snate@binkert.org 4855517Snate@binkert.org# import all sim objects so we can populate the all_objects list 4865517Snate@binkert.org# make sure that we're working with a list, then let's sort it 4875517Snate@binkert.orgfor modname in SimObject.modnames: 4885517Snate@binkert.org exec('from m5.objects import %s' % modname) 4895517Snate@binkert.org 4905517Snate@binkert.org# we need to unload all of the currently imported modules so that they 4915517Snate@binkert.org# will be re-imported the next time the sconscript is run 4925517Snate@binkert.orgimporter.unload() 4935517Snate@binkert.orgsys.meta_path.remove(importer) 4945517Snate@binkert.org 4955517Snate@binkert.orgsim_objects = m5.SimObject.allClasses 4965517Snate@binkert.orgall_enums = m5.params.allEnums 4975517Snate@binkert.org 4986654Snate@binkert.orgif m5.SimObject.noCxxHeader: 4995517Snate@binkert.org print >> sys.stderr, \ 5005517Snate@binkert.org "warning: At least one SimObject lacks a header specification. " \ 5015517Snate@binkert.org "This can cause unexpected results in the generated SWIG " \ 5025517Snate@binkert.org "wrappers." 5035517Snate@binkert.org 50411802Sandreas.sandberg@arm.com# Find param types that need to be explicitly wrapped with swig. 5055517Snate@binkert.org# These will be recognized because the ParamDesc will have a 5065517Snate@binkert.org# swig_decl() method. Most param types are based on types that don't 5076143Snate@binkert.org# need this, either because they're based on native types (like Int) 5086654Snate@binkert.org# or because they're SimObjects (which get swigged independently). 5095517Snate@binkert.org# For now the only things handled here are VectorParam types. 5105517Snate@binkert.orgparams_to_swig = {} 5115517Snate@binkert.orgfor name,obj in sorted(sim_objects.iteritems()): 5125517Snate@binkert.org for param in obj._params.local.values(): 5135517Snate@binkert.org # load the ptype attribute now because it depends on the 5145517Snate@binkert.org # current version of SimObject.allClasses, but when scons 5155517Snate@binkert.org # actually uses the value, all versions of 5165517Snate@binkert.org # SimObject.allClasses will have been loaded 5175517Snate@binkert.org param.ptype 5185517Snate@binkert.org 5195517Snate@binkert.org if not hasattr(param, 'swig_decl'): 5205517Snate@binkert.org continue 5215517Snate@binkert.org pname = param.ptype_str 5225517Snate@binkert.org if pname not in params_to_swig: 5236654Snate@binkert.org params_to_swig[pname] = param 5246654Snate@binkert.org 5255517Snate@binkert.org######################################################################## 5265517Snate@binkert.org# 5276143Snate@binkert.org# calculate extra dependencies 5286143Snate@binkert.org# 5296143Snate@binkert.orgmodule_depends = ["m5", "m5.SimObject", "m5.params"] 5306727Ssteve.reinhardt@amd.comdepends = [ PySource.modules[dep].snode for dep in module_depends ] 5315517Snate@binkert.orgdepends.sort(key = lambda x: x.name) 5326727Ssteve.reinhardt@amd.com 5335517Snate@binkert.org######################################################################## 5345517Snate@binkert.org# 5355517Snate@binkert.org# Commands for the basic automatically generated python files 5366654Snate@binkert.org# 5376654Snate@binkert.org 5387673Snate@binkert.org# Generate Python file containing a dict specifying the current 5396654Snate@binkert.org# buildEnv flags. 5406654Snate@binkert.orgdef makeDefinesPyFile(target, source, env): 5416654Snate@binkert.org build_env = source[0].get_contents() 5426654Snate@binkert.org 5435517Snate@binkert.org code = code_formatter() 5445517Snate@binkert.org code(""" 5455517Snate@binkert.orgimport m5.internal 5466143Snate@binkert.orgimport m5.util 5475517Snate@binkert.org 5484762Snate@binkert.orgbuildEnv = m5.util.SmartDict($build_env) 5495517Snate@binkert.org 5505517Snate@binkert.orgcompileDate = m5.internal.core.compileDate 5516143Snate@binkert.org_globals = globals() 5526143Snate@binkert.orgfor key,val in m5.internal.core.__dict__.iteritems(): 5535517Snate@binkert.org if key.startswith('flag_'): 5545517Snate@binkert.org flag = key[5:] 5555517Snate@binkert.org _globals[flag] = val 5565517Snate@binkert.orgdel _globals 5575517Snate@binkert.org""") 5585517Snate@binkert.org code.write(target[0].abspath) 5595517Snate@binkert.org 5605517Snate@binkert.orgdefines_info = Value(build_env) 5615517Snate@binkert.org# Generate a file with all of the compile options in it 5629338SAndreas.Sandberg@arm.comenv.Command('python/m5/defines.py', defines_info, 5639338SAndreas.Sandberg@arm.com MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 5649338SAndreas.Sandberg@arm.comPySource('m5', 'python/m5/defines.py') 5659338SAndreas.Sandberg@arm.com 5669338SAndreas.Sandberg@arm.com# Generate python file containing info about the M5 source code 5679338SAndreas.Sandberg@arm.comdef makeInfoPyFile(target, source, env): 5688596Ssteve.reinhardt@amd.com code = code_formatter() 5698596Ssteve.reinhardt@amd.com for src in source: 5708596Ssteve.reinhardt@amd.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 5718596Ssteve.reinhardt@amd.com code('$src = ${{repr(data)}}') 5728596Ssteve.reinhardt@amd.com code.write(str(target[0])) 5738596Ssteve.reinhardt@amd.com 5748596Ssteve.reinhardt@amd.com# Generate a file that wraps the basic top level files 5756143Snate@binkert.orgenv.Command('python/m5/info.py', 5765517Snate@binkert.org [ '#/COPYING', '#/LICENSE', '#/README', ], 5776654Snate@binkert.org MakeAction(makeInfoPyFile, Transform("INFO"))) 5786654Snate@binkert.orgPySource('m5', 'python/m5/info.py') 5796654Snate@binkert.org 5806654Snate@binkert.org######################################################################## 5816654Snate@binkert.org# 5826654Snate@binkert.org# Create all of the SimObject param headers and enum headers 5835517Snate@binkert.org# 5845517Snate@binkert.org 5855517Snate@binkert.orgdef createSimObjectParamStruct(target, source, env): 5868596Ssteve.reinhardt@amd.com assert len(target) == 1 and len(source) == 1 5878596Ssteve.reinhardt@amd.com 5884762Snate@binkert.org name = str(source[0].get_contents()) 5894762Snate@binkert.org obj = sim_objects[name] 5904762Snate@binkert.org 5914762Snate@binkert.org code = code_formatter() 5924762Snate@binkert.org obj.cxx_param_decl(code) 5934762Snate@binkert.org code.write(target[0].abspath) 5947675Snate@binkert.org 59510584Sandreas.hansson@arm.comdef createSimObjectCxxConfig(is_header): 5964762Snate@binkert.org def body(target, source, env): 5974762Snate@binkert.org assert len(target) == 1 and len(source) == 1 5984762Snate@binkert.org 5994762Snate@binkert.org name = str(source[0].get_contents()) 6004382Sbinkertn@umich.edu obj = sim_objects[name] 6014382Sbinkertn@umich.edu 6025517Snate@binkert.org code = code_formatter() 6036654Snate@binkert.org obj.cxx_config_param_file(code, is_header) 6045517Snate@binkert.org code.write(target[0].abspath) 6058126Sgblack@eecs.umich.edu return body 6066654Snate@binkert.org 6077673Snate@binkert.orgdef createParamSwigWrapper(target, source, env): 6086654Snate@binkert.org assert len(target) == 1 and len(source) == 1 60911802Sandreas.sandberg@arm.com 6106654Snate@binkert.org name = str(source[0].get_contents()) 6116654Snate@binkert.org param = params_to_swig[name] 6126654Snate@binkert.org 6136654Snate@binkert.org code = code_formatter() 61411802Sandreas.sandberg@arm.com param.swig_decl(code) 6156669Snate@binkert.org code.write(target[0].abspath) 61611802Sandreas.sandberg@arm.com 6176669Snate@binkert.orgdef createEnumStrings(target, source, env): 6186669Snate@binkert.org assert len(target) == 1 and len(source) == 1 6196669Snate@binkert.org 6206669Snate@binkert.org name = str(source[0].get_contents()) 6216654Snate@binkert.org obj = all_enums[name] 6227673Snate@binkert.org 6235517Snate@binkert.org code = code_formatter() 6248126Sgblack@eecs.umich.edu obj.cxx_def(code) 6255798Snate@binkert.org code.write(target[0].abspath) 6267756SAli.Saidi@ARM.com 6277816Ssteve.reinhardt@amd.comdef createEnumDecls(target, source, env): 6285798Snate@binkert.org assert len(target) == 1 and len(source) == 1 6295798Snate@binkert.org 6305517Snate@binkert.org name = str(source[0].get_contents()) 6315517Snate@binkert.org obj = all_enums[name] 6327673Snate@binkert.org 6335517Snate@binkert.org code = code_formatter() 6345517Snate@binkert.org obj.cxx_decl(code) 6357673Snate@binkert.org code.write(target[0].abspath) 6367673Snate@binkert.org 6375517Snate@binkert.orgdef createEnumSwigWrapper(target, source, env): 6385798Snate@binkert.org assert len(target) == 1 and len(source) == 1 6395798Snate@binkert.org 6408333Snate@binkert.org name = str(source[0].get_contents()) 6417816Ssteve.reinhardt@amd.com obj = all_enums[name] 6425798Snate@binkert.org 6435798Snate@binkert.org code = code_formatter() 6444762Snate@binkert.org obj.swig_decl(code) 6454762Snate@binkert.org code.write(target[0].abspath) 6464762Snate@binkert.org 6474762Snate@binkert.orgdef createSimObjectSwigWrapper(target, source, env): 6484762Snate@binkert.org name = source[0].get_contents() 6498596Ssteve.reinhardt@amd.com obj = sim_objects[name] 6505517Snate@binkert.org 6515517Snate@binkert.org code = code_formatter() 6525517Snate@binkert.org obj.swig_decl(code) 6535517Snate@binkert.org code.write(target[0].abspath) 6545517Snate@binkert.org 6557673Snate@binkert.org# dummy target for generated code 6568596Ssteve.reinhardt@amd.com# we start out with all the Source files so they get copied to build/*/ also. 6577673Snate@binkert.orgSWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 6585517Snate@binkert.org 65910458Sandreas.hansson@arm.com# Generate all of the SimObject param C++ struct header files 66010458Sandreas.hansson@arm.comparams_hh_files = [] 66110458Sandreas.hansson@arm.comfor name,simobj in sorted(sim_objects.iteritems()): 66210458Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 66310458Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 66410458Sandreas.hansson@arm.com 66510458Sandreas.hansson@arm.com hh_file = File('params/%s.hh' % name) 66610458Sandreas.hansson@arm.com params_hh_files.append(hh_file) 66710458Sandreas.hansson@arm.com env.Command(hh_file, Value(name), 66810458Sandreas.hansson@arm.com MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 66910458Sandreas.hansson@arm.com env.Depends(hh_file, depends + extra_deps) 67010458Sandreas.hansson@arm.com env.Depends(SWIG, hh_file) 6718596Ssteve.reinhardt@amd.com 6725517Snate@binkert.org# C++ parameter description files 6735517Snate@binkert.orgif GetOption('with_cxx_config'): 6745517Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 6758596Ssteve.reinhardt@amd.com py_source = PySource.modules[simobj.__module__] 6765517Snate@binkert.org extra_deps = [ py_source.tnode ] 6777673Snate@binkert.org 6787673Snate@binkert.org cxx_config_hh_file = File('cxx_config/%s.hh' % name) 6797673Snate@binkert.org cxx_config_cc_file = File('cxx_config/%s.cc' % name) 6805517Snate@binkert.org env.Command(cxx_config_hh_file, Value(name), 6815517Snate@binkert.org MakeAction(createSimObjectCxxConfig(True), 6825517Snate@binkert.org Transform("CXXCPRHH"))) 6835517Snate@binkert.org env.Command(cxx_config_cc_file, Value(name), 6845517Snate@binkert.org MakeAction(createSimObjectCxxConfig(False), 6855517Snate@binkert.org Transform("CXXCPRCC"))) 6865517Snate@binkert.org env.Depends(cxx_config_hh_file, depends + extra_deps + 6877673Snate@binkert.org [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 6887673Snate@binkert.org env.Depends(cxx_config_cc_file, depends + extra_deps + 6897673Snate@binkert.org [cxx_config_hh_file]) 6905517Snate@binkert.org Source(cxx_config_cc_file) 6918596Ssteve.reinhardt@amd.com 6925517Snate@binkert.org cxx_config_init_cc_file = File('cxx_config/init.cc') 6935517Snate@binkert.org 6945517Snate@binkert.org def createCxxConfigInitCC(target, source, env): 6955517Snate@binkert.org assert len(target) == 1 and len(source) == 1 6965517Snate@binkert.org 6977673Snate@binkert.org code = code_formatter() 6987673Snate@binkert.org 6997673Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 7005517Snate@binkert.org if not hasattr(simobj, 'abstract') or not simobj.abstract: 7018596Ssteve.reinhardt@amd.com code('#include "cxx_config/${name}.hh"') 7027675Snate@binkert.org code() 7037675Snate@binkert.org code('void cxxConfigInit()') 7047675Snate@binkert.org code('{') 7057675Snate@binkert.org code.indent() 7067675Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 7077675Snate@binkert.org not_abstract = not hasattr(simobj, 'abstract') or \ 7088596Ssteve.reinhardt@amd.com not simobj.abstract 7097675Snate@binkert.org if not_abstract and 'type' in simobj.__dict__: 7107675Snate@binkert.org code('cxx_config_directory["${name}"] = ' 7118596Ssteve.reinhardt@amd.com '${name}CxxConfigParams::makeDirectoryEntry();') 7128596Ssteve.reinhardt@amd.com code.dedent() 7138596Ssteve.reinhardt@amd.com code('}') 7148596Ssteve.reinhardt@amd.com code.write(target[0].abspath) 7158596Ssteve.reinhardt@amd.com 7168596Ssteve.reinhardt@amd.com py_source = PySource.modules[simobj.__module__] 7178596Ssteve.reinhardt@amd.com extra_deps = [ py_source.tnode ] 7188596Ssteve.reinhardt@amd.com env.Command(cxx_config_init_cc_file, Value(name), 71910454SCurtis.Dunham@arm.com MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 72010454SCurtis.Dunham@arm.com cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 72110454SCurtis.Dunham@arm.com for name,simobj in sorted(sim_objects.iteritems()) 72210454SCurtis.Dunham@arm.com if not hasattr(simobj, 'abstract') or not simobj.abstract] 7238596Ssteve.reinhardt@amd.com Depends(cxx_config_init_cc_file, cxx_param_hh_files + 7244762Snate@binkert.org [File('sim/cxx_config.hh')]) 7256143Snate@binkert.org Source(cxx_config_init_cc_file) 7266143Snate@binkert.org 7276143Snate@binkert.org# Generate any needed param SWIG wrapper files 7284762Snate@binkert.orgparams_i_files = [] 7294762Snate@binkert.orgfor name,param in sorted(params_to_swig.iteritems()): 7304762Snate@binkert.org i_file = File('python/m5/internal/%s.i' % (param.swig_module_name())) 7317756SAli.Saidi@ARM.com params_i_files.append(i_file) 7328596Ssteve.reinhardt@amd.com env.Command(i_file, Value(name), 7334762Snate@binkert.org MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 73410454SCurtis.Dunham@arm.com env.Depends(i_file, depends) 7354762Snate@binkert.org env.Depends(SWIG, i_file) 73610458Sandreas.hansson@arm.com SwigSource('m5.internal', i_file) 73710458Sandreas.hansson@arm.com 73810458Sandreas.hansson@arm.com# Generate all enum header files 73910458Sandreas.hansson@arm.comfor name,enum in sorted(all_enums.iteritems()): 74010458Sandreas.hansson@arm.com py_source = PySource.modules[enum.__module__] 74110458Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 74210458Sandreas.hansson@arm.com 74310458Sandreas.hansson@arm.com cc_file = File('enums/%s.cc' % name) 74410458Sandreas.hansson@arm.com env.Command(cc_file, Value(name), 74510458Sandreas.hansson@arm.com MakeAction(createEnumStrings, Transform("ENUM STR"))) 74610458Sandreas.hansson@arm.com env.Depends(cc_file, depends + extra_deps) 74710458Sandreas.hansson@arm.com env.Depends(SWIG, cc_file) 74810458Sandreas.hansson@arm.com Source(cc_file) 74910458Sandreas.hansson@arm.com 75010458Sandreas.hansson@arm.com hh_file = File('enums/%s.hh' % name) 75110458Sandreas.hansson@arm.com env.Command(hh_file, Value(name), 75210458Sandreas.hansson@arm.com MakeAction(createEnumDecls, Transform("ENUMDECL"))) 75310458Sandreas.hansson@arm.com env.Depends(hh_file, depends + extra_deps) 75410458Sandreas.hansson@arm.com env.Depends(SWIG, hh_file) 75510458Sandreas.hansson@arm.com 75610458Sandreas.hansson@arm.com i_file = File('python/m5/internal/enum_%s.i' % name) 75710458Sandreas.hansson@arm.com env.Command(i_file, Value(name), 75810458Sandreas.hansson@arm.com MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 75910458Sandreas.hansson@arm.com env.Depends(i_file, depends + extra_deps) 76010458Sandreas.hansson@arm.com env.Depends(SWIG, i_file) 76110458Sandreas.hansson@arm.com SwigSource('m5.internal', i_file) 76210458Sandreas.hansson@arm.com 76310458Sandreas.hansson@arm.com# Generate SimObject SWIG wrapper files 76410458Sandreas.hansson@arm.comfor name,simobj in sorted(sim_objects.iteritems()): 76510458Sandreas.hansson@arm.com py_source = PySource.modules[simobj.__module__] 76610458Sandreas.hansson@arm.com extra_deps = [ py_source.tnode ] 76710458Sandreas.hansson@arm.com i_file = File('python/m5/internal/param_%s.i' % name) 76810458Sandreas.hansson@arm.com env.Command(i_file, Value(name), 76910458Sandreas.hansson@arm.com MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 77010458Sandreas.hansson@arm.com env.Depends(i_file, depends + extra_deps) 77110458Sandreas.hansson@arm.com SwigSource('m5.internal', i_file) 77210458Sandreas.hansson@arm.com 77310458Sandreas.hansson@arm.com# Generate the main swig init file 77410458Sandreas.hansson@arm.comdef makeEmbeddedSwigInit(target, source, env): 77510458Sandreas.hansson@arm.com code = code_formatter() 77610458Sandreas.hansson@arm.com module = source[0].get_contents() 77710458Sandreas.hansson@arm.com code('''\ 77810458Sandreas.hansson@arm.com#include "sim/init.hh" 77910458Sandreas.hansson@arm.com 78010458Sandreas.hansson@arm.comextern "C" { 78110458Sandreas.hansson@arm.com void init_${module}(); 78210458Sandreas.hansson@arm.com} 78310458Sandreas.hansson@arm.com 78410458Sandreas.hansson@arm.comEmbeddedSwig embed_swig_${module}(init_${module}); 78510584Sandreas.hansson@arm.com''') 78610458Sandreas.hansson@arm.com code.write(str(target[0])) 78710458Sandreas.hansson@arm.com 78810458Sandreas.hansson@arm.com# Build all swig modules 78910458Sandreas.hansson@arm.comfor swig in SwigSource.all: 79010458Sandreas.hansson@arm.com env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 7918596Ssteve.reinhardt@amd.com MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 7925463Snate@binkert.org '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 79310584Sandreas.hansson@arm.com cc_file = str(swig.tnode) 79411802Sandreas.sandberg@arm.com init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 7955463Snate@binkert.org env.Command(init_file, Value(swig.module), 7967756SAli.Saidi@ARM.com MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) 7978596Ssteve.reinhardt@amd.com env.Depends(SWIG, init_file) 7984762Snate@binkert.org Source(init_file, **swig.guards) 79910454SCurtis.Dunham@arm.com 80011802Sandreas.sandberg@arm.com# Build all protocol buffers if we have got protoc and protobuf available 8014762Snate@binkert.orgif env['HAVE_PROTOBUF']: 8024762Snate@binkert.org for proto in ProtoBuf.all: 8036143Snate@binkert.org # Use both the source and header as the target, and the .proto 8046143Snate@binkert.org # file as the source. When executing the protoc compiler, also 8056143Snate@binkert.org # specify the proto_path to avoid having the generated files 8064762Snate@binkert.org # include the path. 8074762Snate@binkert.org env.Command([proto.cc_file, proto.hh_file], proto.tnode, 8087756SAli.Saidi@ARM.com MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 8097816Ssteve.reinhardt@amd.com '--proto_path ${SOURCE.dir} $SOURCE', 8104762Snate@binkert.org Transform("PROTOC"))) 81110454SCurtis.Dunham@arm.com 8124762Snate@binkert.org env.Depends(SWIG, [proto.cc_file, proto.hh_file]) 8134762Snate@binkert.org # Add the C++ source file 8144762Snate@binkert.org Source(proto.cc_file, **proto.guards) 8157756SAli.Saidi@ARM.comelif ProtoBuf.all: 8168596Ssteve.reinhardt@amd.com print 'Got protobuf to build, but lacks support!' 8174762Snate@binkert.org Exit(1) 81810454SCurtis.Dunham@arm.com 8194762Snate@binkert.org# 82011802Sandreas.sandberg@arm.com# Handle debug flags 8217756SAli.Saidi@ARM.com# 8228596Ssteve.reinhardt@amd.comdef makeDebugFlagCC(target, source, env): 8237675Snate@binkert.org assert(len(target) == 1 and len(source) == 1) 82410454SCurtis.Dunham@arm.com 82511802Sandreas.sandberg@arm.com code = code_formatter() 8265517Snate@binkert.org 8278596Ssteve.reinhardt@amd.com # delay definition of CompoundFlags until after all the definition 82810584Sandreas.hansson@arm.com # of all constituent SimpleFlags 8299248SAndreas.Sandberg@arm.com comp_code = code_formatter() 8309248SAndreas.Sandberg@arm.com 83111802Sandreas.sandberg@arm.com # file header 8328596Ssteve.reinhardt@amd.com code(''' 8338596Ssteve.reinhardt@amd.com/* 8349248SAndreas.Sandberg@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 83511802Sandreas.sandberg@arm.com */ 8364762Snate@binkert.org 8377674Snate@binkert.org#include "base/debug.hh" 83811548Sandreas.hansson@arm.com 83911548Sandreas.hansson@arm.comnamespace Debug { 84011548Sandreas.hansson@arm.com 8417674Snate@binkert.org''') 84211548Sandreas.hansson@arm.com 84311548Sandreas.hansson@arm.com for name, flag in sorted(source[0].read().iteritems()): 84411548Sandreas.hansson@arm.com n, compound, desc = flag 84511548Sandreas.hansson@arm.com assert n == name 84611548Sandreas.hansson@arm.com 84711548Sandreas.hansson@arm.com if not compound: 84811548Sandreas.hansson@arm.com code('SimpleFlag $name("$name", "$desc");') 84911548Sandreas.hansson@arm.com else: 8507674Snate@binkert.org comp_code('CompoundFlag $name("$name", "$desc",') 85111548Sandreas.hansson@arm.com comp_code.indent() 85211548Sandreas.hansson@arm.com last = len(compound) - 1 85311548Sandreas.hansson@arm.com for i,flag in enumerate(compound): 85411548Sandreas.hansson@arm.com if i != last: 85511548Sandreas.hansson@arm.com comp_code('$flag,') 85611548Sandreas.hansson@arm.com else: 85711548Sandreas.hansson@arm.com comp_code('$flag);') 85811548Sandreas.hansson@arm.com comp_code.dedent() 85911308Santhony.gutierrez@amd.com 8604762Snate@binkert.org code.append(comp_code) 8616143Snate@binkert.org code() 8626143Snate@binkert.org code('} // namespace Debug') 8637756SAli.Saidi@ARM.com 8647816Ssteve.reinhardt@amd.com code.write(str(target[0])) 8658235Snate@binkert.org 8668596Ssteve.reinhardt@amd.comdef makeDebugFlagHH(target, source, env): 8677756SAli.Saidi@ARM.com assert(len(target) == 1 and len(source) == 1) 86811548Sandreas.hansson@arm.com 86911548Sandreas.hansson@arm.com val = eval(source[0].get_contents()) 87010454SCurtis.Dunham@arm.com name, compound, desc = val 8718235Snate@binkert.org 8724382Sbinkertn@umich.edu code = code_formatter() 8739396Sandreas.hansson@arm.com 8749396Sandreas.hansson@arm.com # file header boilerplate 8759396Sandreas.hansson@arm.com code('''\ 8769396Sandreas.hansson@arm.com/* 8779396Sandreas.hansson@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 8789396Sandreas.hansson@arm.com */ 8799396Sandreas.hansson@arm.com 8809396Sandreas.hansson@arm.com#ifndef __DEBUG_${name}_HH__ 8819396Sandreas.hansson@arm.com#define __DEBUG_${name}_HH__ 8829396Sandreas.hansson@arm.com 8839396Sandreas.hansson@arm.comnamespace Debug { 8849396Sandreas.hansson@arm.com''') 88510454SCurtis.Dunham@arm.com 8869396Sandreas.hansson@arm.com if compound: 8879396Sandreas.hansson@arm.com code('class CompoundFlag;') 8889396Sandreas.hansson@arm.com code('class SimpleFlag;') 8899396Sandreas.hansson@arm.com 8909396Sandreas.hansson@arm.com if compound: 8919396Sandreas.hansson@arm.com code('extern CompoundFlag $name;') 8928232Snate@binkert.org for flag in compound: 8938232Snate@binkert.org code('extern SimpleFlag $flag;') 8948232Snate@binkert.org else: 8958232Snate@binkert.org code('extern SimpleFlag $name;') 8968232Snate@binkert.org 8976229Snate@binkert.org code(''' 89810455SCurtis.Dunham@arm.com} 8996229Snate@binkert.org 90010455SCurtis.Dunham@arm.com#endif // __DEBUG_${name}_HH__ 90110455SCurtis.Dunham@arm.com''') 90210455SCurtis.Dunham@arm.com 9035517Snate@binkert.org code.write(str(target[0])) 9045517Snate@binkert.org 9057673Snate@binkert.orgfor name,flag in sorted(debug_flags.iteritems()): 9065517Snate@binkert.org n, compound, desc = flag 90710455SCurtis.Dunham@arm.com assert n == name 9085517Snate@binkert.org 9095517Snate@binkert.org hh_file = 'debug/%s.hh' % name 9108232Snate@binkert.org env.Command(hh_file, Value(flag), 91110455SCurtis.Dunham@arm.com MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 91210455SCurtis.Dunham@arm.com env.Depends(SWIG, hh_file) 91310455SCurtis.Dunham@arm.com 9147673Snate@binkert.orgenv.Command('debug/flags.cc', Value(debug_flags), 9157673Snate@binkert.org MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 91610455SCurtis.Dunham@arm.comenv.Depends(SWIG, 'debug/flags.cc') 91710455SCurtis.Dunham@arm.comSource('debug/flags.cc') 91810455SCurtis.Dunham@arm.com 9195517Snate@binkert.org# Embed python files. All .py files that have been indicated by a 92010455SCurtis.Dunham@arm.com# PySource() call in a SConscript need to be embedded into the M5 92110455SCurtis.Dunham@arm.com# library. To do that, we compile the file to byte code, marshal the 92210455SCurtis.Dunham@arm.com# byte code, compress it, and then generate a c++ file that 92310455SCurtis.Dunham@arm.com# inserts the result into an array. 92410455SCurtis.Dunham@arm.comdef embedPyFile(target, source, env): 92510455SCurtis.Dunham@arm.com def c_str(string): 92610455SCurtis.Dunham@arm.com if string is None: 92710455SCurtis.Dunham@arm.com return "0" 92810685Sandreas.hansson@arm.com return '"%s"' % string 92910455SCurtis.Dunham@arm.com 93010685Sandreas.hansson@arm.com '''Action function to compile a .py into a code object, marshal 93110455SCurtis.Dunham@arm.com it, compress it, and stick it into an asm file so the code appears 9325517Snate@binkert.org as just bytes with a label in the data section''' 93310455SCurtis.Dunham@arm.com 9348232Snate@binkert.org src = file(str(source[0]), 'r').read() 9358232Snate@binkert.org 9365517Snate@binkert.org pysource = PySource.tnodes[source[0]] 9377673Snate@binkert.org compiled = compile(src, pysource.abspath, 'exec') 9385517Snate@binkert.org marshalled = marshal.dumps(compiled) 9398232Snate@binkert.org compressed = zlib.compress(marshalled) 9408232Snate@binkert.org data = compressed 9415517Snate@binkert.org sym = pysource.symname 9428232Snate@binkert.org 9438232Snate@binkert.org code = code_formatter() 9448232Snate@binkert.org code('''\ 9457673Snate@binkert.org#include "sim/init.hh" 9465517Snate@binkert.org 9475517Snate@binkert.orgnamespace { 9487673Snate@binkert.org 9495517Snate@binkert.orgconst uint8_t data_${sym}[] = { 95010455SCurtis.Dunham@arm.com''') 9515517Snate@binkert.org code.indent() 9525517Snate@binkert.org step = 16 9538232Snate@binkert.org for i in xrange(0, len(data), step): 9548232Snate@binkert.org x = array.array('B', data[i:i+step]) 9555517Snate@binkert.org code(''.join('%d,' % d for d in x)) 9568232Snate@binkert.org code.dedent() 9578232Snate@binkert.org 9585517Snate@binkert.org code('''}; 9598232Snate@binkert.org 9608232Snate@binkert.orgEmbeddedPython embedded_${sym}( 9618232Snate@binkert.org ${{c_str(pysource.arcname)}}, 9625517Snate@binkert.org ${{c_str(pysource.abspath)}}, 9638232Snate@binkert.org ${{c_str(pysource.modpath)}}, 9648232Snate@binkert.org data_${sym}, 9658232Snate@binkert.org ${{len(data)}}, 9668232Snate@binkert.org ${{len(marshalled)}}); 9678232Snate@binkert.org 9688232Snate@binkert.org} // anonymous namespace 9695517Snate@binkert.org''') 9708232Snate@binkert.org code.write(str(target[0])) 9718232Snate@binkert.org 9725517Snate@binkert.orgfor source in PySource.all: 9738232Snate@binkert.org env.Command(source.cpp, source.tnode, 9747673Snate@binkert.org MakeAction(embedPyFile, Transform("EMBED PY"))) 9755517Snate@binkert.org env.Depends(SWIG, source.cpp) 9767673Snate@binkert.org Source(source.cpp, skip_no_python=True) 9775517Snate@binkert.org 9788232Snate@binkert.org######################################################################## 9798232Snate@binkert.org# 9808232Snate@binkert.org# Define binaries. Each different build type (debug, opt, etc.) gets 9815192Ssaidi@eecs.umich.edu# a slightly different build environment. 98210454SCurtis.Dunham@arm.com# 98310454SCurtis.Dunham@arm.com 9848232Snate@binkert.org# List of constructed environments to pass back to SConstruct 98510455SCurtis.Dunham@arm.comdate_source = Source('base/date.cc', skip_lib=True) 98610455SCurtis.Dunham@arm.com 98710455SCurtis.Dunham@arm.com# Capture this directory for the closure makeEnv, otherwise when it is 98810455SCurtis.Dunham@arm.com# called, it won't know what directory it should use. 98910455SCurtis.Dunham@arm.comvariant_dir = Dir('.').path 99010455SCurtis.Dunham@arm.comdef variant(*path): 9915192Ssaidi@eecs.umich.edu return os.path.join(variant_dir, *path) 99211077SCurtis.Dunham@arm.comdef variantd(*path): 99311330SCurtis.Dunham@arm.com return variant(*path)+'/' 99411077SCurtis.Dunham@arm.com 99511077SCurtis.Dunham@arm.com# Function to create a new build environment as clone of current 99611077SCurtis.Dunham@arm.com# environment 'env' with modified object suffix and optional stripped 99711330SCurtis.Dunham@arm.com# binary. Additional keyword arguments are appended to corresponding 99811077SCurtis.Dunham@arm.com# build environment vars. 9997674Snate@binkert.orgdef makeEnv(env, label, objsfx, strip = False, **kwargs): 10005522Snate@binkert.org # SCons doesn't know to append a library suffix when there is a '.' in the 10015522Snate@binkert.org # name. Use '_' instead. 10027674Snate@binkert.org libname = variant('gem5_' + label) 10037674Snate@binkert.org exename = variant('gem5.' + label) 10047674Snate@binkert.org secondary_exename = variant('m5.' + label) 10057674Snate@binkert.org 10067674Snate@binkert.org new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 10077674Snate@binkert.org new_env.Label = label 10087674Snate@binkert.org new_env.Append(**kwargs) 10097674Snate@binkert.org 10105522Snate@binkert.org swig_env = new_env.Clone() 10115522Snate@binkert.org 10125522Snate@binkert.org # Both gcc and clang have issues with unused labels and values in 10135517Snate@binkert.org # the SWIG generated code 10145522Snate@binkert.org swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 10155517Snate@binkert.org 10166143Snate@binkert.org # Add additional warnings here that should not be applied to 10176727Ssteve.reinhardt@amd.com # the SWIG generated code 10185522Snate@binkert.org new_env.Append(CXXFLAGS='-Wmissing-declarations') 10195522Snate@binkert.org 10205522Snate@binkert.org if env['GCC']: 10217674Snate@binkert.org # Depending on the SWIG version, we also need to supress 10225517Snate@binkert.org # warnings about uninitialized variables and missing field 10237673Snate@binkert.org # initializers. 10247673Snate@binkert.org swig_env.Append(CCFLAGS=['-Wno-uninitialized', 10257674Snate@binkert.org '-Wno-missing-field-initializers', 10267673Snate@binkert.org '-Wno-unused-but-set-variable']) 10277674Snate@binkert.org 10287674Snate@binkert.org # If gcc supports it, also warn for deletion of derived 10298946Sandreas.hansson@arm.com # classes with non-virtual desctructors. For gcc >= 4.7 we 10307674Snate@binkert.org # also have to disable warnings about the SWIG code having 10317674Snate@binkert.org # potentially uninitialized variables. 10327674Snate@binkert.org if compareVersions(env['GCC_VERSION'], '4.7') >= 0: 10335522Snate@binkert.org new_env.Append(CXXFLAGS='-Wdelete-non-virtual-dtor') 10345522Snate@binkert.org swig_env.Append(CCFLAGS='-Wno-maybe-uninitialized') 10357674Snate@binkert.org 10367674Snate@binkert.org # Only gcc >= 4.9 supports UBSan, so check both the version 103711308Santhony.gutierrez@amd.com # and the command-line option before adding the compiler and 10387674Snate@binkert.org # linker flags. 10397673Snate@binkert.org if GetOption('with_ubsan') and \ 10407674Snate@binkert.org compareVersions(env['GCC_VERSION'], '4.9') >= 0: 10417674Snate@binkert.org new_env.Append(CCFLAGS='-fsanitize=undefined') 10427674Snate@binkert.org new_env.Append(LINKFLAGS='-fsanitize=undefined') 10437674Snate@binkert.org 10447674Snate@binkert.org if env['CLANG']: 10457674Snate@binkert.org # Always enable the warning for deletion of derived classes 10467674Snate@binkert.org # with non-virtual destructors 10477674Snate@binkert.org new_env.Append(CXXFLAGS=['-Wdelete-non-virtual-dtor']) 10487811Ssteve.reinhardt@amd.com 10497674Snate@binkert.org swig_env.Append(CCFLAGS=[ 10507673Snate@binkert.org # Some versions of SWIG can return uninitialized values 10515522Snate@binkert.org '-Wno-sometimes-uninitialized', 10526143Snate@binkert.org # Register storage is requested in a lot of places in 105310453SAndrew.Bardsley@arm.com # SWIG-generated code. 10547816Ssteve.reinhardt@amd.com '-Wno-deprecated-register', 105510454SCurtis.Dunham@arm.com ]) 105610453SAndrew.Bardsley@arm.com 10574382Sbinkertn@umich.edu # All supported clang versions have support for UBSan, so if 10584382Sbinkertn@umich.edu # asked to use it, append the compiler and linker flags. 10594382Sbinkertn@umich.edu if GetOption('with_ubsan'): 10604382Sbinkertn@umich.edu new_env.Append(CCFLAGS='-fsanitize=undefined') 10614382Sbinkertn@umich.edu new_env.Append(LINKFLAGS='-fsanitize=undefined') 10624382Sbinkertn@umich.edu 10634382Sbinkertn@umich.edu werror_env = new_env.Clone() 10644382Sbinkertn@umich.edu werror_env.Append(CCFLAGS='-Werror') 106510196SCurtis.Dunham@arm.com 10664382Sbinkertn@umich.edu def make_obj(source, static, extra_deps = None): 106710196SCurtis.Dunham@arm.com '''This function adds the specified source to the correct 106810196SCurtis.Dunham@arm.com build environment, and returns the corresponding SCons Object 106910196SCurtis.Dunham@arm.com nodes''' 107010196SCurtis.Dunham@arm.com 107110196SCurtis.Dunham@arm.com if source.swig: 107210196SCurtis.Dunham@arm.com env = swig_env 107310196SCurtis.Dunham@arm.com elif source.Werror: 1074955SN/A env = werror_env 10752655Sstever@eecs.umich.edu else: 10762655Sstever@eecs.umich.edu env = new_env 10772655Sstever@eecs.umich.edu 10782655Sstever@eecs.umich.edu if static: 107910196SCurtis.Dunham@arm.com obj = env.StaticObject(source.tnode) 10805601Snate@binkert.org else: 10815601Snate@binkert.org obj = env.SharedObject(source.tnode) 108210196SCurtis.Dunham@arm.com 108310196SCurtis.Dunham@arm.com if extra_deps: 108410196SCurtis.Dunham@arm.com env.Depends(obj, extra_deps) 10855522Snate@binkert.org 10865863Snate@binkert.org return obj 10875601Snate@binkert.org 10885601Snate@binkert.org lib_guards = {'main': False, 'skip_lib': False} 10895601Snate@binkert.org 10905863Snate@binkert.org # Without Python, leave out all SWIG and Python content from the 10919556Sandreas.hansson@arm.com # library builds. The option doesn't affect gem5 built as a program 10929556Sandreas.hansson@arm.com if GetOption('without_python'): 10939556Sandreas.hansson@arm.com lib_guards['skip_no_python'] = False 10949556Sandreas.hansson@arm.com 10959556Sandreas.hansson@arm.com static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] 10965559Snate@binkert.org shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] 10979556Sandreas.hansson@arm.com 10989618Ssteve.reinhardt@amd.com static_date = make_obj(date_source, static=True, extra_deps=static_objs) 10999618Ssteve.reinhardt@amd.com static_objs.append(static_date) 11009618Ssteve.reinhardt@amd.com 110110238Sandreas.hansson@arm.com shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 110210878Sandreas.hansson@arm.com shared_objs.append(shared_date) 110311294Sandreas.hansson@arm.com 110411294Sandreas.hansson@arm.com # First make a library of everything but main() so other programs can 110510457Sandreas.hansson@arm.com # link against m5. 110611718Sjoseph.gross@amd.com static_lib = new_env.StaticLibrary(libname, static_objs) 110711718Sjoseph.gross@amd.com shared_lib = new_env.SharedLibrary(libname, shared_objs) 110811718Sjoseph.gross@amd.com 110911718Sjoseph.gross@amd.com # Now link a stub with main() and the static library. 111011718Sjoseph.gross@amd.com main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 111111718Sjoseph.gross@amd.com 111211718Sjoseph.gross@amd.com for test in UnitTest.all: 111311718Sjoseph.gross@amd.com flags = { test.target : True } 111411718Sjoseph.gross@amd.com test_sources = Source.get(**flags) 111511718Sjoseph.gross@amd.com test_objs = [ make_obj(s, static=True) for s in test_sources ] 111611718Sjoseph.gross@amd.com if test.main: 111711718Sjoseph.gross@amd.com test_objs += main_objs 111810457Sandreas.hansson@arm.com path = variant('unittest/%s.%s' % (test.target, label)) 111910457Sandreas.hansson@arm.com new_env.Program(path, test_objs + static_objs) 112010457Sandreas.hansson@arm.com 112111718Sjoseph.gross@amd.com progname = exename 112210457Sandreas.hansson@arm.com if strip: 112310457Sandreas.hansson@arm.com progname += '.unstripped' 112410457Sandreas.hansson@arm.com 112510457Sandreas.hansson@arm.com targets = new_env.Program(progname, main_objs + static_objs) 112611342Sandreas.hansson@arm.com 11278737Skoansin.tan@gmail.com if strip: 112811294Sandreas.hansson@arm.com if sys.platform == 'sunos5': 112911294Sandreas.hansson@arm.com cmd = 'cp $SOURCE $TARGET; strip $TARGET' 113011294Sandreas.hansson@arm.com else: 113110278SAndreas.Sandberg@ARM.com cmd = 'strip $SOURCE -o $TARGET' 113211342Sandreas.hansson@arm.com targets = new_env.Command(exename, progname, 113311342Sandreas.hansson@arm.com MakeAction(cmd, Transform("STRIP"))) 113410457Sandreas.hansson@arm.com 113511718Sjoseph.gross@amd.com new_env.Command(secondary_exename, exename, 113611718Sjoseph.gross@amd.com MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 113711718Sjoseph.gross@amd.com 113811718Sjoseph.gross@amd.com new_env.M5Binary = targets[0] 113911718Sjoseph.gross@amd.com return new_env 114011718Sjoseph.gross@amd.com 114111718Sjoseph.gross@amd.com# Start out with the compiler flags common to all compilers, 114210457Sandreas.hansson@arm.com# i.e. they all use -g for opt and -g -pg for prof 114311718Sjoseph.gross@amd.comccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 114411500Sandreas.hansson@arm.com 'perf' : ['-g']} 114511500Sandreas.hansson@arm.com 114611342Sandreas.hansson@arm.com# Start out with the linker flags common to all linkers, i.e. -pg for 114711342Sandreas.hansson@arm.com# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 11488945Ssteve.reinhardt@amd.com# no-as-needed and as-needed as the binutils linker is too clever and 114910686SAndreas.Sandberg@ARM.com# simply doesn't link to the library otherwise. 115010686SAndreas.Sandberg@ARM.comldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 115110686SAndreas.Sandberg@ARM.com 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 115210686SAndreas.Sandberg@ARM.com 115310686SAndreas.Sandberg@ARM.com# For Link Time Optimization, the optimisation flags used to compile 115410686SAndreas.Sandberg@ARM.com# individual files are decoupled from those used at link time 11558945Ssteve.reinhardt@amd.com# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 11566143Snate@binkert.org# to also update the linker flags based on the target. 11576143Snate@binkert.orgif env['GCC']: 11586143Snate@binkert.org if sys.platform == 'sunos5': 11596143Snate@binkert.org ccflags['debug'] += ['-gstabs+'] 11606143Snate@binkert.org else: 11616143Snate@binkert.org ccflags['debug'] += ['-ggdb3'] 11626143Snate@binkert.org ldflags['debug'] += ['-O0'] 11638945Ssteve.reinhardt@amd.com # opt, fast, prof and perf all share the same cc flags, also add 11648945Ssteve.reinhardt@amd.com # the optimization to the ldflags as LTO defers the optimization 11656143Snate@binkert.org # to link time 11666143Snate@binkert.org for target in ['opt', 'fast', 'prof', 'perf']: 11676143Snate@binkert.org ccflags[target] += ['-O3'] 11686143Snate@binkert.org ldflags[target] += ['-O3'] 11696143Snate@binkert.org 11706143Snate@binkert.org ccflags['fast'] += env['LTO_CCFLAGS'] 11716143Snate@binkert.org ldflags['fast'] += env['LTO_LDFLAGS'] 11726143Snate@binkert.orgelif env['CLANG']: 11736143Snate@binkert.org ccflags['debug'] += ['-g', '-O0'] 11746143Snate@binkert.org # opt, fast, prof and perf all share the same cc flags 11756143Snate@binkert.org for target in ['opt', 'fast', 'prof', 'perf']: 11766143Snate@binkert.org ccflags[target] += ['-O3'] 11776143Snate@binkert.orgelse: 117810453SAndrew.Bardsley@arm.com print 'Unknown compiler, please fix compiler options' 117910453SAndrew.Bardsley@arm.com Exit(1) 118010453SAndrew.Bardsley@arm.com 118110453SAndrew.Bardsley@arm.com 118210453SAndrew.Bardsley@arm.com# To speed things up, we only instantiate the build environments we 118310453SAndrew.Bardsley@arm.com# need. We try to identify the needed environment for each target; if 118410453SAndrew.Bardsley@arm.com# we can't, we fall back on instantiating all the environments just to 118511983Sgabeblack@google.com# be safe. 118611983Sgabeblack@google.comtarget_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 118711983Sgabeblack@google.comobj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 118811983Sgabeblack@google.com 'gpo' : 'perf'} 118911983Sgabeblack@google.com 119011983Sgabeblack@google.comdef identifyTarget(t): 119111983Sgabeblack@google.com ext = t.split('.')[-1] 119211983Sgabeblack@google.com if ext in target_types: 119311983Sgabeblack@google.com return ext 119411983Sgabeblack@google.com if obj2target.has_key(ext): 119511983Sgabeblack@google.com return obj2target[ext] 119611983Sgabeblack@google.com match = re.search(r'/tests/([^/]+)/', t) 119711983Sgabeblack@google.com if match and match.group(1) in target_types: 119811983Sgabeblack@google.com return match.group(1) 119911983Sgabeblack@google.com return 'all' 120011983Sgabeblack@google.com 120111983Sgabeblack@google.comneeded_envs = [identifyTarget(target) for target in BUILD_TARGETS] 120211983Sgabeblack@google.comif 'all' in needed_envs: 120311983Sgabeblack@google.com needed_envs += target_types 120411983Sgabeblack@google.com 120511983Sgabeblack@google.comgem5_root = Dir('.').up().up().abspath 120611983Sgabeblack@google.comdef makeEnvirons(target, source, env): 120711983Sgabeblack@google.com # cause any later Source() calls to be fatal, as a diagnostic. 120811983Sgabeblack@google.com Source.done() 120911983Sgabeblack@google.com 121011983Sgabeblack@google.com envList = [] 121111983Sgabeblack@google.com 121211983Sgabeblack@google.com # Debug binary 121311983Sgabeblack@google.com if 'debug' in needed_envs: 121411983Sgabeblack@google.com envList.append( 121511983Sgabeblack@google.com makeEnv(env, 'debug', '.do', 12166143Snate@binkert.org CCFLAGS = Split(ccflags['debug']), 12176143Snate@binkert.org CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 12186143Snate@binkert.org LINKFLAGS = Split(ldflags['debug']))) 121910453SAndrew.Bardsley@arm.com 12206143Snate@binkert.org # Optimized binary 12216240Snate@binkert.org if 'opt' in needed_envs: 12225554Snate@binkert.org envList.append( 12235522Snate@binkert.org makeEnv(env, 'opt', '.o', 12245522Snate@binkert.org CCFLAGS = Split(ccflags['opt']), 12255797Snate@binkert.org CPPDEFINES = ['TRACING_ON=1'], 12265797Snate@binkert.org LINKFLAGS = Split(ldflags['opt']))) 12275522Snate@binkert.org 12285601Snate@binkert.org # "Fast" binary 12298233Snate@binkert.org if 'fast' in needed_envs: 12308233Snate@binkert.org envList.append( 12318235Snate@binkert.org makeEnv(env, 'fast', '.fo', strip = True, 12328235Snate@binkert.org CCFLAGS = Split(ccflags['fast']), 12338235Snate@binkert.org CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 12348235Snate@binkert.org LINKFLAGS = Split(ldflags['fast']))) 12359003SAli.Saidi@ARM.com 12369003SAli.Saidi@ARM.com # Profiled binary using gprof 123710196SCurtis.Dunham@arm.com if 'prof' in needed_envs: 123810196SCurtis.Dunham@arm.com envList.append( 12398235Snate@binkert.org makeEnv(env, 'prof', '.po', 12406143Snate@binkert.org CCFLAGS = Split(ccflags['prof']), 12412655Sstever@eecs.umich.edu CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 12426143Snate@binkert.org LINKFLAGS = Split(ldflags['prof']))) 12436143Snate@binkert.org 124411974Sgabeblack@google.com # Profiled binary using google-pprof 124511974Sgabeblack@google.com if 'perf' in needed_envs: 124611974Sgabeblack@google.com envList.append( 124711974Sgabeblack@google.com makeEnv(env, 'perf', '.gpo', 124811974Sgabeblack@google.com CCFLAGS = Split(ccflags['perf']), 124911974Sgabeblack@google.com CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 125011974Sgabeblack@google.com LINKFLAGS = Split(ldflags['perf']))) 125111974Sgabeblack@google.com 125211974Sgabeblack@google.com # Set up the regression tests for each build. 125311974Sgabeblack@google.com for e in envList: 125411974Sgabeblack@google.com SConscript(os.path.join(gem5_root, 'tests', 'SConscript'), 125511974Sgabeblack@google.com variant_dir = variantd('tests', e.Label), 12566143Snate@binkert.org exports = { 'env' : e }, duplicate = False) 12576143Snate@binkert.org 12584007Ssaidi@eecs.umich.edu# The MakeEnvirons Builder defers the full dependency collection until 12594596Sbinkertn@umich.edu# after processing the ISA definition (due to dynamically generated 12604007Ssaidi@eecs.umich.edu# source files). Add this dependency to all targets so they will wait 12614596Sbinkertn@umich.edu# until the environments are completely set up. Otherwise, a second 12627756SAli.Saidi@ARM.com# process (e.g. -j2 or higher) will try to compile the requested target, 12637816Ssteve.reinhardt@amd.com# not know how, and fail. 12648334Snate@binkert.orgenv.Append(BUILDERS = {'MakeEnvirons' : 12658334Snate@binkert.org Builder(action=MakeAction(makeEnvirons, 12668334Snate@binkert.org Transform("ENVIRONS", 1)))}) 12678334Snate@binkert.org 12685601Snate@binkert.orgisa_target = env['PHONY_BASE'] + '-deps' 126910196SCurtis.Dunham@arm.comenvirons = env['PHONY_BASE'] + '-environs' 12702655Sstever@eecs.umich.eduenv.Depends('#all-deps', isa_target) 12719225Sandreas.hansson@arm.comenv.Depends('#all-environs', environs) 12729225Sandreas.hansson@arm.comenv.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 12739226Sandreas.hansson@arm.comenvSetup = env.MakeEnvirons(environs, isa_target) 12749226Sandreas.hansson@arm.com 12759225Sandreas.hansson@arm.com# make sure no -deps targets occur before all ISAs are complete 12769226Sandreas.hansson@arm.comenv.Depends(isa_target, '#all-isas') 12779226Sandreas.hansson@arm.com# likewise for -environs targets and all the -deps targets 12789226Sandreas.hansson@arm.comenv.Depends(environs, '#all-deps') 12799226Sandreas.hansson@arm.com