SConscript revision 11308
1955SN/A# -*- mode:python -*- 2955SN/A 313576Sciro.santilli@arm.com# Copyright (c) 2004-2005 The Regents of The University of Michigan 413576Sciro.santilli@arm.com# All rights reserved. 513576Sciro.santilli@arm.com# 613576Sciro.santilli@arm.com# Redistribution and use in source and binary forms, with or without 713576Sciro.santilli@arm.com# modification, are permitted provided that the following conditions are 813576Sciro.santilli@arm.com# met: redistributions of source code must retain the above copyright 913576Sciro.santilli@arm.com# notice, this list of conditions and the following disclaimer; 1013576Sciro.santilli@arm.com# redistributions in binary form must reproduce the above copyright 1113576Sciro.santilli@arm.com# notice, this list of conditions and the following disclaimer in the 1213576Sciro.santilli@arm.com# documentation and/or other materials provided with the distribution; 1313576Sciro.santilli@arm.com# neither the name of the copyright holders nor the names of its 141762SN/A# contributors may be used to endorse or promote products derived from 15955SN/A# this software without specific prior written permission. 16955SN/A# 17955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28955SN/A# 29955SN/A# Authors: Nathan Binkert 30955SN/A 31955SN/Aimport array 32955SN/Aimport bisect 33955SN/Aimport imp 34955SN/Aimport marshal 35955SN/Aimport os 36955SN/Aimport re 37955SN/Aimport sys 38955SN/Aimport zlib 392665Ssaidi@eecs.umich.edu 404762Snate@binkert.orgfrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 41955SN/A 4212563Sgabeblack@google.comimport SCons 4312563Sgabeblack@google.com 445522Snate@binkert.org# This file defines how to build a particular configuration of gem5 456143Snate@binkert.org# based on variable settings in the 'env' build environment. 4612371Sgabeblack@google.com 474762Snate@binkert.orgImport('*') 485522Snate@binkert.org 49955SN/A# Children need to see the environment 505522Snate@binkert.orgExport('env') 5111974Sgabeblack@google.com 52955SN/Abuild_env = [(opt, env[opt]) for opt in export_vars] 535522Snate@binkert.org 544202Sbinkertn@umich.edufrom m5.util import code_formatter, compareVersions 555742Snate@binkert.org 56955SN/A######################################################################## 574381Sbinkertn@umich.edu# Code for adding source files of various types 584381Sbinkertn@umich.edu# 5912246Sgabeblack@google.com# When specifying a source file of some type, a set of guards can be 6012246Sgabeblack@google.com# specified for that file. When get() is used to find the files, if 618334Snate@binkert.org# get specifies a set of filters, only files that match those filters 62955SN/A# will be accepted (unspecified filters on files are assumed to be 63955SN/A# false). Current filters are: 644202Sbinkertn@umich.edu# main -- specifies the gem5 main() function 65955SN/A# skip_lib -- do not put this file into the gem5 library 664382Sbinkertn@umich.edu# skip_no_python -- do not put this file into a no_python library 674382Sbinkertn@umich.edu# as it embeds compiled Python 684382Sbinkertn@umich.edu# <unittest> -- unit tests use filters based on the unit test name 696654Snate@binkert.org# 705517Snate@binkert.org# A parent can now be specified for a source file and default filter 718614Sgblack@eecs.umich.edu# values will be retrieved recursively from parents (children override 727674Snate@binkert.org# parents). 736143Snate@binkert.org# 746143Snate@binkert.orgclass SourceMeta(type): 756143Snate@binkert.org '''Meta class for source files that keeps track of all files of a 7612302Sgabeblack@google.com particular type and has a get function for finding all functions 7712302Sgabeblack@google.com of a certain type that match a set of guards''' 7812302Sgabeblack@google.com def __init__(cls, name, bases, dict): 7912371Sgabeblack@google.com super(SourceMeta, cls).__init__(name, bases, dict) 8012371Sgabeblack@google.com cls.all = [] 8112371Sgabeblack@google.com 8212371Sgabeblack@google.com def get(cls, **guards): 8312371Sgabeblack@google.com '''Find all files that match the specified guards. If a source 8412371Sgabeblack@google.com file does not specify a flag, the default is False''' 8512371Sgabeblack@google.com for src in cls.all: 8612371Sgabeblack@google.com for flag,value in guards.iteritems(): 8712371Sgabeblack@google.com # if the flag is found and has a different value, skip 8812371Sgabeblack@google.com # this file 8912371Sgabeblack@google.com if src.all_guards.get(flag, False) != value: 9012371Sgabeblack@google.com break 9112371Sgabeblack@google.com else: 9212371Sgabeblack@google.com yield src 9312371Sgabeblack@google.com 9412371Sgabeblack@google.comclass SourceFile(object): 9512371Sgabeblack@google.com '''Base object that encapsulates the notion of a source file. 9612371Sgabeblack@google.com This includes, the source node, target node, various manipulations 9712371Sgabeblack@google.com of those. A source file also specifies a set of guards which 9812371Sgabeblack@google.com describing which builds the source file applies to. A parent can 9912371Sgabeblack@google.com also be specified to get default guards from''' 10012371Sgabeblack@google.com __metaclass__ = SourceMeta 10112371Sgabeblack@google.com def __init__(self, source, parent=None, **guards): 10212371Sgabeblack@google.com self.guards = guards 10312371Sgabeblack@google.com self.parent = parent 10412371Sgabeblack@google.com 10512371Sgabeblack@google.com tnode = source 10612371Sgabeblack@google.com if not isinstance(source, SCons.Node.FS.File): 10712371Sgabeblack@google.com tnode = File(source) 10812371Sgabeblack@google.com 10912371Sgabeblack@google.com self.tnode = tnode 11012371Sgabeblack@google.com self.snode = tnode.srcnode() 11112371Sgabeblack@google.com 11212371Sgabeblack@google.com for base in type(self).__mro__: 11312371Sgabeblack@google.com if issubclass(base, SourceFile): 11412371Sgabeblack@google.com base.all.append(self) 11512371Sgabeblack@google.com 11612371Sgabeblack@google.com @property 11712371Sgabeblack@google.com def filename(self): 11812371Sgabeblack@google.com return str(self.tnode) 11912371Sgabeblack@google.com 12012371Sgabeblack@google.com @property 12112371Sgabeblack@google.com def dirname(self): 12212371Sgabeblack@google.com return dirname(self.filename) 12312371Sgabeblack@google.com 12412371Sgabeblack@google.com @property 12512371Sgabeblack@google.com def basename(self): 12612302Sgabeblack@google.com return basename(self.filename) 12712371Sgabeblack@google.com 12812302Sgabeblack@google.com @property 12912371Sgabeblack@google.com def extname(self): 13012302Sgabeblack@google.com index = self.basename.rfind('.') 13112302Sgabeblack@google.com if index <= 0: 13212371Sgabeblack@google.com # dot files aren't extensions 13312371Sgabeblack@google.com return self.basename, None 13412371Sgabeblack@google.com 13512371Sgabeblack@google.com return self.basename[:index], self.basename[index+1:] 13612302Sgabeblack@google.com 13712371Sgabeblack@google.com @property 13812371Sgabeblack@google.com def all_guards(self): 13912371Sgabeblack@google.com '''find all guards for this object getting default values 14012371Sgabeblack@google.com recursively from its parents''' 14111983Sgabeblack@google.com guards = {} 1426143Snate@binkert.org if self.parent: 1438233Snate@binkert.org guards.update(self.parent.guards) 14412302Sgabeblack@google.com guards.update(self.guards) 1456143Snate@binkert.org return guards 1466143Snate@binkert.org 14712302Sgabeblack@google.com def __lt__(self, other): return self.filename < other.filename 1484762Snate@binkert.org def __le__(self, other): return self.filename <= other.filename 1496143Snate@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 15212302Sgabeblack@google.com def __ne__(self, other): return self.filename != other.filename 15312302Sgabeblack@google.com 1546143Snate@binkert.org @staticmethod 15512362Sgabeblack@google.com def done(): 15612362Sgabeblack@google.com def disabled(cls, name, *ignored): 15712362Sgabeblack@google.com raise RuntimeError("Additional SourceFile '%s'" % name,\ 15812362Sgabeblack@google.com "declared, but targets deps are already fixed.") 15912302Sgabeblack@google.com SourceFile.__init__ = disabled 16012302Sgabeblack@google.com 16112302Sgabeblack@google.com 16212302Sgabeblack@google.comclass Source(SourceFile): 16312302Sgabeblack@google.com '''Add a c/c++ source file to the build''' 16412363Sgabeblack@google.com def __init__(self, source, Werror=True, swig=False, **guards): 16512363Sgabeblack@google.com '''specify the source file, and any guards''' 16612363Sgabeblack@google.com super(Source, self).__init__(source, **guards) 16712363Sgabeblack@google.com 16812302Sgabeblack@google.com self.Werror = Werror 16912363Sgabeblack@google.com self.swig = swig 17012363Sgabeblack@google.com 17112363Sgabeblack@google.comclass PySource(SourceFile): 17212363Sgabeblack@google.com '''Add a python source file to the named package''' 17312363Sgabeblack@google.com invalid_sym_char = re.compile('[^A-z0-9_]') 1748233Snate@binkert.org modules = {} 1756143Snate@binkert.org tnodes = {} 1766143Snate@binkert.org symnames = {} 1776143Snate@binkert.org 1786143Snate@binkert.org def __init__(self, package, source, **guards): 1796143Snate@binkert.org '''specify the python package, the source file, and any guards''' 1806143Snate@binkert.org super(PySource, self).__init__(source, **guards) 1816143Snate@binkert.org 1826143Snate@binkert.org modname,ext = self.extname 1836143Snate@binkert.org assert ext == 'py' 1847065Snate@binkert.org 1856143Snate@binkert.org if package: 18612362Sgabeblack@google.com path = package.split('.') 18712362Sgabeblack@google.com else: 18812362Sgabeblack@google.com path = [] 18912362Sgabeblack@google.com 19012362Sgabeblack@google.com modpath = path[:] 19112362Sgabeblack@google.com if modname != '__init__': 19212362Sgabeblack@google.com modpath += [ modname ] 19312362Sgabeblack@google.com modpath = '.'.join(modpath) 19412362Sgabeblack@google.com 19512362Sgabeblack@google.com arcpath = path + [ self.basename ] 19612362Sgabeblack@google.com abspath = self.snode.abspath 19712362Sgabeblack@google.com if not exists(abspath): 1988233Snate@binkert.org abspath = self.tnode.abspath 1998233Snate@binkert.org 2008233Snate@binkert.org self.package = package 2018233Snate@binkert.org self.modname = modname 2028233Snate@binkert.org self.modpath = modpath 2038233Snate@binkert.org self.arcname = joinpath(*arcpath) 2048233Snate@binkert.org self.abspath = abspath 2058233Snate@binkert.org self.compiled = File(self.filename + 'c') 2068233Snate@binkert.org self.cpp = File(self.filename + '.cc') 2078233Snate@binkert.org self.symname = PySource.invalid_sym_char.sub('_', modpath) 2088233Snate@binkert.org 2098233Snate@binkert.org PySource.modules[modpath] = self 2108233Snate@binkert.org PySource.tnodes[self.tnode] = self 2118233Snate@binkert.org PySource.symnames[self.symname] = self 2128233Snate@binkert.org 2138233Snate@binkert.orgclass SimObject(PySource): 2148233Snate@binkert.org '''Add a SimObject python file as a python source object and add 2158233Snate@binkert.org it to a list of sim object modules''' 2168233Snate@binkert.org 2178233Snate@binkert.org fixed = False 2188233Snate@binkert.org modnames = [] 2196143Snate@binkert.org 2206143Snate@binkert.org def __init__(self, source, **guards): 2216143Snate@binkert.org '''Specify the source file and any guards (automatically in 2226143Snate@binkert.org the m5.objects package)''' 2236143Snate@binkert.org super(SimObject, self).__init__('m5.objects', source, **guards) 2246143Snate@binkert.org if self.fixed: 2259982Satgutier@umich.edu raise AttributeError, "Too late to call SimObject now." 22613576Sciro.santilli@arm.com 22713576Sciro.santilli@arm.com bisect.insort_right(SimObject.modnames, self.modname) 22813576Sciro.santilli@arm.com 22913576Sciro.santilli@arm.comclass SwigSource(SourceFile): 23013576Sciro.santilli@arm.com '''Add a swig file to build''' 23113576Sciro.santilli@arm.com 23213576Sciro.santilli@arm.com def __init__(self, package, source, **guards): 23313576Sciro.santilli@arm.com '''Specify the python package, the source file, and any guards''' 23413576Sciro.santilli@arm.com super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 23513576Sciro.santilli@arm.com 23613576Sciro.santilli@arm.com modname,ext = self.extname 23713576Sciro.santilli@arm.com assert ext == 'i' 23813576Sciro.santilli@arm.com 23913576Sciro.santilli@arm.com self.module = modname 24013576Sciro.santilli@arm.com cc_file = joinpath(self.dirname, modname + '_wrap.cc') 24113576Sciro.santilli@arm.com py_file = joinpath(self.dirname, modname + '.py') 24213576Sciro.santilli@arm.com 24313576Sciro.santilli@arm.com self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 24413576Sciro.santilli@arm.com self.py_source = PySource(package, py_file, parent=self, **guards) 24513576Sciro.santilli@arm.com 24613576Sciro.santilli@arm.comclass ProtoBuf(SourceFile): 24713576Sciro.santilli@arm.com '''Add a Protocol Buffer to build''' 24813576Sciro.santilli@arm.com 24913576Sciro.santilli@arm.com def __init__(self, source, **guards): 25013576Sciro.santilli@arm.com '''Specify the source file, and any guards''' 25113576Sciro.santilli@arm.com super(ProtoBuf, self).__init__(source, **guards) 25213576Sciro.santilli@arm.com 25313576Sciro.santilli@arm.com # Get the file name and the extension 25413576Sciro.santilli@arm.com modname,ext = self.extname 25513576Sciro.santilli@arm.com assert ext == 'proto' 25613576Sciro.santilli@arm.com 25713576Sciro.santilli@arm.com # Currently, we stick to generating the C++ headers, so we 25813630Sciro.santilli@arm.com # only need to track the source and header. 25913630Sciro.santilli@arm.com self.cc_file = File(modname + '.pb.cc') 26013576Sciro.santilli@arm.com self.hh_file = File(modname + '.pb.h') 26113576Sciro.santilli@arm.com 26213576Sciro.santilli@arm.comclass UnitTest(object): 26313576Sciro.santilli@arm.com '''Create a UnitTest''' 26413576Sciro.santilli@arm.com 26513576Sciro.santilli@arm.com all = [] 26613576Sciro.santilli@arm.com def __init__(self, target, *sources, **kwargs): 26713576Sciro.santilli@arm.com '''Specify the target name and any sources. Sources that are 26813576Sciro.santilli@arm.com not SourceFiles are evalued with Source(). All files are 26913576Sciro.santilli@arm.com guarded with a guard of the same name as the UnitTest 27013576Sciro.santilli@arm.com target.''' 27113576Sciro.santilli@arm.com 27213576Sciro.santilli@arm.com srcs = [] 27313576Sciro.santilli@arm.com for src in sources: 27413576Sciro.santilli@arm.com if not isinstance(src, SourceFile): 27513576Sciro.santilli@arm.com src = Source(src, skip_lib=True) 27613576Sciro.santilli@arm.com src.guards[target] = True 27713576Sciro.santilli@arm.com srcs.append(src) 27813576Sciro.santilli@arm.com 27913576Sciro.santilli@arm.com self.sources = srcs 28013576Sciro.santilli@arm.com self.target = target 28113576Sciro.santilli@arm.com self.main = kwargs.get('main', False) 28213576Sciro.santilli@arm.com UnitTest.all.append(self) 28313576Sciro.santilli@arm.com 28413576Sciro.santilli@arm.com# Children should have access 28513576Sciro.santilli@arm.comExport('Source') 28613576Sciro.santilli@arm.comExport('PySource') 28713576Sciro.santilli@arm.comExport('SimObject') 28813576Sciro.santilli@arm.comExport('SwigSource') 28913576Sciro.santilli@arm.comExport('ProtoBuf') 29013576Sciro.santilli@arm.comExport('UnitTest') 29113576Sciro.santilli@arm.com 29213576Sciro.santilli@arm.com######################################################################## 29313576Sciro.santilli@arm.com# 29413576Sciro.santilli@arm.com# Debug Flags 29513576Sciro.santilli@arm.com# 29613576Sciro.santilli@arm.comdebug_flags = {} 29713577Sciro.santilli@arm.comdef DebugFlag(name, desc=None): 29813577Sciro.santilli@arm.com if name in debug_flags: 29913577Sciro.santilli@arm.com raise AttributeError, "Flag %s already specified" % name 3006143Snate@binkert.org debug_flags[name] = (name, (), desc) 30112302Sgabeblack@google.com 30212302Sgabeblack@google.comdef CompoundFlag(name, flags, desc=None): 30312302Sgabeblack@google.com if name in debug_flags: 30412302Sgabeblack@google.com raise AttributeError, "Flag %s already specified" % name 30512302Sgabeblack@google.com 30612302Sgabeblack@google.com compound = tuple(flags) 30712302Sgabeblack@google.com debug_flags[name] = (name, compound, desc) 30812302Sgabeblack@google.com 30911983Sgabeblack@google.comExport('DebugFlag') 31011983Sgabeblack@google.comExport('CompoundFlag') 31111983Sgabeblack@google.com 31212302Sgabeblack@google.com######################################################################## 31312302Sgabeblack@google.com# 31412302Sgabeblack@google.com# Set some compiler variables 31512302Sgabeblack@google.com# 31612302Sgabeblack@google.com 31712302Sgabeblack@google.com# Include file paths are rooted in this directory. SCons will 31811983Sgabeblack@google.com# automatically expand '.' to refer to both the source directory and 3196143Snate@binkert.org# the corresponding build directory to pick up generated include 32012305Sgabeblack@google.com# files. 32112302Sgabeblack@google.comenv.Append(CPPPATH=Dir('.')) 32212302Sgabeblack@google.com 32312302Sgabeblack@google.comfor extra_dir in extras_dir_list: 3246143Snate@binkert.org env.Append(CPPPATH=Dir(extra_dir)) 3256143Snate@binkert.org 3266143Snate@binkert.org# Workaround for bug in SCons version > 0.97d20071212 3275522Snate@binkert.org# Scons bug id: 2006 gem5 Bug id: 308 3286143Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True): 3296143Snate@binkert.org Dir(root[len(base_dir) + 1:]) 3306143Snate@binkert.org 3319982Satgutier@umich.edu######################################################################## 33212302Sgabeblack@google.com# 33312302Sgabeblack@google.com# Walk the tree and execute all SConscripts in subdirectories 33412302Sgabeblack@google.com# 3356143Snate@binkert.org 3366143Snate@binkert.orghere = Dir('.').srcnode().abspath 3376143Snate@binkert.orgfor root, dirs, files in os.walk(base_dir, topdown=True): 3386143Snate@binkert.org if root == here: 3395522Snate@binkert.org # we don't want to recurse back into this SConscript 3405522Snate@binkert.org continue 3415522Snate@binkert.org 3425522Snate@binkert.org if 'SConscript' in files: 3435604Snate@binkert.org build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 3445604Snate@binkert.org SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3456143Snate@binkert.org 3466143Snate@binkert.orgfor extra_dir in extras_dir_list: 3474762Snate@binkert.org prefix_len = len(dirname(extra_dir)) + 1 3484762Snate@binkert.org 3496143Snate@binkert.org # Also add the corresponding build directory to pick up generated 3506727Ssteve.reinhardt@amd.com # include files. 3516727Ssteve.reinhardt@amd.com env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 3526727Ssteve.reinhardt@amd.com 3534762Snate@binkert.org for root, dirs, files in os.walk(extra_dir, topdown=True): 3546143Snate@binkert.org # if build lives in the extras directory, don't walk down it 3556143Snate@binkert.org if 'build' in dirs: 3566143Snate@binkert.org dirs.remove('build') 3576143Snate@binkert.org 3586727Ssteve.reinhardt@amd.com if 'SConscript' in files: 3596143Snate@binkert.org build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 3607674Snate@binkert.org SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 3617674Snate@binkert.org 3625604Snate@binkert.orgfor opt in export_vars: 3636143Snate@binkert.org env.ConfigFile(opt) 3646143Snate@binkert.org 3656143Snate@binkert.orgdef makeTheISA(source, target, env): 3664762Snate@binkert.org isas = [ src.get_contents() for src in source ] 3676143Snate@binkert.org target_isa = env['TARGET_ISA'] 3684762Snate@binkert.org def define(isa): 3694762Snate@binkert.org return isa.upper() + '_ISA' 3704762Snate@binkert.org 3716143Snate@binkert.org def namespace(isa): 3726143Snate@binkert.org return isa[0].upper() + isa[1:].lower() + 'ISA' 3734762Snate@binkert.org 37412302Sgabeblack@google.com 37512302Sgabeblack@google.com code = code_formatter() 3768233Snate@binkert.org code('''\ 37712302Sgabeblack@google.com#ifndef __CONFIG_THE_ISA_HH__ 3786143Snate@binkert.org#define __CONFIG_THE_ISA_HH__ 3796143Snate@binkert.org 3804762Snate@binkert.org''') 3816143Snate@binkert.org 3824762Snate@binkert.org # create defines for the preprocessing and compile-time determination 3839396Sandreas.hansson@arm.com for i,isa in enumerate(isas): 3849396Sandreas.hansson@arm.com code('#define $0 $1', define(isa), i + 1) 3859396Sandreas.hansson@arm.com code() 38612302Sgabeblack@google.com 38712302Sgabeblack@google.com # create an enum for any run-time determination of the ISA, we 38812302Sgabeblack@google.com # reuse the same name as the namespaces 3899396Sandreas.hansson@arm.com code('enum class Arch {') 3909396Sandreas.hansson@arm.com for i,isa in enumerate(isas): 3919396Sandreas.hansson@arm.com if i + 1 == len(isas): 3929396Sandreas.hansson@arm.com code(' $0 = $1', namespace(isa), define(isa)) 3939396Sandreas.hansson@arm.com else: 3949396Sandreas.hansson@arm.com code(' $0 = $1,', namespace(isa), define(isa)) 3959396Sandreas.hansson@arm.com code('};') 3969930Sandreas.hansson@arm.com 3979930Sandreas.hansson@arm.com code(''' 3989396Sandreas.hansson@arm.com 3996143Snate@binkert.org#define THE_ISA ${{define(target_isa)}} 40012797Sgabeblack@google.com#define TheISA ${{namespace(target_isa)}} 40112797Sgabeblack@google.com#define THE_ISA_STR "${{target_isa}}" 40212797Sgabeblack@google.com 4038235Snate@binkert.org#endif // __CONFIG_THE_ISA_HH__''') 40412797Sgabeblack@google.com 40512797Sgabeblack@google.com code.write(str(target[0])) 40612797Sgabeblack@google.com 40712797Sgabeblack@google.comenv.Command('config/the_isa.hh', map(Value, all_isa_list), 40812797Sgabeblack@google.com MakeAction(makeTheISA, Transform("CFG ISA", 0))) 40912797Sgabeblack@google.com 41012797Sgabeblack@google.comdef makeTheGPUISA(source, target, env): 41112797Sgabeblack@google.com isas = [ src.get_contents() for src in source ] 41212797Sgabeblack@google.com target_gpu_isa = env['TARGET_GPU_ISA'] 41312797Sgabeblack@google.com def define(isa): 41412797Sgabeblack@google.com return isa.upper() + '_ISA' 41512797Sgabeblack@google.com 41612797Sgabeblack@google.com def namespace(isa): 41712797Sgabeblack@google.com return isa[0].upper() + isa[1:].lower() + 'ISA' 41812797Sgabeblack@google.com 41912757Sgabeblack@google.com 42012757Sgabeblack@google.com code = code_formatter() 42112797Sgabeblack@google.com code('''\ 42212797Sgabeblack@google.com#ifndef __CONFIG_THE_GPU_ISA_HH__ 42312797Sgabeblack@google.com#define __CONFIG_THE_GPU_ISA_HH__ 42412757Sgabeblack@google.com 42512757Sgabeblack@google.com''') 42612757Sgabeblack@google.com 42712757Sgabeblack@google.com # create defines for the preprocessing and compile-time determination 4288235Snate@binkert.org for i,isa in enumerate(isas): 42912302Sgabeblack@google.com code('#define $0 $1', define(isa), i + 1) 4308235Snate@binkert.org code() 4318235Snate@binkert.org 43212757Sgabeblack@google.com # create an enum for any run-time determination of the ISA, we 4338235Snate@binkert.org # reuse the same name as the namespaces 4348235Snate@binkert.org code('enum class GPUArch {') 4358235Snate@binkert.org for i,isa in enumerate(isas): 43612757Sgabeblack@google.com if i + 1 == len(isas): 43712313Sgabeblack@google.com code(' $0 = $1', namespace(isa), define(isa)) 43812797Sgabeblack@google.com else: 43912797Sgabeblack@google.com code(' $0 = $1,', namespace(isa), define(isa)) 44012797Sgabeblack@google.com code('};') 44112797Sgabeblack@google.com 44212797Sgabeblack@google.com code(''' 44312797Sgabeblack@google.com 44412797Sgabeblack@google.com#define THE_GPU_ISA ${{define(target_gpu_isa)}} 44512797Sgabeblack@google.com#define TheGpuISA ${{namespace(target_gpu_isa)}} 44612797Sgabeblack@google.com#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 44712797Sgabeblack@google.com 44812797Sgabeblack@google.com#endif // __CONFIG_THE_GPU_ISA_HH__''') 44912797Sgabeblack@google.com 45012797Sgabeblack@google.com code.write(str(target[0])) 45112797Sgabeblack@google.com 45212797Sgabeblack@google.comenv.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 45312797Sgabeblack@google.com MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 45412797Sgabeblack@google.com 45512797Sgabeblack@google.com######################################################################## 45612797Sgabeblack@google.com# 45712797Sgabeblack@google.com# Prevent any SimObjects from being added after this point, they 45812797Sgabeblack@google.com# should all have been added in the SConscripts above 45912797Sgabeblack@google.com# 46012797Sgabeblack@google.comSimObject.fixed = True 46112797Sgabeblack@google.com 46212797Sgabeblack@google.comclass DictImporter(object): 46312797Sgabeblack@google.com '''This importer takes a dictionary of arbitrary module names that 46412797Sgabeblack@google.com map to arbitrary filenames.''' 46512797Sgabeblack@google.com def __init__(self, modules): 46612797Sgabeblack@google.com self.modules = modules 46712797Sgabeblack@google.com self.installed = set() 46812797Sgabeblack@google.com 46912797Sgabeblack@google.com def __del__(self): 47012797Sgabeblack@google.com self.unload() 47112797Sgabeblack@google.com 47212797Sgabeblack@google.com def unload(self): 47312797Sgabeblack@google.com import sys 47412797Sgabeblack@google.com for module in self.installed: 47512797Sgabeblack@google.com del sys.modules[module] 47612797Sgabeblack@google.com self.installed = set() 47712797Sgabeblack@google.com 47812797Sgabeblack@google.com def find_module(self, fullname, path): 47912797Sgabeblack@google.com if fullname == 'm5.defines': 48012797Sgabeblack@google.com return self 48112797Sgabeblack@google.com 48212313Sgabeblack@google.com if fullname == 'm5.objects': 48312313Sgabeblack@google.com return self 48412797Sgabeblack@google.com 48512797Sgabeblack@google.com if fullname.startswith('m5.internal'): 48612797Sgabeblack@google.com return None 48712371Sgabeblack@google.com 4885584Snate@binkert.org source = self.modules.get(fullname, None) 48912797Sgabeblack@google.com if source is not None and fullname.startswith('m5.objects'): 49012797Sgabeblack@google.com return self 49112797Sgabeblack@google.com 49212797Sgabeblack@google.com return None 49312797Sgabeblack@google.com 49412797Sgabeblack@google.com def load_module(self, fullname): 49512797Sgabeblack@google.com mod = imp.new_module(fullname) 49612797Sgabeblack@google.com sys.modules[fullname] = mod 49712797Sgabeblack@google.com self.installed.add(fullname) 49812797Sgabeblack@google.com 49912797Sgabeblack@google.com mod.__loader__ = self 50012797Sgabeblack@google.com if fullname == 'm5.objects': 50112797Sgabeblack@google.com mod.__path__ = fullname.split('.') 50212797Sgabeblack@google.com return mod 50312797Sgabeblack@google.com 50412797Sgabeblack@google.com if fullname == 'm5.defines': 50512797Sgabeblack@google.com mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 50612797Sgabeblack@google.com return mod 50712797Sgabeblack@google.com 50812797Sgabeblack@google.com source = self.modules[fullname] 50912797Sgabeblack@google.com if source.modname == '__init__': 51012797Sgabeblack@google.com mod.__path__ = source.modpath 51112797Sgabeblack@google.com mod.__file__ = source.abspath 51212797Sgabeblack@google.com 51312797Sgabeblack@google.com exec file(source.abspath, 'r') in mod.__dict__ 51412797Sgabeblack@google.com 51512797Sgabeblack@google.com return mod 51612797Sgabeblack@google.com 51712797Sgabeblack@google.comimport m5.SimObject 51812797Sgabeblack@google.comimport m5.params 51912797Sgabeblack@google.comfrom m5.util import code_formatter 52012797Sgabeblack@google.com 52112797Sgabeblack@google.comm5.SimObject.clear() 52212797Sgabeblack@google.comm5.params.clear() 52312797Sgabeblack@google.com 52412797Sgabeblack@google.com# install the python importer so we can grab stuff from the source 52512797Sgabeblack@google.com# tree itself. We can't have SimObjects added after this point or 52612797Sgabeblack@google.com# else we won't know about them for the rest of the stuff. 5274382Sbinkertn@umich.eduimporter = DictImporter(PySource.modules) 52813576Sciro.santilli@arm.comsys.meta_path[0:0] = [ importer ] 52913577Sciro.santilli@arm.com 5304202Sbinkertn@umich.edu# import all sim objects so we can populate the all_objects list 5314382Sbinkertn@umich.edu# make sure that we're working with a list, then let's sort it 5324382Sbinkertn@umich.edufor modname in SimObject.modnames: 5339396Sandreas.hansson@arm.com exec('from m5.objects import %s' % modname) 53412797Sgabeblack@google.com 5355584Snate@binkert.org# we need to unload all of the currently imported modules so that they 53612313Sgabeblack@google.com# will be re-imported the next time the sconscript is run 5374382Sbinkertn@umich.eduimporter.unload() 5384382Sbinkertn@umich.edusys.meta_path.remove(importer) 5394382Sbinkertn@umich.edu 5408232Snate@binkert.orgsim_objects = m5.SimObject.allClasses 5415192Ssaidi@eecs.umich.eduall_enums = m5.params.allEnums 5428232Snate@binkert.org 5438232Snate@binkert.orgif m5.SimObject.noCxxHeader: 5448232Snate@binkert.org print >> sys.stderr, \ 5455192Ssaidi@eecs.umich.edu "warning: At least one SimObject lacks a header specification. " \ 5468232Snate@binkert.org "This can cause unexpected results in the generated SWIG " \ 5475192Ssaidi@eecs.umich.edu "wrappers." 5485799Snate@binkert.org 5498232Snate@binkert.org# Find param types that need to be explicitly wrapped with swig. 5505192Ssaidi@eecs.umich.edu# These will be recognized because the ParamDesc will have a 5515192Ssaidi@eecs.umich.edu# swig_decl() method. Most param types are based on types that don't 5525192Ssaidi@eecs.umich.edu# need this, either because they're based on native types (like Int) 5538232Snate@binkert.org# or because they're SimObjects (which get swigged independently). 5545192Ssaidi@eecs.umich.edu# For now the only things handled here are VectorParam types. 5558232Snate@binkert.orgparams_to_swig = {} 5565192Ssaidi@eecs.umich.edufor name,obj in sorted(sim_objects.iteritems()): 5575192Ssaidi@eecs.umich.edu for param in obj._params.local.values(): 5585192Ssaidi@eecs.umich.edu # load the ptype attribute now because it depends on the 5595192Ssaidi@eecs.umich.edu # current version of SimObject.allClasses, but when scons 5604382Sbinkertn@umich.edu # actually uses the value, all versions of 5614382Sbinkertn@umich.edu # SimObject.allClasses will have been loaded 5624382Sbinkertn@umich.edu param.ptype 5632667Sstever@eecs.umich.edu 5642667Sstever@eecs.umich.edu if not hasattr(param, 'swig_decl'): 5652667Sstever@eecs.umich.edu continue 5662667Sstever@eecs.umich.edu pname = param.ptype_str 5672667Sstever@eecs.umich.edu if pname not in params_to_swig: 5682667Sstever@eecs.umich.edu params_to_swig[pname] = param 5695742Snate@binkert.org 5705742Snate@binkert.org######################################################################## 5715742Snate@binkert.org# 5725793Snate@binkert.org# calculate extra dependencies 5738334Snate@binkert.org# 5745793Snate@binkert.orgmodule_depends = ["m5", "m5.SimObject", "m5.params"] 5755793Snate@binkert.orgdepends = [ PySource.modules[dep].snode for dep in module_depends ] 5765793Snate@binkert.orgdepends.sort(key = lambda x: x.name) 5774382Sbinkertn@umich.edu 5784762Snate@binkert.org######################################################################## 5795344Sstever@gmail.com# 5804382Sbinkertn@umich.edu# Commands for the basic automatically generated python files 5815341Sstever@gmail.com# 5825742Snate@binkert.org 5835742Snate@binkert.org# Generate Python file containing a dict specifying the current 5845742Snate@binkert.org# buildEnv flags. 5855742Snate@binkert.orgdef makeDefinesPyFile(target, source, env): 5865742Snate@binkert.org build_env = source[0].get_contents() 5874762Snate@binkert.org 5885742Snate@binkert.org code = code_formatter() 5895742Snate@binkert.org code(""" 59011984Sgabeblack@google.comimport m5.internal 5917722Sgblack@eecs.umich.eduimport m5.util 5925742Snate@binkert.org 5935742Snate@binkert.orgbuildEnv = m5.util.SmartDict($build_env) 5945742Snate@binkert.org 5959930Sandreas.hansson@arm.comcompileDate = m5.internal.core.compileDate 5969930Sandreas.hansson@arm.com_globals = globals() 5979930Sandreas.hansson@arm.comfor key,val in m5.internal.core.__dict__.iteritems(): 5989930Sandreas.hansson@arm.com if key.startswith('flag_'): 5999930Sandreas.hansson@arm.com flag = key[5:] 6005742Snate@binkert.org _globals[flag] = val 6018242Sbradley.danofsky@amd.comdel _globals 6028242Sbradley.danofsky@amd.com""") 6038242Sbradley.danofsky@amd.com code.write(target[0].abspath) 6048242Sbradley.danofsky@amd.com 6055341Sstever@gmail.comdefines_info = Value(build_env) 6065742Snate@binkert.org# Generate a file with all of the compile options in it 6077722Sgblack@eecs.umich.eduenv.Command('python/m5/defines.py', defines_info, 6084773Snate@binkert.org MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 6096108Snate@binkert.orgPySource('m5', 'python/m5/defines.py') 6101858SN/A 6111085SN/A# Generate python file containing info about the M5 source code 6126658Snate@binkert.orgdef makeInfoPyFile(target, source, env): 6136658Snate@binkert.org code = code_formatter() 6147673Snate@binkert.org for src in source: 6156658Snate@binkert.org data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 6166658Snate@binkert.org code('$src = ${{repr(data)}}') 61711308Santhony.gutierrez@amd.com code.write(str(target[0])) 6186658Snate@binkert.org 61911308Santhony.gutierrez@amd.com# Generate a file that wraps the basic top level files 6206658Snate@binkert.orgenv.Command('python/m5/info.py', 6216658Snate@binkert.org [ '#/COPYING', '#/LICENSE', '#/README', ], 6227673Snate@binkert.org MakeAction(makeInfoPyFile, Transform("INFO"))) 6237673Snate@binkert.orgPySource('m5', 'python/m5/info.py') 6247673Snate@binkert.org 6257673Snate@binkert.org######################################################################## 6267673Snate@binkert.org# 6277673Snate@binkert.org# Create all of the SimObject param headers and enum headers 6287673Snate@binkert.org# 62910467Sandreas.hansson@arm.com 6306658Snate@binkert.orgdef createSimObjectParamStruct(target, source, env): 6317673Snate@binkert.org assert len(target) == 1 and len(source) == 1 63210467Sandreas.hansson@arm.com 63310467Sandreas.hansson@arm.com name = str(source[0].get_contents()) 63410467Sandreas.hansson@arm.com obj = sim_objects[name] 63510467Sandreas.hansson@arm.com 63610467Sandreas.hansson@arm.com code = code_formatter() 63710467Sandreas.hansson@arm.com obj.cxx_param_decl(code) 63810467Sandreas.hansson@arm.com code.write(target[0].abspath) 63910467Sandreas.hansson@arm.com 64010467Sandreas.hansson@arm.comdef createSimObjectCxxConfig(is_header): 64110467Sandreas.hansson@arm.com def body(target, source, env): 64210467Sandreas.hansson@arm.com assert len(target) == 1 and len(source) == 1 6437673Snate@binkert.org 6447673Snate@binkert.org name = str(source[0].get_contents()) 6457673Snate@binkert.org obj = sim_objects[name] 6467673Snate@binkert.org 6477673Snate@binkert.org code = code_formatter() 6489048SAli.Saidi@ARM.com obj.cxx_config_param_file(code, is_header) 6497673Snate@binkert.org code.write(target[0].abspath) 6507673Snate@binkert.org return body 6517673Snate@binkert.org 6527673Snate@binkert.orgdef createParamSwigWrapper(target, source, env): 6536658Snate@binkert.org assert len(target) == 1 and len(source) == 1 6547756SAli.Saidi@ARM.com 6557816Ssteve.reinhardt@amd.com name = str(source[0].get_contents()) 6566658Snate@binkert.org param = params_to_swig[name] 65711308Santhony.gutierrez@amd.com 65811308Santhony.gutierrez@amd.com code = code_formatter() 65911308Santhony.gutierrez@amd.com param.swig_decl(code) 66011308Santhony.gutierrez@amd.com code.write(target[0].abspath) 66111308Santhony.gutierrez@amd.com 66211308Santhony.gutierrez@amd.comdef createEnumStrings(target, source, env): 66311308Santhony.gutierrez@amd.com assert len(target) == 1 and len(source) == 1 66411308Santhony.gutierrez@amd.com 66511308Santhony.gutierrez@amd.com name = str(source[0].get_contents()) 66611308Santhony.gutierrez@amd.com obj = all_enums[name] 66711308Santhony.gutierrez@amd.com 66811308Santhony.gutierrez@amd.com code = code_formatter() 66911308Santhony.gutierrez@amd.com obj.cxx_def(code) 67011308Santhony.gutierrez@amd.com code.write(target[0].abspath) 67111308Santhony.gutierrez@amd.com 67211308Santhony.gutierrez@amd.comdef createEnumDecls(target, source, env): 67311308Santhony.gutierrez@amd.com assert len(target) == 1 and len(source) == 1 67411308Santhony.gutierrez@amd.com 67511308Santhony.gutierrez@amd.com name = str(source[0].get_contents()) 67611308Santhony.gutierrez@amd.com obj = all_enums[name] 67711308Santhony.gutierrez@amd.com 67811308Santhony.gutierrez@amd.com code = code_formatter() 67911308Santhony.gutierrez@amd.com obj.cxx_decl(code) 68011308Santhony.gutierrez@amd.com code.write(target[0].abspath) 68111308Santhony.gutierrez@amd.com 68211308Santhony.gutierrez@amd.comdef createEnumSwigWrapper(target, source, env): 68311308Santhony.gutierrez@amd.com assert len(target) == 1 and len(source) == 1 68411308Santhony.gutierrez@amd.com 68511308Santhony.gutierrez@amd.com name = str(source[0].get_contents()) 68611308Santhony.gutierrez@amd.com obj = all_enums[name] 68711308Santhony.gutierrez@amd.com 68811308Santhony.gutierrez@amd.com code = code_formatter() 68911308Santhony.gutierrez@amd.com obj.swig_decl(code) 69011308Santhony.gutierrez@amd.com code.write(target[0].abspath) 69111308Santhony.gutierrez@amd.com 69211308Santhony.gutierrez@amd.comdef createSimObjectSwigWrapper(target, source, env): 69311308Santhony.gutierrez@amd.com name = source[0].get_contents() 69411308Santhony.gutierrez@amd.com obj = sim_objects[name] 69511308Santhony.gutierrez@amd.com 69611308Santhony.gutierrez@amd.com code = code_formatter() 69711308Santhony.gutierrez@amd.com obj.swig_decl(code) 69811308Santhony.gutierrez@amd.com code.write(target[0].abspath) 69911308Santhony.gutierrez@amd.com 70011308Santhony.gutierrez@amd.com# dummy target for generated code 70111308Santhony.gutierrez@amd.com# we start out with all the Source files so they get copied to build/*/ also. 7024382Sbinkertn@umich.eduSWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 7034382Sbinkertn@umich.edu 7044762Snate@binkert.org# Generate all of the SimObject param C++ struct header files 7054762Snate@binkert.orgparams_hh_files = [] 7064762Snate@binkert.orgfor name,simobj in sorted(sim_objects.iteritems()): 7076654Snate@binkert.org py_source = PySource.modules[simobj.__module__] 7086654Snate@binkert.org extra_deps = [ py_source.tnode ] 7095517Snate@binkert.org 7105517Snate@binkert.org hh_file = File('params/%s.hh' % name) 7115517Snate@binkert.org params_hh_files.append(hh_file) 7125517Snate@binkert.org env.Command(hh_file, Value(name), 7135517Snate@binkert.org MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 7145517Snate@binkert.org env.Depends(hh_file, depends + extra_deps) 7155517Snate@binkert.org env.Depends(SWIG, hh_file) 7165517Snate@binkert.org 7175517Snate@binkert.org# C++ parameter description files 7185517Snate@binkert.orgif GetOption('with_cxx_config'): 7195517Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 7205517Snate@binkert.org py_source = PySource.modules[simobj.__module__] 7215517Snate@binkert.org extra_deps = [ py_source.tnode ] 7225517Snate@binkert.org 7235517Snate@binkert.org cxx_config_hh_file = File('cxx_config/%s.hh' % name) 7245517Snate@binkert.org cxx_config_cc_file = File('cxx_config/%s.cc' % name) 7255517Snate@binkert.org env.Command(cxx_config_hh_file, Value(name), 7266654Snate@binkert.org MakeAction(createSimObjectCxxConfig(True), 7275517Snate@binkert.org Transform("CXXCPRHH"))) 7285517Snate@binkert.org env.Command(cxx_config_cc_file, Value(name), 7295517Snate@binkert.org MakeAction(createSimObjectCxxConfig(False), 7305517Snate@binkert.org Transform("CXXCPRCC"))) 7315517Snate@binkert.org env.Depends(cxx_config_hh_file, depends + extra_deps + 73211802Sandreas.sandberg@arm.com [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 7335517Snate@binkert.org env.Depends(cxx_config_cc_file, depends + extra_deps + 7345517Snate@binkert.org [cxx_config_hh_file]) 7356143Snate@binkert.org Source(cxx_config_cc_file) 7366654Snate@binkert.org 7375517Snate@binkert.org cxx_config_init_cc_file = File('cxx_config/init.cc') 7385517Snate@binkert.org 7395517Snate@binkert.org def createCxxConfigInitCC(target, source, env): 7405517Snate@binkert.org assert len(target) == 1 and len(source) == 1 7415517Snate@binkert.org 7425517Snate@binkert.org code = code_formatter() 7435517Snate@binkert.org 7445517Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 7455517Snate@binkert.org if not hasattr(simobj, 'abstract') or not simobj.abstract: 7465517Snate@binkert.org code('#include "cxx_config/${name}.hh"') 7475517Snate@binkert.org code() 7485517Snate@binkert.org code('void cxxConfigInit()') 7495517Snate@binkert.org code('{') 7505517Snate@binkert.org code.indent() 7516654Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()): 7526654Snate@binkert.org not_abstract = not hasattr(simobj, 'abstract') or \ 7535517Snate@binkert.org not simobj.abstract 7545517Snate@binkert.org if not_abstract and 'type' in simobj.__dict__: 7556143Snate@binkert.org code('cxx_config_directory["${name}"] = ' 7566143Snate@binkert.org '${name}CxxConfigParams::makeDirectoryEntry();') 7576143Snate@binkert.org code.dedent() 7586727Ssteve.reinhardt@amd.com code('}') 7595517Snate@binkert.org code.write(target[0].abspath) 7606727Ssteve.reinhardt@amd.com 7615517Snate@binkert.org py_source = PySource.modules[simobj.__module__] 7625517Snate@binkert.org extra_deps = [ py_source.tnode ] 7635517Snate@binkert.org env.Command(cxx_config_init_cc_file, Value(name), 7646654Snate@binkert.org MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 7656654Snate@binkert.org cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 7667673Snate@binkert.org for name,simobj in sorted(sim_objects.iteritems()) 7676654Snate@binkert.org if not hasattr(simobj, 'abstract') or not simobj.abstract] 7686654Snate@binkert.org Depends(cxx_config_init_cc_file, cxx_param_hh_files + 7696654Snate@binkert.org [File('sim/cxx_config.hh')]) 7706654Snate@binkert.org Source(cxx_config_init_cc_file) 7715517Snate@binkert.org 7725517Snate@binkert.org# Generate any needed param SWIG wrapper files 7735517Snate@binkert.orgparams_i_files = [] 7746143Snate@binkert.orgfor name,param in sorted(params_to_swig.iteritems()): 7755517Snate@binkert.org i_file = File('python/m5/internal/%s.i' % (param.swig_module_name())) 7764762Snate@binkert.org params_i_files.append(i_file) 7775517Snate@binkert.org env.Command(i_file, Value(name), 7785517Snate@binkert.org MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 7796143Snate@binkert.org env.Depends(i_file, depends) 7806143Snate@binkert.org env.Depends(SWIG, i_file) 7815517Snate@binkert.org SwigSource('m5.internal', i_file) 7825517Snate@binkert.org 7835517Snate@binkert.org# Generate all enum header files 7845517Snate@binkert.orgfor name,enum in sorted(all_enums.iteritems()): 7855517Snate@binkert.org py_source = PySource.modules[enum.__module__] 7865517Snate@binkert.org extra_deps = [ py_source.tnode ] 7875517Snate@binkert.org 7885517Snate@binkert.org cc_file = File('enums/%s.cc' % name) 7895517Snate@binkert.org env.Command(cc_file, Value(name), 7906143Snate@binkert.org MakeAction(createEnumStrings, Transform("ENUM STR"))) 7915517Snate@binkert.org env.Depends(cc_file, depends + extra_deps) 7926654Snate@binkert.org env.Depends(SWIG, cc_file) 7936654Snate@binkert.org Source(cc_file) 7946654Snate@binkert.org 7956654Snate@binkert.org hh_file = File('enums/%s.hh' % name) 7966654Snate@binkert.org env.Command(hh_file, Value(name), 7976654Snate@binkert.org MakeAction(createEnumDecls, Transform("ENUMDECL"))) 7984762Snate@binkert.org env.Depends(hh_file, depends + extra_deps) 7994762Snate@binkert.org env.Depends(SWIG, hh_file) 8004762Snate@binkert.org 8014762Snate@binkert.org i_file = File('python/m5/internal/enum_%s.i' % name) 8024762Snate@binkert.org env.Command(i_file, Value(name), 8037675Snate@binkert.org MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 80410584Sandreas.hansson@arm.com env.Depends(i_file, depends + extra_deps) 8054762Snate@binkert.org env.Depends(SWIG, i_file) 8064762Snate@binkert.org SwigSource('m5.internal', i_file) 8074762Snate@binkert.org 8084762Snate@binkert.org# Generate SimObject SWIG wrapper files 8094382Sbinkertn@umich.edufor name,simobj in sorted(sim_objects.iteritems()): 8104382Sbinkertn@umich.edu py_source = PySource.modules[simobj.__module__] 8115517Snate@binkert.org extra_deps = [ py_source.tnode ] 8126654Snate@binkert.org i_file = File('python/m5/internal/param_%s.i' % name) 8135517Snate@binkert.org env.Command(i_file, Value(name), 8148126Sgblack@eecs.umich.edu MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 8156654Snate@binkert.org env.Depends(i_file, depends + extra_deps) 8167673Snate@binkert.org SwigSource('m5.internal', i_file) 8176654Snate@binkert.org 81811802Sandreas.sandberg@arm.com# Generate the main swig init file 8196654Snate@binkert.orgdef makeEmbeddedSwigInit(target, source, env): 8206654Snate@binkert.org code = code_formatter() 8216654Snate@binkert.org module = source[0].get_contents() 8226654Snate@binkert.org code('''\ 82311802Sandreas.sandberg@arm.com#include "sim/init.hh" 8246669Snate@binkert.org 82511802Sandreas.sandberg@arm.comextern "C" { 8266669Snate@binkert.org void init_${module}(); 8276669Snate@binkert.org} 8286669Snate@binkert.org 8296669Snate@binkert.orgEmbeddedSwig embed_swig_${module}(init_${module}); 8306654Snate@binkert.org''') 8317673Snate@binkert.org code.write(str(target[0])) 8325517Snate@binkert.org 8338126Sgblack@eecs.umich.edu# Build all swig modules 8345798Snate@binkert.orgfor swig in SwigSource.all: 8357756SAli.Saidi@ARM.com env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 8367816Ssteve.reinhardt@amd.com MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 8375798Snate@binkert.org '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 8385798Snate@binkert.org cc_file = str(swig.tnode) 8395517Snate@binkert.org init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 8405517Snate@binkert.org env.Command(init_file, Value(swig.module), 8417673Snate@binkert.org MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) 8425517Snate@binkert.org env.Depends(SWIG, init_file) 8435517Snate@binkert.org Source(init_file, **swig.guards) 8447673Snate@binkert.org 8457673Snate@binkert.org# Build all protocol buffers if we have got protoc and protobuf available 8465517Snate@binkert.orgif env['HAVE_PROTOBUF']: 8475798Snate@binkert.org for proto in ProtoBuf.all: 8485798Snate@binkert.org # Use both the source and header as the target, and the .proto 8498333Snate@binkert.org # file as the source. When executing the protoc compiler, also 8507816Ssteve.reinhardt@amd.com # specify the proto_path to avoid having the generated files 8515798Snate@binkert.org # include the path. 8525798Snate@binkert.org env.Command([proto.cc_file, proto.hh_file], proto.tnode, 8534762Snate@binkert.org MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 8544762Snate@binkert.org '--proto_path ${SOURCE.dir} $SOURCE', 8554762Snate@binkert.org Transform("PROTOC"))) 8564762Snate@binkert.org 8574762Snate@binkert.org env.Depends(SWIG, [proto.cc_file, proto.hh_file]) 8588596Ssteve.reinhardt@amd.com # Add the C++ source file 8595517Snate@binkert.org Source(proto.cc_file, **proto.guards) 8605517Snate@binkert.orgelif ProtoBuf.all: 86111997Sgabeblack@google.com print 'Got protobuf to build, but lacks support!' 8625517Snate@binkert.org Exit(1) 8635517Snate@binkert.org 8647673Snate@binkert.org# 8658596Ssteve.reinhardt@amd.com# Handle debug flags 8667673Snate@binkert.org# 8675517Snate@binkert.orgdef makeDebugFlagCC(target, source, env): 86810458Sandreas.hansson@arm.com assert(len(target) == 1 and len(source) == 1) 86910458Sandreas.hansson@arm.com 87010458Sandreas.hansson@arm.com code = code_formatter() 87110458Sandreas.hansson@arm.com 87210458Sandreas.hansson@arm.com # delay definition of CompoundFlags until after all the definition 87310458Sandreas.hansson@arm.com # of all constituent SimpleFlags 87410458Sandreas.hansson@arm.com comp_code = code_formatter() 87510458Sandreas.hansson@arm.com 87610458Sandreas.hansson@arm.com # file header 87710458Sandreas.hansson@arm.com code(''' 87810458Sandreas.hansson@arm.com/* 87910458Sandreas.hansson@arm.com * DO NOT EDIT THIS FILE! Automatically generated by SCons. 8805517Snate@binkert.org */ 88111996Sgabeblack@google.com 8825517Snate@binkert.org#include "base/debug.hh" 88311997Sgabeblack@google.com 88411996Sgabeblack@google.comnamespace Debug { 8855517Snate@binkert.org 8865517Snate@binkert.org''') 8877673Snate@binkert.org 8887673Snate@binkert.org for name, flag in sorted(source[0].read().iteritems()): 88911996Sgabeblack@google.com n, compound, desc = flag 89011988Sandreas.sandberg@arm.com assert n == name 8917673Snate@binkert.org 8925517Snate@binkert.org if not compound: 8938596Ssteve.reinhardt@amd.com code('SimpleFlag $name("$name", "$desc");') 8945517Snate@binkert.org else: 8955517Snate@binkert.org comp_code('CompoundFlag $name("$name", "$desc",') 89611997Sgabeblack@google.com comp_code.indent() 8975517Snate@binkert.org last = len(compound) - 1 8985517Snate@binkert.org for i,flag in enumerate(compound): 8997673Snate@binkert.org if i != last: 9007673Snate@binkert.org comp_code('&$flag,') 9017673Snate@binkert.org else: 9025517Snate@binkert.org comp_code('&$flag);') 90311988Sandreas.sandberg@arm.com comp_code.dedent() 90411997Sgabeblack@google.com 9058596Ssteve.reinhardt@amd.com code.append(comp_code) 9068596Ssteve.reinhardt@amd.com code() 9078596Ssteve.reinhardt@amd.com code('} // namespace Debug') 90811988Sandreas.sandberg@arm.com 9098596Ssteve.reinhardt@amd.com code.write(str(target[0])) 9108596Ssteve.reinhardt@amd.com 9118596Ssteve.reinhardt@amd.comdef makeDebugFlagHH(target, source, env): 9124762Snate@binkert.org assert(len(target) == 1 and len(source) == 1) 9136143Snate@binkert.org 9146143Snate@binkert.org val = eval(source[0].get_contents()) 9156143Snate@binkert.org name, compound, desc = val 9164762Snate@binkert.org 9174762Snate@binkert.org code = code_formatter() 9184762Snate@binkert.org 9197756SAli.Saidi@ARM.com # file header boilerplate 9208596Ssteve.reinhardt@amd.com code('''\ 9214762Snate@binkert.org/* 9224762Snate@binkert.org * DO NOT EDIT THIS FILE! Automatically generated by SCons. 92310458Sandreas.hansson@arm.com */ 92410458Sandreas.hansson@arm.com 92510458Sandreas.hansson@arm.com#ifndef __DEBUG_${name}_HH__ 92610458Sandreas.hansson@arm.com#define __DEBUG_${name}_HH__ 92710458Sandreas.hansson@arm.com 92810458Sandreas.hansson@arm.comnamespace Debug { 92910458Sandreas.hansson@arm.com''') 93010458Sandreas.hansson@arm.com 93110458Sandreas.hansson@arm.com if compound: 93210458Sandreas.hansson@arm.com code('class CompoundFlag;') 93310458Sandreas.hansson@arm.com code('class SimpleFlag;') 93410458Sandreas.hansson@arm.com 93510458Sandreas.hansson@arm.com if compound: 93610458Sandreas.hansson@arm.com code('extern CompoundFlag $name;') 93710458Sandreas.hansson@arm.com for flag in compound: 93810458Sandreas.hansson@arm.com code('extern SimpleFlag $flag;') 93910458Sandreas.hansson@arm.com else: 94010458Sandreas.hansson@arm.com code('extern SimpleFlag $name;') 94110458Sandreas.hansson@arm.com 94210458Sandreas.hansson@arm.com code(''' 94310458Sandreas.hansson@arm.com} 94410458Sandreas.hansson@arm.com 94510458Sandreas.hansson@arm.com#endif // __DEBUG_${name}_HH__ 94610458Sandreas.hansson@arm.com''') 94710458Sandreas.hansson@arm.com 94810458Sandreas.hansson@arm.com code.write(str(target[0])) 94910458Sandreas.hansson@arm.com 95010458Sandreas.hansson@arm.comfor name,flag in sorted(debug_flags.iteritems()): 95110458Sandreas.hansson@arm.com n, compound, desc = flag 95210458Sandreas.hansson@arm.com assert n == name 95310458Sandreas.hansson@arm.com 95410458Sandreas.hansson@arm.com hh_file = 'debug/%s.hh' % name 95510458Sandreas.hansson@arm.com env.Command(hh_file, Value(flag), 95610458Sandreas.hansson@arm.com MakeAction(makeDebugFlagHH, Transform("TRACING", 0))) 95710458Sandreas.hansson@arm.com env.Depends(SWIG, hh_file) 95810458Sandreas.hansson@arm.com 95910458Sandreas.hansson@arm.comenv.Command('debug/flags.cc', Value(debug_flags), 96010458Sandreas.hansson@arm.com MakeAction(makeDebugFlagCC, Transform("TRACING", 0))) 96110458Sandreas.hansson@arm.comenv.Depends(SWIG, 'debug/flags.cc') 96210458Sandreas.hansson@arm.comSource('debug/flags.cc') 96310458Sandreas.hansson@arm.com 96410458Sandreas.hansson@arm.com# version tags 96510458Sandreas.hansson@arm.comenv.Command('sim/tags.cc', None, 96610458Sandreas.hansson@arm.com MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 96710458Sandreas.hansson@arm.com Transform("VER TAGS"))) 96810458Sandreas.hansson@arm.com 96910458Sandreas.hansson@arm.com# Embed python files. All .py files that have been indicated by a 97010458Sandreas.hansson@arm.com# PySource() call in a SConscript need to be embedded into the M5 97110458Sandreas.hansson@arm.com# library. To do that, we compile the file to byte code, marshal the 97210584Sandreas.hansson@arm.com# byte code, compress it, and then generate a c++ file that 97310458Sandreas.hansson@arm.com# inserts the result into an array. 97410458Sandreas.hansson@arm.comdef embedPyFile(target, source, env): 97510458Sandreas.hansson@arm.com def c_str(string): 97610458Sandreas.hansson@arm.com if string is None: 97710458Sandreas.hansson@arm.com return "0" 9784762Snate@binkert.org return '"%s"' % string 9796143Snate@binkert.org 9806143Snate@binkert.org '''Action function to compile a .py into a code object, marshal 9816143Snate@binkert.org it, compress it, and stick it into an asm file so the code appears 9824762Snate@binkert.org as just bytes with a label in the data section''' 9834762Snate@binkert.org 98411996Sgabeblack@google.com src = file(str(source[0]), 'r').read() 9857816Ssteve.reinhardt@amd.com 9864762Snate@binkert.org pysource = PySource.tnodes[source[0]] 9874762Snate@binkert.org compiled = compile(src, pysource.abspath, 'exec') 9884762Snate@binkert.org marshalled = marshal.dumps(compiled) 9894762Snate@binkert.org compressed = zlib.compress(marshalled) 9907756SAli.Saidi@ARM.com data = compressed 9918596Ssteve.reinhardt@amd.com sym = pysource.symname 9924762Snate@binkert.org 9934762Snate@binkert.org code = code_formatter() 99411988Sandreas.sandberg@arm.com code('''\ 99511988Sandreas.sandberg@arm.com#include "sim/init.hh" 99611988Sandreas.sandberg@arm.com 99711988Sandreas.sandberg@arm.comnamespace { 99811988Sandreas.sandberg@arm.com 99911988Sandreas.sandberg@arm.comconst uint8_t data_${sym}[] = { 100011988Sandreas.sandberg@arm.com''') 100111988Sandreas.sandberg@arm.com code.indent() 100211988Sandreas.sandberg@arm.com step = 16 100311988Sandreas.sandberg@arm.com for i in xrange(0, len(data), step): 100411988Sandreas.sandberg@arm.com x = array.array('B', data[i:i+step]) 10054382Sbinkertn@umich.edu code(''.join('%d,' % d for d in x)) 10069396Sandreas.hansson@arm.com code.dedent() 10079396Sandreas.hansson@arm.com 10089396Sandreas.hansson@arm.com code('''}; 10099396Sandreas.hansson@arm.com 10109396Sandreas.hansson@arm.comEmbeddedPython embedded_${sym}( 10119396Sandreas.hansson@arm.com ${{c_str(pysource.arcname)}}, 10129396Sandreas.hansson@arm.com ${{c_str(pysource.abspath)}}, 10139396Sandreas.hansson@arm.com ${{c_str(pysource.modpath)}}, 10149396Sandreas.hansson@arm.com data_${sym}, 10159396Sandreas.hansson@arm.com ${{len(data)}}, 10169396Sandreas.hansson@arm.com ${{len(marshalled)}}); 10179396Sandreas.hansson@arm.com 10189396Sandreas.hansson@arm.com} // anonymous namespace 101912302Sgabeblack@google.com''') 10209396Sandreas.hansson@arm.com code.write(str(target[0])) 102112563Sgabeblack@google.com 10229396Sandreas.hansson@arm.comfor source in PySource.all: 10239396Sandreas.hansson@arm.com env.Command(source.cpp, source.tnode, 10248232Snate@binkert.org MakeAction(embedPyFile, Transform("EMBED PY"))) 10258232Snate@binkert.org env.Depends(SWIG, source.cpp) 10268232Snate@binkert.org Source(source.cpp, skip_no_python=True) 10278232Snate@binkert.org 10288232Snate@binkert.org######################################################################## 10296229Snate@binkert.org# 103010455SCurtis.Dunham@arm.com# Define binaries. Each different build type (debug, opt, etc.) gets 10316229Snate@binkert.org# a slightly different build environment. 103210455SCurtis.Dunham@arm.com# 103310455SCurtis.Dunham@arm.com 103410455SCurtis.Dunham@arm.com# List of constructed environments to pass back to SConstruct 10355517Snate@binkert.orgdate_source = Source('base/date.cc', skip_lib=True) 10365517Snate@binkert.org 10377673Snate@binkert.org# Capture this directory for the closure makeEnv, otherwise when it is 10385517Snate@binkert.org# called, it won't know what directory it should use. 103910455SCurtis.Dunham@arm.comvariant_dir = Dir('.').path 10405517Snate@binkert.orgdef variant(*path): 10415517Snate@binkert.org return os.path.join(variant_dir, *path) 10428232Snate@binkert.orgdef variantd(*path): 104310455SCurtis.Dunham@arm.com return variant(*path)+'/' 104410455SCurtis.Dunham@arm.com 104510455SCurtis.Dunham@arm.com# Function to create a new build environment as clone of current 10467673Snate@binkert.org# environment 'env' with modified object suffix and optional stripped 10477673Snate@binkert.org# binary. Additional keyword arguments are appended to corresponding 104810455SCurtis.Dunham@arm.com# build environment vars. 104910455SCurtis.Dunham@arm.comdef makeEnv(env, label, objsfx, strip = False, **kwargs): 105010455SCurtis.Dunham@arm.com # SCons doesn't know to append a library suffix when there is a '.' in the 10515517Snate@binkert.org # name. Use '_' instead. 105210455SCurtis.Dunham@arm.com libname = variant('gem5_' + label) 105310455SCurtis.Dunham@arm.com exename = variant('gem5.' + label) 105410455SCurtis.Dunham@arm.com secondary_exename = variant('m5.' + label) 105510455SCurtis.Dunham@arm.com 105610455SCurtis.Dunham@arm.com new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 105710455SCurtis.Dunham@arm.com new_env.Label = label 105810455SCurtis.Dunham@arm.com new_env.Append(**kwargs) 105910455SCurtis.Dunham@arm.com 106010685Sandreas.hansson@arm.com swig_env = new_env.Clone() 106110455SCurtis.Dunham@arm.com 106210685Sandreas.hansson@arm.com # Both gcc and clang have issues with unused labels and values in 106310455SCurtis.Dunham@arm.com # the SWIG generated code 10645517Snate@binkert.org swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 106510455SCurtis.Dunham@arm.com 10668232Snate@binkert.org if env['GCC']: 10678232Snate@binkert.org # Depending on the SWIG version, we also need to supress 10685517Snate@binkert.org # warnings about uninitialized variables and missing field 10697673Snate@binkert.org # initializers. 10705517Snate@binkert.org swig_env.Append(CCFLAGS=['-Wno-uninitialized', 10718232Snate@binkert.org '-Wno-missing-field-initializers', 10728232Snate@binkert.org '-Wno-unused-but-set-variable', 10735517Snate@binkert.org '-Wno-maybe-uninitialized', 10748232Snate@binkert.org '-Wno-type-limits']) 10758232Snate@binkert.org 10768232Snate@binkert.org # Only gcc >= 4.9 supports UBSan, so check both the version 10777673Snate@binkert.org # and the command-line option before adding the compiler and 10785517Snate@binkert.org # linker flags. 10795517Snate@binkert.org if GetOption('with_ubsan') and \ 10807673Snate@binkert.org compareVersions(env['GCC_VERSION'], '4.9') >= 0: 10815517Snate@binkert.org new_env.Append(CCFLAGS='-fsanitize=undefined') 108210455SCurtis.Dunham@arm.com new_env.Append(LINKFLAGS='-fsanitize=undefined') 10835517Snate@binkert.org 10845517Snate@binkert.org if env['CLANG']: 10858232Snate@binkert.org swig_env.Append(CCFLAGS=['-Wno-sometimes-uninitialized', 10868232Snate@binkert.org '-Wno-deprecated-register', 10875517Snate@binkert.org '-Wno-tautological-compare']) 10888232Snate@binkert.org 10898232Snate@binkert.org # All supported clang versions have support for UBSan, so if 10905517Snate@binkert.org # asked to use it, append the compiler and linker flags. 10918232Snate@binkert.org if GetOption('with_ubsan'): 10928232Snate@binkert.org new_env.Append(CCFLAGS='-fsanitize=undefined') 10938232Snate@binkert.org new_env.Append(LINKFLAGS='-fsanitize=undefined') 10945517Snate@binkert.org 10958232Snate@binkert.org werror_env = new_env.Clone() 10968232Snate@binkert.org # Treat warnings as errors but white list some warnings that we 10978232Snate@binkert.org # want to allow (e.g., deprecation warnings). 10988232Snate@binkert.org werror_env.Append(CCFLAGS=['-Werror', 10998232Snate@binkert.org '-Wno-error=deprecated-declarations', 11008232Snate@binkert.org '-Wno-error=deprecated', 11015517Snate@binkert.org ]) 11028232Snate@binkert.org 11038232Snate@binkert.org def make_obj(source, static, extra_deps = None): 11045517Snate@binkert.org '''This function adds the specified source to the correct 11058232Snate@binkert.org build environment, and returns the corresponding SCons Object 11067673Snate@binkert.org nodes''' 11075517Snate@binkert.org 11087673Snate@binkert.org if source.swig: 11095517Snate@binkert.org env = swig_env 11108232Snate@binkert.org elif source.Werror: 11118232Snate@binkert.org env = werror_env 11128232Snate@binkert.org else: 11135192Ssaidi@eecs.umich.edu env = new_env 111410454SCurtis.Dunham@arm.com 111510454SCurtis.Dunham@arm.com if static: 11168232Snate@binkert.org obj = env.StaticObject(source.tnode) 111710455SCurtis.Dunham@arm.com else: 111810455SCurtis.Dunham@arm.com obj = env.SharedObject(source.tnode) 111910455SCurtis.Dunham@arm.com 112010455SCurtis.Dunham@arm.com if extra_deps: 11215192Ssaidi@eecs.umich.edu env.Depends(obj, extra_deps) 112211077SCurtis.Dunham@arm.com 112311330SCurtis.Dunham@arm.com return obj 112411077SCurtis.Dunham@arm.com 112511077SCurtis.Dunham@arm.com lib_guards = {'main': False, 'skip_lib': False} 112611077SCurtis.Dunham@arm.com 112711330SCurtis.Dunham@arm.com # Without Python, leave out all SWIG and Python content from the 112811077SCurtis.Dunham@arm.com # library builds. The option doesn't affect gem5 built as a program 11297674Snate@binkert.org if GetOption('without_python'): 11305522Snate@binkert.org lib_guards['skip_no_python'] = False 11315522Snate@binkert.org 11327674Snate@binkert.org static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] 11337674Snate@binkert.org shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] 11347674Snate@binkert.org 11357674Snate@binkert.org static_date = make_obj(date_source, static=True, extra_deps=static_objs) 11367674Snate@binkert.org static_objs.append(static_date) 11377674Snate@binkert.org 11387674Snate@binkert.org shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 11397674Snate@binkert.org shared_objs.append(shared_date) 11405522Snate@binkert.org 11415522Snate@binkert.org # First make a library of everything but main() so other programs can 11425522Snate@binkert.org # link against m5. 11435517Snate@binkert.org static_lib = new_env.StaticLibrary(libname, static_objs) 11445522Snate@binkert.org shared_lib = new_env.SharedLibrary(libname, shared_objs) 11455517Snate@binkert.org 11466143Snate@binkert.org # Now link a stub with main() and the static library. 11476727Ssteve.reinhardt@amd.com main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 11485522Snate@binkert.org 11495522Snate@binkert.org for test in UnitTest.all: 11505522Snate@binkert.org flags = { test.target : True } 11517674Snate@binkert.org test_sources = Source.get(**flags) 11525517Snate@binkert.org test_objs = [ make_obj(s, static=True) for s in test_sources ] 11537673Snate@binkert.org if test.main: 11547673Snate@binkert.org test_objs += main_objs 11557674Snate@binkert.org path = variant('unittest/%s.%s' % (test.target, label)) 11567673Snate@binkert.org new_env.Program(path, test_objs + static_objs) 11577674Snate@binkert.org 11587674Snate@binkert.org progname = exename 11597674Snate@binkert.org if strip: 116013576Sciro.santilli@arm.com progname += '.unstripped' 116113576Sciro.santilli@arm.com 116211308Santhony.gutierrez@amd.com targets = new_env.Program(progname, main_objs + static_objs) 11637673Snate@binkert.org 11647674Snate@binkert.org if strip: 11657674Snate@binkert.org if sys.platform == 'sunos5': 11667674Snate@binkert.org cmd = 'cp $SOURCE $TARGET; strip $TARGET' 11677674Snate@binkert.org else: 11687674Snate@binkert.org cmd = 'strip $SOURCE -o $TARGET' 11697674Snate@binkert.org targets = new_env.Command(exename, progname, 11707674Snate@binkert.org MakeAction(cmd, Transform("STRIP"))) 11717674Snate@binkert.org 11727811Ssteve.reinhardt@amd.com new_env.Command(secondary_exename, exename, 11737674Snate@binkert.org MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 11747673Snate@binkert.org 11755522Snate@binkert.org new_env.M5Binary = targets[0] 11766143Snate@binkert.org return new_env 117710453SAndrew.Bardsley@arm.com 11787816Ssteve.reinhardt@amd.com# Start out with the compiler flags common to all compilers, 117912302Sgabeblack@google.com# i.e. they all use -g for opt and -g -pg for prof 11804382Sbinkertn@umich.educcflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 11814382Sbinkertn@umich.edu 'perf' : ['-g']} 11824382Sbinkertn@umich.edu 11834382Sbinkertn@umich.edu# Start out with the linker flags common to all linkers, i.e. -pg for 11844382Sbinkertn@umich.edu# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 11854382Sbinkertn@umich.edu# no-as-needed and as-needed as the binutils linker is too clever and 11864382Sbinkertn@umich.edu# simply doesn't link to the library otherwise. 11874382Sbinkertn@umich.eduldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 118812302Sgabeblack@google.com 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 11894382Sbinkertn@umich.edu 119012797Sgabeblack@google.com# For Link Time Optimization, the optimisation flags used to compile 119112797Sgabeblack@google.com# individual files are decoupled from those used at link time 11922655Sstever@eecs.umich.edu# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 11932655Sstever@eecs.umich.edu# to also update the linker flags based on the target. 11942655Sstever@eecs.umich.eduif env['GCC']: 11952655Sstever@eecs.umich.edu if sys.platform == 'sunos5': 119612063Sgabeblack@google.com ccflags['debug'] += ['-gstabs+'] 11975601Snate@binkert.org else: 11985601Snate@binkert.org ccflags['debug'] += ['-ggdb3'] 119912222Sgabeblack@google.com ldflags['debug'] += ['-O0'] 120012222Sgabeblack@google.com # opt, fast, prof and perf all share the same cc flags, also add 12015522Snate@binkert.org # the optimization to the ldflags as LTO defers the optimization 12025863Snate@binkert.org # to link time 12035601Snate@binkert.org for target in ['opt', 'fast', 'prof', 'perf']: 12045601Snate@binkert.org ccflags[target] += ['-O3'] 12055601Snate@binkert.org ldflags[target] += ['-O3'] 120612302Sgabeblack@google.com 120710453SAndrew.Bardsley@arm.com ccflags['fast'] += env['LTO_CCFLAGS'] 120811988Sandreas.sandberg@arm.com ldflags['fast'] += env['LTO_LDFLAGS'] 120911988Sandreas.sandberg@arm.comelif env['CLANG']: 121010453SAndrew.Bardsley@arm.com ccflags['debug'] += ['-g', '-O0'] 121112302Sgabeblack@google.com # opt, fast, prof and perf all share the same cc flags 121210453SAndrew.Bardsley@arm.com for target in ['opt', 'fast', 'prof', 'perf']: 121311983Sgabeblack@google.com ccflags[target] += ['-O3'] 121411983Sgabeblack@google.comelse: 121512302Sgabeblack@google.com print 'Unknown compiler, please fix compiler options' 121612302Sgabeblack@google.com Exit(1) 121712362Sgabeblack@google.com 121812362Sgabeblack@google.com 121911983Sgabeblack@google.com# To speed things up, we only instantiate the build environments we 122012302Sgabeblack@google.com# need. We try to identify the needed environment for each target; if 122112302Sgabeblack@google.com# we can't, we fall back on instantiating all the environments just to 122211983Sgabeblack@google.com# be safe. 122311983Sgabeblack@google.comtarget_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 122411983Sgabeblack@google.comobj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 122512362Sgabeblack@google.com 'gpo' : 'perf'} 122612362Sgabeblack@google.com 122712310Sgabeblack@google.comdef identifyTarget(t): 122812063Sgabeblack@google.com ext = t.split('.')[-1] 122912063Sgabeblack@google.com if ext in target_types: 123012063Sgabeblack@google.com return ext 123112310Sgabeblack@google.com if obj2target.has_key(ext): 123212310Sgabeblack@google.com return obj2target[ext] 123312063Sgabeblack@google.com match = re.search(r'/tests/([^/]+)/', t) 123412063Sgabeblack@google.com if match and match.group(1) in target_types: 123511983Sgabeblack@google.com return match.group(1) 123611983Sgabeblack@google.com return 'all' 123711983Sgabeblack@google.com 123812310Sgabeblack@google.comneeded_envs = [identifyTarget(target) for target in BUILD_TARGETS] 123912310Sgabeblack@google.comif 'all' in needed_envs: 124011983Sgabeblack@google.com needed_envs += target_types 124111983Sgabeblack@google.com 124211983Sgabeblack@google.comgem5_root = Dir('.').up().up().abspath 124311983Sgabeblack@google.comdef makeEnvirons(target, source, env): 124412310Sgabeblack@google.com # cause any later Source() calls to be fatal, as a diagnostic. 124512310Sgabeblack@google.com Source.done() 12466143Snate@binkert.org 124712362Sgabeblack@google.com envList = [] 124812306Sgabeblack@google.com 124912310Sgabeblack@google.com # Debug binary 125010453SAndrew.Bardsley@arm.com if 'debug' in needed_envs: 125112362Sgabeblack@google.com envList.append( 125212306Sgabeblack@google.com makeEnv(env, 'debug', '.do', 125312310Sgabeblack@google.com CCFLAGS = Split(ccflags['debug']), 12545554Snate@binkert.org CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 125512797Sgabeblack@google.com LINKFLAGS = Split(ldflags['debug']))) 125612797Sgabeblack@google.com 12575522Snate@binkert.org # Optimized binary 12585522Snate@binkert.org if 'opt' in needed_envs: 12595797Snate@binkert.org envList.append( 12605797Snate@binkert.org makeEnv(env, 'opt', '.o', 12615522Snate@binkert.org CCFLAGS = Split(ccflags['opt']), 126212797Sgabeblack@google.com CPPDEFINES = ['TRACING_ON=1'], 126312797Sgabeblack@google.com LINKFLAGS = Split(ldflags['opt']))) 126412797Sgabeblack@google.com 126512797Sgabeblack@google.com # "Fast" binary 126612797Sgabeblack@google.com if 'fast' in needed_envs: 12678233Snate@binkert.org envList.append( 126812797Sgabeblack@google.com makeEnv(env, 'fast', '.fo', strip = True, 126912797Sgabeblack@google.com CCFLAGS = Split(ccflags['fast']), 12708235Snate@binkert.org CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 127112797Sgabeblack@google.com LINKFLAGS = Split(ldflags['fast']))) 127212797Sgabeblack@google.com 127312797Sgabeblack@google.com # Profiled binary using gprof 127412370Sgabeblack@google.com if 'prof' in needed_envs: 127512797Sgabeblack@google.com envList.append( 127612797Sgabeblack@google.com makeEnv(env, 'prof', '.po', 127712313Sgabeblack@google.com CCFLAGS = Split(ccflags['prof']), 127812797Sgabeblack@google.com CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 12796143Snate@binkert.org LINKFLAGS = Split(ldflags['prof']))) 128012797Sgabeblack@google.com 12818334Snate@binkert.org # Profiled binary using google-pprof 12828334Snate@binkert.org if 'perf' in needed_envs: 128311993Sgabeblack@google.com envList.append( 128411993Sgabeblack@google.com makeEnv(env, 'perf', '.gpo', 128512223Sgabeblack@google.com CCFLAGS = Split(ccflags['perf']), 128611993Sgabeblack@google.com CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 12872655Sstever@eecs.umich.edu LINKFLAGS = Split(ldflags['perf']))) 12889225Sandreas.hansson@arm.com 12899225Sandreas.hansson@arm.com # Set up the regression tests for each build. 12909226Sandreas.hansson@arm.com for e in envList: 12919226Sandreas.hansson@arm.com SConscript(os.path.join(gem5_root, 'tests', 'SConscript'), 12929225Sandreas.hansson@arm.com variant_dir = variantd('tests', e.Label), 12939226Sandreas.hansson@arm.com exports = { 'env' : e }, duplicate = False) 12949226Sandreas.hansson@arm.com 12959226Sandreas.hansson@arm.com# The MakeEnvirons Builder defers the full dependency collection until 12969226Sandreas.hansson@arm.com# after processing the ISA definition (due to dynamically generated 12979226Sandreas.hansson@arm.com# source files). Add this dependency to all targets so they will wait 12989226Sandreas.hansson@arm.com# until the environments are completely set up. Otherwise, a second 12999225Sandreas.hansson@arm.com# process (e.g. -j2 or higher) will try to compile the requested target, 13009227Sandreas.hansson@arm.com# not know how, and fail. 13019227Sandreas.hansson@arm.comenv.Append(BUILDERS = {'MakeEnvirons' : 13029227Sandreas.hansson@arm.com Builder(action=MakeAction(makeEnvirons, 13039227Sandreas.hansson@arm.com Transform("ENVIRONS", 1)))}) 13048946Sandreas.hansson@arm.com 13053918Ssaidi@eecs.umich.eduisa_target = env['PHONY_BASE'] + '-deps' 13069225Sandreas.hansson@arm.comenvirons = env['PHONY_BASE'] + '-environs' 13073918Ssaidi@eecs.umich.eduenv.Depends('#all-deps', isa_target) 13089225Sandreas.hansson@arm.comenv.Depends('#all-environs', environs) 13099225Sandreas.hansson@arm.comenv.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 13109227Sandreas.hansson@arm.comenvSetup = env.MakeEnvirons(environs, isa_target) 13119227Sandreas.hansson@arm.com 13129227Sandreas.hansson@arm.com# make sure no -deps targets occur before all ISAs are complete 13139226Sandreas.hansson@arm.comenv.Depends(isa_target, '#all-isas') 13149225Sandreas.hansson@arm.com# likewise for -environs targets and all the -deps targets 13159227Sandreas.hansson@arm.comenv.Depends(environs, '#all-deps') 13169227Sandreas.hansson@arm.com