SConscript revision 6397
16145Snate@binkert.org# -*- mode:python -*- 210012Snilay@cs.wisc.edu 36145Snate@binkert.org# Copyright (c) 2004-2005 The Regents of The University of Michigan 46145Snate@binkert.org# All rights reserved. 56145Snate@binkert.org# 66145Snate@binkert.org# Redistribution and use in source and binary forms, with or without 76145Snate@binkert.org# modification, are permitted provided that the following conditions are 86145Snate@binkert.org# met: redistributions of source code must retain the above copyright 96145Snate@binkert.org# notice, this list of conditions and the following disclaimer; 106145Snate@binkert.org# redistributions in binary form must reproduce the above copyright 116145Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 126145Snate@binkert.org# documentation and/or other materials provided with the distribution; 136145Snate@binkert.org# neither the name of the copyright holders nor the names of its 146145Snate@binkert.org# contributors may be used to endorse or promote products derived from 156145Snate@binkert.org# this software without specific prior written permission. 166145Snate@binkert.org# 176145Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186145Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196145Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206145Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216145Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226145Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236145Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246145Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256145Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266145Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276145Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286145Snate@binkert.org# 296145Snate@binkert.org# Authors: Nathan Binkert 306145Snate@binkert.org 316145Snate@binkert.orgimport array 326145Snate@binkert.orgimport bisect 336145Snate@binkert.orgimport imp 346145Snate@binkert.orgimport marshal 356145Snate@binkert.orgimport os 366145Snate@binkert.orgimport re 376145Snate@binkert.orgimport sys 386145Snate@binkert.orgimport zlib 396145Snate@binkert.org 406145Snate@binkert.orgfrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 416145Snate@binkert.org 426145Snate@binkert.orgimport SCons 436145Snate@binkert.org 446145Snate@binkert.org# This file defines how to build a particular configuration of M5 4511309Sdavid.hashe@amd.com# based on variable settings in the 'env' build environment. 4611309Sdavid.hashe@amd.com 478946Sandreas.hansson@arm.comImport('*') 488946Sandreas.hansson@arm.com 497002Snate@binkert.org# Children need to see the environment 507454Snate@binkert.orgExport('env') 517832Snate@binkert.org 527454Snate@binkert.orgbuild_env = dict([(opt, env[opt]) for opt in export_vars]) 537454Snate@binkert.org 547056Snate@binkert.org######################################################################## 557048Snate@binkert.org# Code for adding source files of various types 567048Snate@binkert.org# 5714184Sgabeblack@google.comclass SourceMeta(type): 5814184Sgabeblack@google.com def __init__(cls, name, bases, dict): 5911798Santhony.gutierrez@amd.com super(SourceMeta, cls).__init__(name, bases, dict) 6011798Santhony.gutierrez@amd.com cls.all = [] 6111798Santhony.gutierrez@amd.com 6211798Santhony.gutierrez@amd.com def get(cls, **kwargs): 6311798Santhony.gutierrez@amd.com for src in cls.all: 6411798Santhony.gutierrez@amd.com for attr,value in kwargs.iteritems(): 6511798Santhony.gutierrez@amd.com if getattr(src, attr) != value: 6611798Santhony.gutierrez@amd.com break 6711798Santhony.gutierrez@amd.com else: 6811798Santhony.gutierrez@amd.com yield src 6911798Santhony.gutierrez@amd.com 7011798Santhony.gutierrez@amd.comclass SourceFile(object): 7111798Santhony.gutierrez@amd.com __metaclass__ = SourceMeta 7211798Santhony.gutierrez@amd.com def __init__(self, source): 7311798Santhony.gutierrez@amd.com tnode = source 7411309Sdavid.hashe@amd.com if not isinstance(source, SCons.Node.FS.File): 7514184Sgabeblack@google.com tnode = File(source) 7611798Santhony.gutierrez@amd.com 7711798Santhony.gutierrez@amd.com self.tnode = tnode 789598Snilay@cs.wisc.edu self.snode = tnode.srcnode() 796876Ssteve.reinhardt@amd.com self.filename = str(tnode) 807055Snate@binkert.org self.dirname = dirname(self.filename) 817454Snate@binkert.org self.basename = basename(self.filename) 827055Snate@binkert.org index = self.basename.rfind('.') 8310920Sbrandon.potter@amd.com if index <= 0: 8411172Snilay@cs.wisc.edu # dot files aren't extensions 8511172Snilay@cs.wisc.edu self.extname = self.basename, None 8611172Snilay@cs.wisc.edu else: 876145Snate@binkert.org self.extname = self.basename[:index], self.basename[index+1:] 8810919Sbrandon.potter@amd.com 897048Snate@binkert.org for base in type(self).__mro__: 907048Snate@binkert.org if issubclass(base, SourceFile): 916285Snate@binkert.org bisect.insort_right(base.all, self) 927048Snate@binkert.org 9310919Sbrandon.potter@amd.com def __lt__(self, other): return self.filename < other.filename 947048Snate@binkert.org def __le__(self, other): return self.filename <= other.filename 957048Snate@binkert.org def __gt__(self, other): return self.filename > other.filename 967048Snate@binkert.org def __ge__(self, other): return self.filename >= other.filename 976285Snate@binkert.org def __eq__(self, other): return self.filename == other.filename 986285Snate@binkert.org def __ne__(self, other): return self.filename != other.filename 996889SBrad.Beckmann@amd.com 1006889SBrad.Beckmann@amd.comclass Source(SourceFile): 1017048Snate@binkert.org '''Add a c/c++ source file to the build''' 1027048Snate@binkert.org def __init__(self, source, Werror=True, swig=False, bin_only=False, 1037048Snate@binkert.org skip_lib=False): 10410012Snilay@cs.wisc.edu super(Source, self).__init__(source) 1057048Snate@binkert.org 10610012Snilay@cs.wisc.edu self.Werror = Werror 10710012Snilay@cs.wisc.edu self.swig = swig 10810012Snilay@cs.wisc.edu self.bin_only = bin_only 10910012Snilay@cs.wisc.edu self.skip_lib = bin_only or skip_lib 11010012Snilay@cs.wisc.edu 11110012Snilay@cs.wisc.educlass PySource(SourceFile): 11210012Snilay@cs.wisc.edu '''Add a python source file to the named package''' 11310012Snilay@cs.wisc.edu invalid_sym_char = re.compile('[^A-z0-9_]') 11410012Snilay@cs.wisc.edu modules = {} 11510012Snilay@cs.wisc.edu tnodes = {} 11610012Snilay@cs.wisc.edu symnames = {} 11710012Snilay@cs.wisc.edu 11810012Snilay@cs.wisc.edu def __init__(self, package, source): 11910012Snilay@cs.wisc.edu super(PySource, self).__init__(source) 12011172Snilay@cs.wisc.edu 12110012Snilay@cs.wisc.edu modname,ext = self.extname 12210012Snilay@cs.wisc.edu assert ext == 'py' 12310012Snilay@cs.wisc.edu 12410012Snilay@cs.wisc.edu if package: 12510012Snilay@cs.wisc.edu path = package.split('.') 12610012Snilay@cs.wisc.edu else: 12710012Snilay@cs.wisc.edu path = [] 12810012Snilay@cs.wisc.edu 12911309Sdavid.hashe@amd.com modpath = path[:] 13010012Snilay@cs.wisc.edu if modname != '__init__': 13111309Sdavid.hashe@amd.com modpath += [ modname ] 13210012Snilay@cs.wisc.edu modpath = '.'.join(modpath) 13310012Snilay@cs.wisc.edu 13410012Snilay@cs.wisc.edu arcpath = path + [ self.basename ] 13511309Sdavid.hashe@amd.com debugname = self.snode.abspath 13610012Snilay@cs.wisc.edu if not exists(debugname): 13711309Sdavid.hashe@amd.com debugname = self.tnode.abspath 13810012Snilay@cs.wisc.edu 13910012Snilay@cs.wisc.edu self.package = package 14010012Snilay@cs.wisc.edu self.modname = modname 14111309Sdavid.hashe@amd.com self.modpath = modpath 14210012Snilay@cs.wisc.edu self.arcname = joinpath(*arcpath) 14311309Sdavid.hashe@amd.com self.debugname = debugname 14410012Snilay@cs.wisc.edu self.compiled = File(self.filename + 'c') 14510012Snilay@cs.wisc.edu self.assembly = File(self.filename + '.s') 14610012Snilay@cs.wisc.edu self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath) 14711309Sdavid.hashe@amd.com 14810012Snilay@cs.wisc.edu PySource.modules[modpath] = self 14911309Sdavid.hashe@amd.com PySource.tnodes[self.tnode] = self 15011309Sdavid.hashe@amd.com PySource.symnames[self.symname] = self 15111309Sdavid.hashe@amd.com 15211309Sdavid.hashe@amd.comclass SimObject(PySource): 15311309Sdavid.hashe@amd.com '''Add a SimObject python file as a python source object and add 15411309Sdavid.hashe@amd.com it to a list of sim object modules''' 15511309Sdavid.hashe@amd.com 15611309Sdavid.hashe@amd.com fixed = False 15711309Sdavid.hashe@amd.com modnames = [] 15811309Sdavid.hashe@amd.com 15911309Sdavid.hashe@amd.com def __init__(self, source): 16011309Sdavid.hashe@amd.com super(SimObject, self).__init__('m5.objects', source) 16111309Sdavid.hashe@amd.com if self.fixed: 16211309Sdavid.hashe@amd.com raise AttributeError, "Too late to call SimObject now." 16311309Sdavid.hashe@amd.com 16411309Sdavid.hashe@amd.com bisect.insort_right(SimObject.modnames, self.modname) 16511309Sdavid.hashe@amd.com 16611309Sdavid.hashe@amd.comclass SwigSource(SourceFile): 16711309Sdavid.hashe@amd.com '''Add a swig file to build''' 16810012Snilay@cs.wisc.edu 16910012Snilay@cs.wisc.edu def __init__(self, package, source): 17010012Snilay@cs.wisc.edu super(SwigSource, self).__init__(source) 17110012Snilay@cs.wisc.edu 17211309Sdavid.hashe@amd.com modname,ext = self.extname 17311309Sdavid.hashe@amd.com assert ext == 'i' 17410012Snilay@cs.wisc.edu 17511309Sdavid.hashe@amd.com self.module = modname 17610012Snilay@cs.wisc.edu cc_file = joinpath(self.dirname, modname + '_wrap.cc') 17710012Snilay@cs.wisc.edu py_file = joinpath(self.dirname, modname + '.py') 17810012Snilay@cs.wisc.edu 17910012Snilay@cs.wisc.edu self.cc_source = Source(cc_file, swig=True) 18011309Sdavid.hashe@amd.com self.py_source = PySource(package, py_file) 18111309Sdavid.hashe@amd.com 18210012Snilay@cs.wisc.eduunit_tests = [] 18311309Sdavid.hashe@amd.comdef UnitTest(target, sources): 18410012Snilay@cs.wisc.edu if not isinstance(sources, (list, tuple)): 18510012Snilay@cs.wisc.edu sources = [ sources ] 18610012Snilay@cs.wisc.edu 18710012Snilay@cs.wisc.edu sources = [ Source(src, skip_lib=True) for src in sources ] 18811309Sdavid.hashe@amd.com unit_tests.append((target, sources)) 18911309Sdavid.hashe@amd.com 19010012Snilay@cs.wisc.edu# Children should have access 19111309Sdavid.hashe@amd.comExport('Source') 19211309Sdavid.hashe@amd.comExport('PySource') 19311309Sdavid.hashe@amd.comExport('SimObject') 19411309Sdavid.hashe@amd.comExport('SwigSource') 19511309Sdavid.hashe@amd.comExport('UnitTest') 19611309Sdavid.hashe@amd.com 19711309Sdavid.hashe@amd.com######################################################################## 19811309Sdavid.hashe@amd.com# 19911309Sdavid.hashe@amd.com# Trace Flags 20011309Sdavid.hashe@amd.com# 20111309Sdavid.hashe@amd.comtrace_flags = {} 20211309Sdavid.hashe@amd.comdef TraceFlag(name, desc=None): 20311309Sdavid.hashe@amd.com if name in trace_flags: 20411309Sdavid.hashe@amd.com raise AttributeError, "Flag %s already specified" % name 20511309Sdavid.hashe@amd.com trace_flags[name] = (name, (), desc) 20611309Sdavid.hashe@amd.com 20711309Sdavid.hashe@amd.comdef CompoundFlag(name, flags, desc=None): 20810012Snilay@cs.wisc.edu if name in trace_flags: 20910012Snilay@cs.wisc.edu raise AttributeError, "Flag %s already specified" % name 21010012Snilay@cs.wisc.edu 21110012Snilay@cs.wisc.edu compound = tuple(flags) 21210012Snilay@cs.wisc.edu trace_flags[name] = (name, compound, desc) 21310012Snilay@cs.wisc.edu 21411309Sdavid.hashe@amd.comExport('TraceFlag') 21511309Sdavid.hashe@amd.comExport('CompoundFlag') 21610012Snilay@cs.wisc.edu 21711309Sdavid.hashe@amd.com######################################################################## 21810012Snilay@cs.wisc.edu# 21910012Snilay@cs.wisc.edu# Set some compiler variables 22010012Snilay@cs.wisc.edu# 22110012Snilay@cs.wisc.edu 22211309Sdavid.hashe@amd.com# Include file paths are rooted in this directory. SCons will 22311309Sdavid.hashe@amd.com# automatically expand '.' to refer to both the source directory and 22410012Snilay@cs.wisc.edu# the corresponding build directory to pick up generated include 22511309Sdavid.hashe@amd.com# files. 22610012Snilay@cs.wisc.eduenv.Append(CPPPATH=Dir('.')) 22710012Snilay@cs.wisc.edu 22810012Snilay@cs.wisc.edufor extra_dir in extras_dir_list: 22910012Snilay@cs.wisc.edu env.Append(CPPPATH=Dir(extra_dir)) 23011309Sdavid.hashe@amd.com 23111309Sdavid.hashe@amd.com# Add a flag defining what THE_ISA should be for all compilation 23211309Sdavid.hashe@amd.comenv.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) 23311309Sdavid.hashe@amd.com 23411309Sdavid.hashe@amd.com# Workaround for bug in SCons version > 0.97d20071212 23511309Sdavid.hashe@amd.com# Scons bug id: 2006 M5 Bug id: 308 23611309Sdavid.hashe@amd.comfor root, dirs, files in os.walk(base_dir, topdown=True): 23711309Sdavid.hashe@amd.com Dir(root[len(base_dir) + 1:]) 23811309Sdavid.hashe@amd.com 23911309Sdavid.hashe@amd.com######################################################################## 24010012Snilay@cs.wisc.edu# 24110012Snilay@cs.wisc.edu# Walk the tree and execute all SConscripts in subdirectories 24211309Sdavid.hashe@amd.com# 24310012Snilay@cs.wisc.edu 24410012Snilay@cs.wisc.eduhere = Dir('.').srcnode().abspath 24510012Snilay@cs.wisc.edufor root, dirs, files in os.walk(base_dir, topdown=True): 24610012Snilay@cs.wisc.edu if root == here: 24711309Sdavid.hashe@amd.com # we don't want to recurse back into this SConscript 24811309Sdavid.hashe@amd.com continue 24910012Snilay@cs.wisc.edu 25011309Sdavid.hashe@amd.com if 'SConscript' in files: 25111309Sdavid.hashe@amd.com build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 25211309Sdavid.hashe@amd.com SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) 25311309Sdavid.hashe@amd.com 25411309Sdavid.hashe@amd.comfor extra_dir in extras_dir_list: 25511309Sdavid.hashe@amd.com prefix_len = len(dirname(extra_dir)) + 1 25611309Sdavid.hashe@amd.com for root, dirs, files in os.walk(extra_dir, topdown=True): 25711309Sdavid.hashe@amd.com if 'SConscript' in files: 25811309Sdavid.hashe@amd.com build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 25911309Sdavid.hashe@amd.com SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) 26010012Snilay@cs.wisc.edu 26110012Snilay@cs.wisc.edufor opt in export_vars: 26210012Snilay@cs.wisc.edu env.ConfigFile(opt) 26310012Snilay@cs.wisc.edu 26411309Sdavid.hashe@amd.com######################################################################## 26511309Sdavid.hashe@amd.com# 26611309Sdavid.hashe@amd.com# Prevent any SimObjects from being added after this point, they 26711309Sdavid.hashe@amd.com# should all have been added in the SConscripts above 26811309Sdavid.hashe@amd.com# 26911309Sdavid.hashe@amd.comclass DictImporter(object): 27011309Sdavid.hashe@amd.com '''This importer takes a dictionary of arbitrary module names that 27111309Sdavid.hashe@amd.com map to arbitrary filenames.''' 27211309Sdavid.hashe@amd.com def __init__(self, modules): 27311309Sdavid.hashe@amd.com self.modules = modules 27410012Snilay@cs.wisc.edu self.installed = set() 27510012Snilay@cs.wisc.edu 27611309Sdavid.hashe@amd.com def __del__(self): 27710012Snilay@cs.wisc.edu self.unload() 27810012Snilay@cs.wisc.edu 27910012Snilay@cs.wisc.edu def unload(self): 28010012Snilay@cs.wisc.edu import sys 28111309Sdavid.hashe@amd.com for module in self.installed: 28211309Sdavid.hashe@amd.com del sys.modules[module] 28310012Snilay@cs.wisc.edu self.installed = set() 28410012Snilay@cs.wisc.edu 28511309Sdavid.hashe@amd.com def find_module(self, fullname, path): 28610012Snilay@cs.wisc.edu if fullname == 'defines': 28710012Snilay@cs.wisc.edu return self 28810012Snilay@cs.wisc.edu 28910012Snilay@cs.wisc.edu if fullname == 'm5.objects': 29011309Sdavid.hashe@amd.com return self 29111309Sdavid.hashe@amd.com 29211309Sdavid.hashe@amd.com if fullname.startswith('m5.internal'): 29311309Sdavid.hashe@amd.com return None 29411309Sdavid.hashe@amd.com 29511309Sdavid.hashe@amd.com source = self.modules.get(fullname, None) 29611309Sdavid.hashe@amd.com if source is not None and exists(source.snode.abspath): 29711309Sdavid.hashe@amd.com return self 29811309Sdavid.hashe@amd.com 29911309Sdavid.hashe@amd.com return None 30011309Sdavid.hashe@amd.com 30111309Sdavid.hashe@amd.com def load_module(self, fullname): 30211309Sdavid.hashe@amd.com mod = imp.new_module(fullname) 30311309Sdavid.hashe@amd.com sys.modules[fullname] = mod 30411309Sdavid.hashe@amd.com self.installed.add(fullname) 30511309Sdavid.hashe@amd.com 30611309Sdavid.hashe@amd.com mod.__loader__ = self 30711309Sdavid.hashe@amd.com if fullname == 'm5.objects': 30811309Sdavid.hashe@amd.com mod.__path__ = fullname.split('.') 30911309Sdavid.hashe@amd.com return mod 31010012Snilay@cs.wisc.edu 31110012Snilay@cs.wisc.edu if fullname == 'defines': 31210012Snilay@cs.wisc.edu mod.__dict__['buildEnv'] = build_env 31310012Snilay@cs.wisc.edu return mod 31410012Snilay@cs.wisc.edu 31511309Sdavid.hashe@amd.com source = self.modules[fullname] 31611309Sdavid.hashe@amd.com if source.modname == '__init__': 31711309Sdavid.hashe@amd.com mod.__path__ = source.modpath 31810012Snilay@cs.wisc.edu mod.__file__ = source.snode.abspath 31910012Snilay@cs.wisc.edu 32011309Sdavid.hashe@amd.com exec file(source.snode.abspath, 'r') in mod.__dict__ 32111309Sdavid.hashe@amd.com 32210012Snilay@cs.wisc.edu return mod 32311309Sdavid.hashe@amd.com 32410012Snilay@cs.wisc.edu# install the python importer so we can grab stuff from the source 32510012Snilay@cs.wisc.edu# tree itself. We can't have SimObjects added after this point or 32610012Snilay@cs.wisc.edu# else we won't know about them for the rest of the stuff. 32710012Snilay@cs.wisc.eduSimObject.fixed = True 32811309Sdavid.hashe@amd.comimporter = DictImporter(PySource.modules) 32911309Sdavid.hashe@amd.comsys.meta_path[0:0] = [ importer ] 33010012Snilay@cs.wisc.edu 33111309Sdavid.hashe@amd.comimport m5 33211309Sdavid.hashe@amd.com 33311309Sdavid.hashe@amd.com# import all sim objects so we can populate the all_objects list 33411309Sdavid.hashe@amd.com# make sure that we're working with a list, then let's sort it 33511309Sdavid.hashe@amd.comfor modname in SimObject.modnames: 33611309Sdavid.hashe@amd.com exec('from m5.objects import %s' % modname) 33711309Sdavid.hashe@amd.com 33811309Sdavid.hashe@amd.com# we need to unload all of the currently imported modules so that they 33911309Sdavid.hashe@amd.com# will be re-imported the next time the sconscript is run 34010012Snilay@cs.wisc.eduimporter.unload() 34110012Snilay@cs.wisc.edusys.meta_path.remove(importer) 34210012Snilay@cs.wisc.edu 34310012Snilay@cs.wisc.edusim_objects = m5.SimObject.allClasses 34410012Snilay@cs.wisc.eduall_enums = m5.params.allEnums 3457048Snate@binkert.org 3467048Snate@binkert.orgall_params = {} 3477048Snate@binkert.orgfor name,obj in sorted(sim_objects.iteritems()): 34810012Snilay@cs.wisc.edu for param in obj._params.local.values(): 3499496Snilay@cs.wisc.edu if not hasattr(param, 'swig_decl'): 35010012Snilay@cs.wisc.edu continue 35110012Snilay@cs.wisc.edu pname = param.ptype_str 3529496Snilay@cs.wisc.edu if pname not in all_params: 3539496Snilay@cs.wisc.edu all_params[pname] = param 35410012Snilay@cs.wisc.edu 35510012Snilay@cs.wisc.edu######################################################################## 3569496Snilay@cs.wisc.edu# 3579497Snilay@cs.wisc.edu# calculate extra dependencies 3589497Snilay@cs.wisc.edu# 3599497Snilay@cs.wisc.edumodule_depends = ["m5", "m5.SimObject", "m5.params"] 36010920Sbrandon.potter@amd.comdepends = [ PySource.modules[dep].tnode for dep in module_depends ] 36110920Sbrandon.potter@amd.com 3629497Snilay@cs.wisc.edu######################################################################## 3639497Snilay@cs.wisc.edu# 3649497Snilay@cs.wisc.edu# Commands for the basic automatically generated python files 3659497Snilay@cs.wisc.edu# 36611172Snilay@cs.wisc.edu 36710012Snilay@cs.wisc.edu# Generate Python file containing a dict specifying the current 3689497Snilay@cs.wisc.edu# build_env flags. 3699497Snilay@cs.wisc.edudef makeDefinesPyFile(target, source, env): 3709497Snilay@cs.wisc.edu f = file(str(target[0]), 'w') 3719497Snilay@cs.wisc.edu build_env, hg_info = [ x.get_contents() for x in source ] 3729598Snilay@cs.wisc.edu print >>f, "buildEnv = %s" % build_env 3739598Snilay@cs.wisc.edu print >>f, "hgRev = '%s'" % hg_info 37410920Sbrandon.potter@amd.com f.close() 37510920Sbrandon.potter@amd.com 3769598Snilay@cs.wisc.edudefines_info = [ Value(build_env), Value(env['HG_INFO']) ] 3779598Snilay@cs.wisc.edu# Generate a file with all of the compile options in it 37811308Santhony.gutierrez@amd.comenv.Command('python/m5/defines.py', defines_info, makeDefinesPyFile) 3799598Snilay@cs.wisc.eduPySource('m5', 'python/m5/defines.py') 38011309Sdavid.hashe@amd.com 38111309Sdavid.hashe@amd.com# Generate python file containing info about the M5 source code 38211798Santhony.gutierrez@amd.comdef makeInfoPyFile(target, source, env): 38311309Sdavid.hashe@amd.com f = file(str(target[0]), 'w') 38411309Sdavid.hashe@amd.com for src in source: 38511309Sdavid.hashe@amd.com data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 3869598Snilay@cs.wisc.edu print >>f, "%s = %s" % (src, repr(data)) 38711798Santhony.gutierrez@amd.com f.close() 3889598Snilay@cs.wisc.edu 3899598Snilay@cs.wisc.edu# Generate a file that wraps the basic top level files 3909598Snilay@cs.wisc.eduenv.Command('python/m5/info.py', 3919773Snilay@cs.wisc.edu [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ], 3929773Snilay@cs.wisc.edu makeInfoPyFile) 39310920Sbrandon.potter@amd.comPySource('m5', 'python/m5/info.py') 39410920Sbrandon.potter@amd.com 3959773Snilay@cs.wisc.edu# Generate the __init__.py file for m5.objects 3969773Snilay@cs.wisc.edudef makeObjectsInitFile(target, source, env): 39711308Santhony.gutierrez@amd.com f = file(str(target[0]), 'w') 3989773Snilay@cs.wisc.edu print >>f, 'from params import *' 3999773Snilay@cs.wisc.edu print >>f, 'from m5.SimObject import *' 40011309Sdavid.hashe@amd.com for module in source: 40111309Sdavid.hashe@amd.com print >>f, 'from %s import *' % module.get_contents() 40211309Sdavid.hashe@amd.com f.close() 4039773Snilay@cs.wisc.edu 4049773Snilay@cs.wisc.edu# Generate an __init__.py file for the objects package 4059773Snilay@cs.wisc.eduenv.Command('python/m5/objects/__init__.py', 40611309Sdavid.hashe@amd.com map(Value, SimObject.modnames), 40710012Snilay@cs.wisc.edu makeObjectsInitFile) 40811309Sdavid.hashe@amd.comPySource('m5.objects', 'python/m5/objects/__init__.py') 40910012Snilay@cs.wisc.edu 41011309Sdavid.hashe@amd.com######################################################################## 41110012Snilay@cs.wisc.edu# 4129773Snilay@cs.wisc.edu# Create all of the SimObject param headers and enum headers 4139773Snilay@cs.wisc.edu# 4149773Snilay@cs.wisc.edu 4159773Snilay@cs.wisc.edudef createSimObjectParam(target, source, env): 41611309Sdavid.hashe@amd.com assert len(target) == 1 and len(source) == 1 41710012Snilay@cs.wisc.edu 41811309Sdavid.hashe@amd.com hh_file = file(target[0].abspath, 'w') 41910012Snilay@cs.wisc.edu name = str(source[0].get_contents()) 4209773Snilay@cs.wisc.edu obj = sim_objects[name] 42111309Sdavid.hashe@amd.com 4229773Snilay@cs.wisc.edu print >>hh_file, obj.cxx_decl() 4239773Snilay@cs.wisc.edu hh_file.close() 42411309Sdavid.hashe@amd.com 4259773Snilay@cs.wisc.edudef createSwigParam(target, source, env): 42611309Sdavid.hashe@amd.com assert len(target) == 1 and len(source) == 1 4279773Snilay@cs.wisc.edu 4289773Snilay@cs.wisc.edu i_file = file(target[0].abspath, 'w') 42911309Sdavid.hashe@amd.com name = str(source[0].get_contents()) 43010012Snilay@cs.wisc.edu param = all_params[name] 43110012Snilay@cs.wisc.edu 43211309Sdavid.hashe@amd.com for line in param.swig_decl(): 4339773Snilay@cs.wisc.edu print >>i_file, line 4349773Snilay@cs.wisc.edu i_file.close() 4359773Snilay@cs.wisc.edu 4369773Snilay@cs.wisc.edudef createEnumStrings(target, source, env): 4379773Snilay@cs.wisc.edu assert len(target) == 1 and len(source) == 1 4389773Snilay@cs.wisc.edu 43911309Sdavid.hashe@amd.com cc_file = file(target[0].abspath, 'w') 44010012Snilay@cs.wisc.edu name = str(source[0].get_contents()) 44111309Sdavid.hashe@amd.com obj = all_enums[name] 44210012Snilay@cs.wisc.edu 4439773Snilay@cs.wisc.edu print >>cc_file, obj.cxx_def() 4449773Snilay@cs.wisc.edu cc_file.close() 4459773Snilay@cs.wisc.edu 44611798Santhony.gutierrez@amd.comdef createEnumParam(target, source, env): 44711309Sdavid.hashe@amd.com assert len(target) == 1 and len(source) == 1 44811309Sdavid.hashe@amd.com 44911309Sdavid.hashe@amd.com hh_file = file(target[0].abspath, 'w') 45011309Sdavid.hashe@amd.com name = str(source[0].get_contents()) 45111309Sdavid.hashe@amd.com obj = all_enums[name] 45211309Sdavid.hashe@amd.com 45311309Sdavid.hashe@amd.com print >>hh_file, obj.cxx_decl() 45411309Sdavid.hashe@amd.com hh_file.close() 45511309Sdavid.hashe@amd.com 45611309Sdavid.hashe@amd.com# Generate all of the SimObject param struct header files 45711309Sdavid.hashe@amd.comparams_hh_files = [] 45811309Sdavid.hashe@amd.comfor name,simobj in sorted(sim_objects.iteritems()): 45911309Sdavid.hashe@amd.com py_source = PySource.modules[simobj.__module__] 46011309Sdavid.hashe@amd.com extra_deps = [ py_source.tnode ] 46111309Sdavid.hashe@amd.com 46211309Sdavid.hashe@amd.com hh_file = File('params/%s.hh' % name) 46311309Sdavid.hashe@amd.com params_hh_files.append(hh_file) 46411309Sdavid.hashe@amd.com env.Command(hh_file, Value(name), createSimObjectParam) 46511309Sdavid.hashe@amd.com env.Depends(hh_file, depends + extra_deps) 46611309Sdavid.hashe@amd.com 46711309Sdavid.hashe@amd.com# Generate any parameter header files needed 46811309Sdavid.hashe@amd.comparams_i_files = [] 46911309Sdavid.hashe@amd.comfor name,param in all_params.iteritems(): 47011309Sdavid.hashe@amd.com if isinstance(param, m5.params.VectorParamDesc): 47111309Sdavid.hashe@amd.com ext = 'vptype' 47211309Sdavid.hashe@amd.com else: 47311309Sdavid.hashe@amd.com ext = 'ptype' 47411309Sdavid.hashe@amd.com 47511309Sdavid.hashe@amd.com i_file = File('params/%s_%s.i' % (name, ext)) 47611309Sdavid.hashe@amd.com params_i_files.append(i_file) 47711309Sdavid.hashe@amd.com env.Command(i_file, Value(name), createSwigParam) 47811309Sdavid.hashe@amd.com env.Depends(i_file, depends) 47911309Sdavid.hashe@amd.com 48011309Sdavid.hashe@amd.com# Generate all enum header files 48111309Sdavid.hashe@amd.comfor name,enum in sorted(all_enums.iteritems()): 48211309Sdavid.hashe@amd.com py_source = PySource.modules[enum.__module__] 48311309Sdavid.hashe@amd.com extra_deps = [ py_source.tnode ] 48411309Sdavid.hashe@amd.com 48511309Sdavid.hashe@amd.com cc_file = File('enums/%s.cc' % name) 48611309Sdavid.hashe@amd.com env.Command(cc_file, Value(name), createEnumStrings) 48711798Santhony.gutierrez@amd.com env.Depends(cc_file, depends + extra_deps) 4889773Snilay@cs.wisc.edu Source(cc_file) 4899773Snilay@cs.wisc.edu 4906145Snate@binkert.org hh_file = File('enums/%s.hh' % name) 4916145Snate@binkert.org env.Command(hh_file, Value(name), createEnumParam) 4927048Snate@binkert.org env.Depends(hh_file, depends + extra_deps) 4938174Snilay@cs.wisc.edu 4946145Snate@binkert.org# Build the big monolithic swigged params module (wraps all SimObject 4958165Snilay@cs.wisc.edu# param structs and enum structs) 4967048Snate@binkert.orgdef buildParams(target, source, env): 4977048Snate@binkert.org names = [ s.get_contents() for s in source ] 4987048Snate@binkert.org objs = [ sim_objects[name] for name in names ] 4996145Snate@binkert.org out = file(target[0].abspath, 'w') 5007048Snate@binkert.org 5017048Snate@binkert.org ordered_objs = [] 5027048Snate@binkert.org obj_seen = set() 5037048Snate@binkert.org def order_obj(obj): 5047048Snate@binkert.org name = str(obj) 5057048Snate@binkert.org if name in obj_seen: 5066145Snate@binkert.org return 507 508 obj_seen.add(name) 509 if str(obj) != 'SimObject': 510 order_obj(obj.__bases__[0]) 511 512 ordered_objs.append(obj) 513 514 for obj in objs: 515 order_obj(obj) 516 517 enums = set() 518 predecls = [] 519 pd_seen = set() 520 521 def add_pds(*pds): 522 for pd in pds: 523 if pd not in pd_seen: 524 predecls.append(pd) 525 pd_seen.add(pd) 526 527 for obj in ordered_objs: 528 params = obj._params.local.values() 529 for param in params: 530 ptype = param.ptype 531 if issubclass(ptype, m5.params.Enum): 532 if ptype not in enums: 533 enums.add(ptype) 534 pds = param.swig_predecls() 535 if isinstance(pds, (list, tuple)): 536 add_pds(*pds) 537 else: 538 add_pds(pds) 539 540 print >>out, '%module params' 541 542 print >>out, '%{' 543 for obj in ordered_objs: 544 print >>out, '#include "params/%s.hh"' % obj 545 print >>out, '%}' 546 547 for pd in predecls: 548 print >>out, pd 549 550 enums = list(enums) 551 enums.sort() 552 for enum in enums: 553 print >>out, '%%include "enums/%s.hh"' % enum.__name__ 554 print >>out 555 556 for obj in ordered_objs: 557 if obj.swig_objdecls: 558 for decl in obj.swig_objdecls: 559 print >>out, decl 560 continue 561 562 class_path = obj.cxx_class.split('::') 563 classname = class_path[-1] 564 namespaces = class_path[:-1] 565 namespaces.reverse() 566 567 code = '' 568 569 if namespaces: 570 code += '// avoid name conflicts\n' 571 sep_string = '_COLONS_' 572 flat_name = sep_string.join(class_path) 573 code += '%%rename(%s) %s;\n' % (flat_name, classname) 574 575 code += '// stop swig from creating/wrapping default ctor/dtor\n' 576 code += '%%nodefault %s;\n' % classname 577 code += 'class %s ' % classname 578 if obj._base: 579 code += ': public %s' % obj._base.cxx_class 580 code += ' {};\n' 581 582 for ns in namespaces: 583 new_code = 'namespace %s {\n' % ns 584 new_code += code 585 new_code += '}\n' 586 code = new_code 587 588 print >>out, code 589 590 print >>out, '%%include "src/sim/sim_object_params.hh"' % obj 591 for obj in ordered_objs: 592 print >>out, '%%include "params/%s.hh"' % obj 593 594params_file = File('params/params.i') 595names = sorted(sim_objects.keys()) 596env.Command(params_file, map(Value, names), buildParams) 597env.Depends(params_file, params_hh_files + params_i_files + depends) 598SwigSource('m5.objects', params_file) 599 600# Build all swig modules 601for swig in SwigSource.all: 602 env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 603 '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 604 '-o ${TARGETS[0]} $SOURCES') 605 env.Depends(swig.py_source.tnode, swig.tnode) 606 env.Depends(swig.cc_source.tnode, swig.tnode) 607 608# Generate the main swig init file 609def makeSwigInit(target, source, env): 610 f = file(str(target[0]), 'w') 611 print >>f, 'extern "C" {' 612 for module in source: 613 print >>f, ' void init_%s();' % module.get_contents() 614 print >>f, '}' 615 print >>f, 'void initSwig() {' 616 for module in source: 617 print >>f, ' init_%s();' % module.get_contents() 618 print >>f, '}' 619 f.close() 620 621env.Command('python/swig/init.cc', 622 map(Value, sorted(s.module for s in SwigSource.all)), 623 makeSwigInit) 624Source('python/swig/init.cc') 625 626def getFlags(source_flags): 627 flagsMap = {} 628 flagsList = [] 629 for s in source_flags: 630 val = eval(s.get_contents()) 631 name, compound, desc = val 632 flagsList.append(val) 633 flagsMap[name] = bool(compound) 634 635 for name, compound, desc in flagsList: 636 for flag in compound: 637 if flag not in flagsMap: 638 raise AttributeError, "Trace flag %s not found" % flag 639 if flagsMap[flag]: 640 raise AttributeError, \ 641 "Compound flag can't point to another compound flag" 642 643 flagsList.sort() 644 return flagsList 645 646 647# Generate traceflags.py 648def traceFlagsPy(target, source, env): 649 assert(len(target) == 1) 650 651 f = file(str(target[0]), 'w') 652 653 allFlags = getFlags(source) 654 655 print >>f, 'basic = [' 656 for flag, compound, desc in allFlags: 657 if not compound: 658 print >>f, " '%s'," % flag 659 print >>f, " ]" 660 print >>f 661 662 print >>f, 'compound = [' 663 print >>f, " 'All'," 664 for flag, compound, desc in allFlags: 665 if compound: 666 print >>f, " '%s'," % flag 667 print >>f, " ]" 668 print >>f 669 670 print >>f, "all = frozenset(basic + compound)" 671 print >>f 672 673 print >>f, 'compoundMap = {' 674 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 675 print >>f, " 'All' : %s," % (all, ) 676 for flag, compound, desc in allFlags: 677 if compound: 678 print >>f, " '%s' : %s," % (flag, compound) 679 print >>f, " }" 680 print >>f 681 682 print >>f, 'descriptions = {' 683 print >>f, " 'All' : 'All flags'," 684 for flag, compound, desc in allFlags: 685 print >>f, " '%s' : '%s'," % (flag, desc) 686 print >>f, " }" 687 688 f.close() 689 690def traceFlagsCC(target, source, env): 691 assert(len(target) == 1) 692 693 f = file(str(target[0]), 'w') 694 695 allFlags = getFlags(source) 696 697 # file header 698 print >>f, ''' 699/* 700 * DO NOT EDIT THIS FILE! Automatically generated 701 */ 702 703#include "base/traceflags.hh" 704 705using namespace Trace; 706 707const char *Trace::flagStrings[] = 708{''' 709 710 # The string array is used by SimpleEnumParam to map the strings 711 # provided by the user to enum values. 712 for flag, compound, desc in allFlags: 713 if not compound: 714 print >>f, ' "%s",' % flag 715 716 print >>f, ' "All",' 717 for flag, compound, desc in allFlags: 718 if compound: 719 print >>f, ' "%s",' % flag 720 721 print >>f, '};' 722 print >>f 723 print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1) 724 print >>f 725 726 # 727 # Now define the individual compound flag arrays. There is an array 728 # for each compound flag listing the component base flags. 729 # 730 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 731 print >>f, 'static const Flags AllMap[] = {' 732 for flag, compound, desc in allFlags: 733 if not compound: 734 print >>f, " %s," % flag 735 print >>f, '};' 736 print >>f 737 738 for flag, compound, desc in allFlags: 739 if not compound: 740 continue 741 print >>f, 'static const Flags %sMap[] = {' % flag 742 for flag in compound: 743 print >>f, " %s," % flag 744 print >>f, " (Flags)-1" 745 print >>f, '};' 746 print >>f 747 748 # 749 # Finally the compoundFlags[] array maps the compound flags 750 # to their individual arrays/ 751 # 752 print >>f, 'const Flags *Trace::compoundFlags[] =' 753 print >>f, '{' 754 print >>f, ' AllMap,' 755 for flag, compound, desc in allFlags: 756 if compound: 757 print >>f, ' %sMap,' % flag 758 # file trailer 759 print >>f, '};' 760 761 f.close() 762 763def traceFlagsHH(target, source, env): 764 assert(len(target) == 1) 765 766 f = file(str(target[0]), 'w') 767 768 allFlags = getFlags(source) 769 770 # file header boilerplate 771 print >>f, ''' 772/* 773 * DO NOT EDIT THIS FILE! 774 * 775 * Automatically generated from traceflags.py 776 */ 777 778#ifndef __BASE_TRACE_FLAGS_HH__ 779#define __BASE_TRACE_FLAGS_HH__ 780 781namespace Trace { 782 783enum Flags {''' 784 785 # Generate the enum. Base flags come first, then compound flags. 786 idx = 0 787 for flag, compound, desc in allFlags: 788 if not compound: 789 print >>f, ' %s = %d,' % (flag, idx) 790 idx += 1 791 792 numBaseFlags = idx 793 print >>f, ' NumFlags = %d,' % idx 794 795 # put a comment in here to separate base from compound flags 796 print >>f, ''' 797// The remaining enum values are *not* valid indices for Trace::flags. 798// They are "compound" flags, which correspond to sets of base 799// flags, and are used by changeFlag.''' 800 801 print >>f, ' All = %d,' % idx 802 idx += 1 803 for flag, compound, desc in allFlags: 804 if compound: 805 print >>f, ' %s = %d,' % (flag, idx) 806 idx += 1 807 808 numCompoundFlags = idx - numBaseFlags 809 print >>f, ' NumCompoundFlags = %d' % numCompoundFlags 810 811 # trailer boilerplate 812 print >>f, '''\ 813}; // enum Flags 814 815// Array of strings for SimpleEnumParam 816extern const char *flagStrings[]; 817extern const int numFlagStrings; 818 819// Array of arraay pointers: for each compound flag, gives the list of 820// base flags to set. Inidividual flag arrays are terminated by -1. 821extern const Flags *compoundFlags[]; 822 823/* namespace Trace */ } 824 825#endif // __BASE_TRACE_FLAGS_HH__ 826''' 827 828 f.close() 829 830flags = map(Value, trace_flags.values()) 831env.Command('base/traceflags.py', flags, traceFlagsPy) 832PySource('m5', 'base/traceflags.py') 833 834env.Command('base/traceflags.hh', flags, traceFlagsHH) 835env.Command('base/traceflags.cc', flags, traceFlagsCC) 836Source('base/traceflags.cc') 837 838# embed python files. All .py files that have been indicated by a 839# PySource() call in a SConscript need to be embedded into the M5 840# library. To do that, we compile the file to byte code, marshal the 841# byte code, compress it, and then generate an assembly file that 842# inserts the result into the data section with symbols indicating the 843# beginning, and end (and with the size at the end) 844def objectifyPyFile(target, source, env): 845 '''Action function to compile a .py into a code object, marshal 846 it, compress it, and stick it into an asm file so the code appears 847 as just bytes with a label in the data section''' 848 849 src = file(str(source[0]), 'r').read() 850 dst = file(str(target[0]), 'w') 851 852 pysource = PySource.tnodes[source[0]] 853 compiled = compile(src, pysource.debugname, 'exec') 854 marshalled = marshal.dumps(compiled) 855 compressed = zlib.compress(marshalled) 856 data = compressed 857 858 # Some C/C++ compilers prepend an underscore to global symbol 859 # names, so if they're going to do that, we need to prepend that 860 # leading underscore to globals in the assembly file. 861 if env['LEADING_UNDERSCORE']: 862 sym = '_' + pysource.symname 863 else: 864 sym = pysource.symname 865 866 step = 16 867 print >>dst, ".data" 868 print >>dst, ".globl %s_beg" % sym 869 print >>dst, ".globl %s_end" % sym 870 print >>dst, "%s_beg:" % sym 871 for i in xrange(0, len(data), step): 872 x = array.array('B', data[i:i+step]) 873 print >>dst, ".byte", ','.join([str(d) for d in x]) 874 print >>dst, "%s_end:" % sym 875 print >>dst, ".long %d" % len(marshalled) 876 877for source in PySource.all: 878 env.Command(source.assembly, source.tnode, objectifyPyFile) 879 Source(source.assembly) 880 881# Generate init_python.cc which creates a bunch of EmbeddedPyModule 882# structs that describe the embedded python code. One such struct 883# contains information about the importer that python uses to get at 884# the embedded files, and then there's a list of all of the rest that 885# the importer uses to load the rest on demand. 886def pythonInit(target, source, env): 887 dst = file(str(target[0]), 'w') 888 889 def dump_mod(sym, endchar=','): 890 pysource = PySource.symnames[sym] 891 print >>dst, ' { "%s",' % pysource.arcname 892 print >>dst, ' "%s",' % pysource.modpath 893 print >>dst, ' %s_beg, %s_end,' % (sym, sym) 894 print >>dst, ' %s_end - %s_beg,' % (sym, sym) 895 print >>dst, ' *(int *)%s_end }%s' % (sym, endchar) 896 897 print >>dst, '#include "sim/init.hh"' 898 899 for sym in source: 900 sym = sym.get_contents() 901 print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym) 902 903 print >>dst, "const EmbeddedPyModule embeddedPyImporter = " 904 dump_mod("PyEMB_importer", endchar=';'); 905 print >>dst 906 907 print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {" 908 for i,sym in enumerate(source): 909 sym = sym.get_contents() 910 if sym == "PyEMB_importer": 911 # Skip the importer since we've already exported it 912 continue 913 dump_mod(sym) 914 print >>dst, " { 0, 0, 0, 0, 0, 0 }" 915 print >>dst, "};" 916 917 918env.Command('sim/init_python.cc', 919 map(Value, (s.symname for s in PySource.all)), 920 pythonInit) 921Source('sim/init_python.cc') 922 923######################################################################## 924# 925# Define binaries. Each different build type (debug, opt, etc.) gets 926# a slightly different build environment. 927# 928 929# List of constructed environments to pass back to SConstruct 930envList = [] 931 932date_source = Source('base/date.cc', skip_lib=True) 933 934# Function to create a new build environment as clone of current 935# environment 'env' with modified object suffix and optional stripped 936# binary. Additional keyword arguments are appended to corresponding 937# build environment vars. 938def makeEnv(label, objsfx, strip = False, **kwargs): 939 # SCons doesn't know to append a library suffix when there is a '.' in the 940 # name. Use '_' instead. 941 libname = 'm5_' + label 942 exename = 'm5.' + label 943 944 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 945 new_env.Label = label 946 new_env.Append(**kwargs) 947 948 swig_env = new_env.Clone() 949 swig_env.Append(CCFLAGS='-Werror') 950 if env['GCC']: 951 swig_env.Append(CCFLAGS='-Wno-uninitialized') 952 swig_env.Append(CCFLAGS='-Wno-sign-compare') 953 swig_env.Append(CCFLAGS='-Wno-parentheses') 954 955 werror_env = new_env.Clone() 956 werror_env.Append(CCFLAGS='-Werror') 957 958 def make_obj(source, static, extra_deps = None): 959 '''This function adds the specified source to the correct 960 build environment, and returns the corresponding SCons Object 961 nodes''' 962 963 if source.swig: 964 env = swig_env 965 elif source.Werror: 966 env = werror_env 967 else: 968 env = new_env 969 970 if static: 971 obj = env.StaticObject(source.tnode) 972 else: 973 obj = env.SharedObject(source.tnode) 974 975 if extra_deps: 976 env.Depends(obj, extra_deps) 977 978 return obj 979 980 static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)] 981 shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)] 982 983 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 984 static_objs.append(static_date) 985 986 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 987 shared_objs.append(shared_date) 988 989 # First make a library of everything but main() so other programs can 990 # link against m5. 991 static_lib = new_env.StaticLibrary(libname, static_objs) 992 shared_lib = new_env.SharedLibrary(libname, shared_objs) 993 994 for target, sources in unit_tests: 995 objs = [ make_obj(s, static=True) for s in sources ] 996 new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs) 997 998 # Now link a stub with main() and the static library. 999 bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ] 1000 progname = exename 1001 if strip: 1002 progname += '.unstripped' 1003 1004 targets = new_env.Program(progname, bin_objs + static_objs) 1005 1006 if strip: 1007 if sys.platform == 'sunos5': 1008 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1009 else: 1010 cmd = 'strip $SOURCE -o $TARGET' 1011 targets = new_env.Command(exename, progname, cmd) 1012 1013 new_env.M5Binary = targets[0] 1014 envList.append(new_env) 1015 1016# Debug binary 1017ccflags = {} 1018if env['GCC']: 1019 if sys.platform == 'sunos5': 1020 ccflags['debug'] = '-gstabs+' 1021 else: 1022 ccflags['debug'] = '-ggdb3' 1023 ccflags['opt'] = '-g -O3' 1024 ccflags['fast'] = '-O3' 1025 ccflags['prof'] = '-O3 -g -pg' 1026elif env['SUNCC']: 1027 ccflags['debug'] = '-g0' 1028 ccflags['opt'] = '-g -O' 1029 ccflags['fast'] = '-fast' 1030 ccflags['prof'] = '-fast -g -pg' 1031elif env['ICC']: 1032 ccflags['debug'] = '-g -O0' 1033 ccflags['opt'] = '-g -O' 1034 ccflags['fast'] = '-fast' 1035 ccflags['prof'] = '-fast -g -pg' 1036else: 1037 print 'Unknown compiler, please fix compiler options' 1038 Exit(1) 1039 1040makeEnv('debug', '.do', 1041 CCFLAGS = Split(ccflags['debug']), 1042 CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 1043 1044# Optimized binary 1045makeEnv('opt', '.o', 1046 CCFLAGS = Split(ccflags['opt']), 1047 CPPDEFINES = ['TRACING_ON=1']) 1048 1049# "Fast" binary 1050makeEnv('fast', '.fo', strip = True, 1051 CCFLAGS = Split(ccflags['fast']), 1052 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 1053 1054# Profiled binary 1055makeEnv('prof', '.po', 1056 CCFLAGS = Split(ccflags['prof']), 1057 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1058 LINKFLAGS = '-pg') 1059 1060Return('envList') 1061