SConscript revision 7816:b5003ac75977
1955SN/A# -*- mode:python -*- 2955SN/A 31762SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 4955SN/A# All rights reserved. 5955SN/A# 6955SN/A# Redistribution and use in source and binary forms, with or without 7955SN/A# modification, are permitted provided that the following conditions are 8955SN/A# met: redistributions of source code must retain the above copyright 9955SN/A# notice, this list of conditions and the following disclaimer; 10955SN/A# redistributions in binary form must reproduce the above copyright 11955SN/A# notice, this list of conditions and the following disclaimer in the 12955SN/A# documentation and/or other materials provided with the distribution; 13955SN/A# neither the name of the copyright holders nor the names of its 14955SN/A# contributors may be used to endorse or promote products derived from 15955SN/A# this software without specific prior written permission. 16955SN/A# 17955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu# 292665Ssaidi@eecs.umich.edu# Authors: Nathan Binkert 30955SN/A 31955SN/Aimport array 32955SN/Aimport bisect 33955SN/Aimport imp 34955SN/Aimport marshal 352632Sstever@eecs.umich.eduimport os 362632Sstever@eecs.umich.eduimport re 372632Sstever@eecs.umich.eduimport sys 382632Sstever@eecs.umich.eduimport zlib 39955SN/A 402632Sstever@eecs.umich.edufrom os.path import basename, dirname, exists, isdir, isfile, join as joinpath 412632Sstever@eecs.umich.edu 422761Sstever@eecs.umich.eduimport SCons 432632Sstever@eecs.umich.edu 442632Sstever@eecs.umich.edu# This file defines how to build a particular configuration of M5 452632Sstever@eecs.umich.edu# based on variable settings in the 'env' build environment. 462761Sstever@eecs.umich.edu 472761Sstever@eecs.umich.eduImport('*') 482761Sstever@eecs.umich.edu 492632Sstever@eecs.umich.edu# Children need to see the environment 502632Sstever@eecs.umich.eduExport('env') 512761Sstever@eecs.umich.edu 522761Sstever@eecs.umich.edubuild_env = [(opt, env[opt]) for opt in export_vars] 532761Sstever@eecs.umich.edu 542761Sstever@eecs.umich.edufrom m5.util import code_formatter 552761Sstever@eecs.umich.edu 562632Sstever@eecs.umich.edu######################################################################## 572632Sstever@eecs.umich.edu# Code for adding source files of various types 582632Sstever@eecs.umich.edu# 592632Sstever@eecs.umich.educlass SourceMeta(type): 602632Sstever@eecs.umich.edu def __init__(cls, name, bases, dict): 612632Sstever@eecs.umich.edu super(SourceMeta, cls).__init__(name, bases, dict) 622632Sstever@eecs.umich.edu cls.all = [] 63955SN/A 64955SN/A def get(cls, **kwargs): 65955SN/A for src in cls.all: 66955SN/A for attr,value in kwargs.iteritems(): 67955SN/A if getattr(src, attr) != value: 683918Ssaidi@eecs.umich.edu break 694202Sbinkertn@umich.edu else: 703716Sstever@eecs.umich.edu yield src 71955SN/A 722656Sstever@eecs.umich.educlass SourceFile(object): 732656Sstever@eecs.umich.edu __metaclass__ = SourceMeta 742656Sstever@eecs.umich.edu def __init__(self, source): 752656Sstever@eecs.umich.edu tnode = source 762656Sstever@eecs.umich.edu if not isinstance(source, SCons.Node.FS.File): 772656Sstever@eecs.umich.edu tnode = File(source) 782656Sstever@eecs.umich.edu 792653Sstever@eecs.umich.edu self.tnode = tnode 802653Sstever@eecs.umich.edu self.snode = tnode.srcnode() 812653Sstever@eecs.umich.edu self.filename = str(tnode) 822653Sstever@eecs.umich.edu self.dirname = dirname(self.filename) 832653Sstever@eecs.umich.edu self.basename = basename(self.filename) 842653Sstever@eecs.umich.edu index = self.basename.rfind('.') 852653Sstever@eecs.umich.edu if index <= 0: 862653Sstever@eecs.umich.edu # dot files aren't extensions 872653Sstever@eecs.umich.edu self.extname = self.basename, None 882653Sstever@eecs.umich.edu else: 892653Sstever@eecs.umich.edu self.extname = self.basename[:index], self.basename[index+1:] 901852SN/A 91955SN/A for base in type(self).__mro__: 92955SN/A if issubclass(base, SourceFile): 93955SN/A base.all.append(self) 943717Sstever@eecs.umich.edu 953716Sstever@eecs.umich.edu def __lt__(self, other): return self.filename < other.filename 96955SN/A def __le__(self, other): return self.filename <= other.filename 971533SN/A def __gt__(self, other): return self.filename > other.filename 983716Sstever@eecs.umich.edu def __ge__(self, other): return self.filename >= other.filename 991533SN/A def __eq__(self, other): return self.filename == other.filename 100955SN/A def __ne__(self, other): return self.filename != other.filename 101955SN/A 1022632Sstever@eecs.umich.educlass Source(SourceFile): 1032632Sstever@eecs.umich.edu '''Add a c/c++ source file to the build''' 104955SN/A def __init__(self, source, Werror=True, swig=False, bin_only=False, 105955SN/A skip_lib=False): 106955SN/A super(Source, self).__init__(source) 107955SN/A 1082632Sstever@eecs.umich.edu self.Werror = Werror 109955SN/A self.swig = swig 1102632Sstever@eecs.umich.edu self.bin_only = bin_only 1112632Sstever@eecs.umich.edu self.skip_lib = bin_only or skip_lib 1122632Sstever@eecs.umich.edu 1132632Sstever@eecs.umich.educlass PySource(SourceFile): 1142632Sstever@eecs.umich.edu '''Add a python source file to the named package''' 1152632Sstever@eecs.umich.edu invalid_sym_char = re.compile('[^A-z0-9_]') 1162632Sstever@eecs.umich.edu modules = {} 1173053Sstever@eecs.umich.edu tnodes = {} 1183053Sstever@eecs.umich.edu symnames = {} 1193053Sstever@eecs.umich.edu 1203053Sstever@eecs.umich.edu def __init__(self, package, source): 1213053Sstever@eecs.umich.edu super(PySource, self).__init__(source) 1223053Sstever@eecs.umich.edu 1233053Sstever@eecs.umich.edu modname,ext = self.extname 1243053Sstever@eecs.umich.edu assert ext == 'py' 1253053Sstever@eecs.umich.edu 1263053Sstever@eecs.umich.edu if package: 1273053Sstever@eecs.umich.edu path = package.split('.') 1283053Sstever@eecs.umich.edu else: 1293053Sstever@eecs.umich.edu path = [] 1303053Sstever@eecs.umich.edu 1313053Sstever@eecs.umich.edu modpath = path[:] 1323053Sstever@eecs.umich.edu if modname != '__init__': 1332632Sstever@eecs.umich.edu modpath += [ modname ] 1342632Sstever@eecs.umich.edu modpath = '.'.join(modpath) 1352632Sstever@eecs.umich.edu 1362632Sstever@eecs.umich.edu arcpath = path + [ self.basename ] 1372632Sstever@eecs.umich.edu abspath = self.snode.abspath 1382632Sstever@eecs.umich.edu if not exists(abspath): 1393718Sstever@eecs.umich.edu abspath = self.tnode.abspath 1403718Sstever@eecs.umich.edu 1413718Sstever@eecs.umich.edu self.package = package 1423718Sstever@eecs.umich.edu self.modname = modname 1433718Sstever@eecs.umich.edu self.modpath = modpath 1443718Sstever@eecs.umich.edu self.arcname = joinpath(*arcpath) 1453718Sstever@eecs.umich.edu self.abspath = abspath 1463718Sstever@eecs.umich.edu self.compiled = File(self.filename + 'c') 1473718Sstever@eecs.umich.edu self.cpp = File(self.filename + '.cc') 1483718Sstever@eecs.umich.edu self.symname = PySource.invalid_sym_char.sub('_', modpath) 1493718Sstever@eecs.umich.edu 1503718Sstever@eecs.umich.edu PySource.modules[modpath] = self 1513718Sstever@eecs.umich.edu PySource.tnodes[self.tnode] = self 1522634Sstever@eecs.umich.edu PySource.symnames[self.symname] = self 1532634Sstever@eecs.umich.edu 1542632Sstever@eecs.umich.educlass SimObject(PySource): 1552638Sstever@eecs.umich.edu '''Add a SimObject python file as a python source object and add 1562632Sstever@eecs.umich.edu it to a list of sim object modules''' 1572632Sstever@eecs.umich.edu 1582632Sstever@eecs.umich.edu fixed = False 1592632Sstever@eecs.umich.edu modnames = [] 1602632Sstever@eecs.umich.edu 1612632Sstever@eecs.umich.edu def __init__(self, source): 1621858SN/A super(SimObject, self).__init__('m5.objects', source) 1633716Sstever@eecs.umich.edu if self.fixed: 1642638Sstever@eecs.umich.edu raise AttributeError, "Too late to call SimObject now." 1652638Sstever@eecs.umich.edu 1662638Sstever@eecs.umich.edu bisect.insort_right(SimObject.modnames, self.modname) 1672638Sstever@eecs.umich.edu 1682638Sstever@eecs.umich.educlass SwigSource(SourceFile): 1692638Sstever@eecs.umich.edu '''Add a swig file to build''' 1702638Sstever@eecs.umich.edu 1713716Sstever@eecs.umich.edu def __init__(self, package, source): 1722634Sstever@eecs.umich.edu super(SwigSource, self).__init__(source) 1732634Sstever@eecs.umich.edu 174955SN/A modname,ext = self.extname 175955SN/A assert ext == 'i' 176955SN/A 177955SN/A self.module = modname 178955SN/A cc_file = joinpath(self.dirname, modname + '_wrap.cc') 179955SN/A py_file = joinpath(self.dirname, modname + '.py') 180955SN/A 181955SN/A self.cc_source = Source(cc_file, swig=True) 1821858SN/A self.py_source = PySource(package, py_file) 1831858SN/A 1842632Sstever@eecs.umich.eduunit_tests = [] 185955SN/Adef UnitTest(target, sources): 1863643Ssaidi@eecs.umich.edu if not isinstance(sources, (list, tuple)): 1873643Ssaidi@eecs.umich.edu sources = [ sources ] 1883643Ssaidi@eecs.umich.edu 1893643Ssaidi@eecs.umich.edu sources = [ Source(src, skip_lib=True) for src in sources ] 1903643Ssaidi@eecs.umich.edu unit_tests.append((target, sources)) 1913643Ssaidi@eecs.umich.edu 1923643Ssaidi@eecs.umich.edu# Children should have access 1933643Ssaidi@eecs.umich.eduExport('Source') 1944494Ssaidi@eecs.umich.eduExport('PySource') 1954494Ssaidi@eecs.umich.eduExport('SimObject') 1963716Sstever@eecs.umich.eduExport('SwigSource') 1971105SN/AExport('UnitTest') 1982667Sstever@eecs.umich.edu 1992667Sstever@eecs.umich.edu######################################################################## 2002667Sstever@eecs.umich.edu# 2012667Sstever@eecs.umich.edu# Trace Flags 2022667Sstever@eecs.umich.edu# 2032667Sstever@eecs.umich.edutrace_flags = {} 2041869SN/Adef TraceFlag(name, desc=None): 2051869SN/A if name in trace_flags: 2061869SN/A raise AttributeError, "Flag %s already specified" % name 2071869SN/A trace_flags[name] = (name, (), desc) 2081869SN/A 2091065SN/Adef CompoundFlag(name, flags, desc=None): 2102632Sstever@eecs.umich.edu if name in trace_flags: 2112632Sstever@eecs.umich.edu raise AttributeError, "Flag %s already specified" % name 2123918Ssaidi@eecs.umich.edu 2133918Ssaidi@eecs.umich.edu compound = tuple(flags) 2143940Ssaidi@eecs.umich.edu trace_flags[name] = (name, compound, desc) 2153918Ssaidi@eecs.umich.edu 2163918Ssaidi@eecs.umich.eduExport('TraceFlag') 2173918Ssaidi@eecs.umich.eduExport('CompoundFlag') 2183918Ssaidi@eecs.umich.edu 2193918Ssaidi@eecs.umich.edu######################################################################## 2203918Ssaidi@eecs.umich.edu# 2213940Ssaidi@eecs.umich.edu# Set some compiler variables 2223940Ssaidi@eecs.umich.edu# 2233940Ssaidi@eecs.umich.edu 2243942Ssaidi@eecs.umich.edu# Include file paths are rooted in this directory. SCons will 2253940Ssaidi@eecs.umich.edu# automatically expand '.' to refer to both the source directory and 2263918Ssaidi@eecs.umich.edu# the corresponding build directory to pick up generated include 2273918Ssaidi@eecs.umich.edu# files. 228955SN/Aenv.Append(CPPPATH=Dir('.')) 2291858SN/A 2303918Ssaidi@eecs.umich.edufor extra_dir in extras_dir_list: 2313918Ssaidi@eecs.umich.edu env.Append(CPPPATH=Dir(extra_dir)) 2323918Ssaidi@eecs.umich.edu 2333918Ssaidi@eecs.umich.edu# Workaround for bug in SCons version > 0.97d20071212 2343940Ssaidi@eecs.umich.edu# Scons bug id: 2006 M5 Bug id: 308 2353940Ssaidi@eecs.umich.edufor root, dirs, files in os.walk(base_dir, topdown=True): 2363918Ssaidi@eecs.umich.edu Dir(root[len(base_dir) + 1:]) 2373918Ssaidi@eecs.umich.edu 2383918Ssaidi@eecs.umich.edu######################################################################## 2393918Ssaidi@eecs.umich.edu# 2403918Ssaidi@eecs.umich.edu# Walk the tree and execute all SConscripts in subdirectories 2413918Ssaidi@eecs.umich.edu# 2423918Ssaidi@eecs.umich.edu 2433918Ssaidi@eecs.umich.eduhere = Dir('.').srcnode().abspath 2443918Ssaidi@eecs.umich.edufor root, dirs, files in os.walk(base_dir, topdown=True): 2453940Ssaidi@eecs.umich.edu if root == here: 2463918Ssaidi@eecs.umich.edu # we don't want to recurse back into this SConscript 2473918Ssaidi@eecs.umich.edu continue 2481851SN/A 2491851SN/A if 'SConscript' in files: 2501858SN/A build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 2512632Sstever@eecs.umich.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 252955SN/A 2533053Sstever@eecs.umich.edufor extra_dir in extras_dir_list: 2543053Sstever@eecs.umich.edu prefix_len = len(dirname(extra_dir)) + 1 2553053Sstever@eecs.umich.edu for root, dirs, files in os.walk(extra_dir, topdown=True): 2563053Sstever@eecs.umich.edu if 'SConscript' in files: 2573053Sstever@eecs.umich.edu build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 2583053Sstever@eecs.umich.edu SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 2593053Sstever@eecs.umich.edu 2603053Sstever@eecs.umich.edufor opt in export_vars: 2613053Sstever@eecs.umich.edu env.ConfigFile(opt) 2624742Sstever@eecs.umich.edu 2634742Sstever@eecs.umich.edudef makeTheISA(source, target, env): 2643053Sstever@eecs.umich.edu isas = [ src.get_contents() for src in source ] 2653053Sstever@eecs.umich.edu target_isa = env['TARGET_ISA'] 2663053Sstever@eecs.umich.edu def define(isa): 2673053Sstever@eecs.umich.edu return isa.upper() + '_ISA' 2683053Sstever@eecs.umich.edu 2693053Sstever@eecs.umich.edu def namespace(isa): 2703053Sstever@eecs.umich.edu return isa[0].upper() + isa[1:].lower() + 'ISA' 2713053Sstever@eecs.umich.edu 2723053Sstever@eecs.umich.edu 2732667Sstever@eecs.umich.edu code = code_formatter() 2744554Sbinkertn@umich.edu code('''\ 2754554Sbinkertn@umich.edu#ifndef __CONFIG_THE_ISA_HH__ 2762667Sstever@eecs.umich.edu#define __CONFIG_THE_ISA_HH__ 2774554Sbinkertn@umich.edu 2784554Sbinkertn@umich.edu''') 2794554Sbinkertn@umich.edu 2804554Sbinkertn@umich.edu for i,isa in enumerate(isas): 2814554Sbinkertn@umich.edu code('#define $0 $1', define(isa), i + 1) 2824554Sbinkertn@umich.edu 2834554Sbinkertn@umich.edu code(''' 2844554Sbinkertn@umich.edu 2854554Sbinkertn@umich.edu#define THE_ISA ${{define(target_isa)}} 2864554Sbinkertn@umich.edu#define TheISA ${{namespace(target_isa)}} 2872667Sstever@eecs.umich.edu 2884554Sbinkertn@umich.edu#endif // __CONFIG_THE_ISA_HH__''') 2894554Sbinkertn@umich.edu 2904554Sbinkertn@umich.edu code.write(str(target[0])) 2914554Sbinkertn@umich.edu 2922667Sstever@eecs.umich.eduenv.Command('config/the_isa.hh', map(Value, all_isa_list), 2934554Sbinkertn@umich.edu MakeAction(makeTheISA, Transform("CFG ISA", 0))) 2942667Sstever@eecs.umich.edu 2954554Sbinkertn@umich.edu######################################################################## 2964554Sbinkertn@umich.edu# 2972667Sstever@eecs.umich.edu# Prevent any SimObjects from being added after this point, they 2982638Sstever@eecs.umich.edu# should all have been added in the SConscripts above 2992638Sstever@eecs.umich.edu# 3002638Sstever@eecs.umich.eduSimObject.fixed = True 3013716Sstever@eecs.umich.edu 3023716Sstever@eecs.umich.educlass DictImporter(object): 3031858SN/A '''This importer takes a dictionary of arbitrary module names that 3043118Sstever@eecs.umich.edu map to arbitrary filenames.''' 3053118Sstever@eecs.umich.edu def __init__(self, modules): 3063118Sstever@eecs.umich.edu self.modules = modules 3073118Sstever@eecs.umich.edu self.installed = set() 3083118Sstever@eecs.umich.edu 3093118Sstever@eecs.umich.edu def __del__(self): 3103118Sstever@eecs.umich.edu self.unload() 3113118Sstever@eecs.umich.edu 3123118Sstever@eecs.umich.edu def unload(self): 3133118Sstever@eecs.umich.edu import sys 3143118Sstever@eecs.umich.edu for module in self.installed: 3153716Sstever@eecs.umich.edu del sys.modules[module] 3163118Sstever@eecs.umich.edu self.installed = set() 3173118Sstever@eecs.umich.edu 3183118Sstever@eecs.umich.edu def find_module(self, fullname, path): 3193118Sstever@eecs.umich.edu if fullname == 'm5.defines': 3203118Sstever@eecs.umich.edu return self 3213118Sstever@eecs.umich.edu 3223118Sstever@eecs.umich.edu if fullname == 'm5.objects': 3233118Sstever@eecs.umich.edu return self 3243118Sstever@eecs.umich.edu 3253716Sstever@eecs.umich.edu if fullname.startswith('m5.internal'): 3263118Sstever@eecs.umich.edu return None 3273118Sstever@eecs.umich.edu 3283118Sstever@eecs.umich.edu source = self.modules.get(fullname, None) 3293118Sstever@eecs.umich.edu if source is not None and fullname.startswith('m5.objects'): 3303118Sstever@eecs.umich.edu return self 3313118Sstever@eecs.umich.edu 3323118Sstever@eecs.umich.edu return None 3333118Sstever@eecs.umich.edu 3343118Sstever@eecs.umich.edu def load_module(self, fullname): 3353118Sstever@eecs.umich.edu mod = imp.new_module(fullname) 3363483Ssaidi@eecs.umich.edu sys.modules[fullname] = mod 3373494Ssaidi@eecs.umich.edu self.installed.add(fullname) 3383494Ssaidi@eecs.umich.edu 3393483Ssaidi@eecs.umich.edu mod.__loader__ = self 3403483Ssaidi@eecs.umich.edu if fullname == 'm5.objects': 3413483Ssaidi@eecs.umich.edu mod.__path__ = fullname.split('.') 3423053Sstever@eecs.umich.edu return mod 3433053Sstever@eecs.umich.edu 3443918Ssaidi@eecs.umich.edu if fullname == 'm5.defines': 3453053Sstever@eecs.umich.edu mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 3463053Sstever@eecs.umich.edu return mod 3473053Sstever@eecs.umich.edu 3483053Sstever@eecs.umich.edu source = self.modules[fullname] 3493053Sstever@eecs.umich.edu if source.modname == '__init__': 3501858SN/A mod.__path__ = source.modpath 3511858SN/A mod.__file__ = source.abspath 3521858SN/A 3531858SN/A exec file(source.abspath, 'r') in mod.__dict__ 3541858SN/A 3551858SN/A return mod 3561859SN/A 3571858SN/Aimport m5.SimObject 3581858SN/Aimport m5.params 3591858SN/Afrom m5.util import code_formatter 3601859SN/A 3611859SN/Am5.SimObject.clear() 3621862SN/Am5.params.clear() 3633053Sstever@eecs.umich.edu 3643053Sstever@eecs.umich.edu# install the python importer so we can grab stuff from the source 3653053Sstever@eecs.umich.edu# tree itself. We can't have SimObjects added after this point or 3663053Sstever@eecs.umich.edu# else we won't know about them for the rest of the stuff. 3671859SN/Aimporter = DictImporter(PySource.modules) 3681859SN/Asys.meta_path[0:0] = [ importer ] 3691859SN/A 3701859SN/A# import all sim objects so we can populate the all_objects list 3711859SN/A# make sure that we're working with a list, then let's sort it 3721859SN/Afor modname in SimObject.modnames: 3731859SN/A exec('from m5.objects import %s' % modname) 3741859SN/A 3751862SN/A# we need to unload all of the currently imported modules so that they 3761859SN/A# will be re-imported the next time the sconscript is run 3771859SN/Aimporter.unload() 3781859SN/Asys.meta_path.remove(importer) 3791858SN/A 3801858SN/Asim_objects = m5.SimObject.allClasses 3812139SN/Aall_enums = m5.params.allEnums 3824202Sbinkertn@umich.edu 3834202Sbinkertn@umich.eduall_params = {} 3842139SN/Afor name,obj in sorted(sim_objects.iteritems()): 3852155SN/A for param in obj._params.local.values(): 3864202Sbinkertn@umich.edu # load the ptype attribute now because it depends on the 3874202Sbinkertn@umich.edu # current version of SimObject.allClasses, but when scons 3884202Sbinkertn@umich.edu # actually uses the value, all versions of 3892155SN/A # SimObject.allClasses will have been loaded 3901869SN/A param.ptype 3911869SN/A 3921869SN/A if not hasattr(param, 'swig_decl'): 3931869SN/A continue 3944202Sbinkertn@umich.edu pname = param.ptype_str 3954202Sbinkertn@umich.edu if pname not in all_params: 3964202Sbinkertn@umich.edu all_params[pname] = param 3974202Sbinkertn@umich.edu 3984202Sbinkertn@umich.edu######################################################################## 3994202Sbinkertn@umich.edu# 4004202Sbinkertn@umich.edu# calculate extra dependencies 4014202Sbinkertn@umich.edu# 4024202Sbinkertn@umich.edumodule_depends = ["m5", "m5.SimObject", "m5.params"] 4034202Sbinkertn@umich.edudepends = [ PySource.modules[dep].snode for dep in module_depends ] 4044202Sbinkertn@umich.edu 4054202Sbinkertn@umich.edu######################################################################## 4064202Sbinkertn@umich.edu# 4074202Sbinkertn@umich.edu# Commands for the basic automatically generated python files 4084202Sbinkertn@umich.edu# 4094202Sbinkertn@umich.edu 4101869SN/A# Generate Python file containing a dict specifying the current 4114202Sbinkertn@umich.edu# buildEnv flags. 4121869SN/Adef makeDefinesPyFile(target, source, env): 4132508SN/A build_env, hg_info = [ x.get_contents() for x in source ] 4142508SN/A 4152508SN/A code = code_formatter() 4162508SN/A code(""" 4174202Sbinkertn@umich.eduimport m5.internal 4181869SN/Aimport m5.util 4191869SN/A 4201869SN/AbuildEnv = m5.util.SmartDict($build_env) 4211869SN/AhgRev = '$hg_info' 4221869SN/A 4231869SN/AcompileDate = m5.internal.core.compileDate 4241965SN/A_globals = globals() 4251965SN/Afor key,val in m5.internal.core.__dict__.iteritems(): 4261965SN/A if key.startswith('flag_'): 4271869SN/A flag = key[5:] 4281869SN/A _globals[flag] = val 4292733Sktlim@umich.edudel _globals 4301869SN/A""") 4311884SN/A code.write(target[0].abspath) 4321884SN/A 4333356Sbinkertn@umich.edudefines_info = [ Value(build_env), Value(env['HG_INFO']) ] 4343356Sbinkertn@umich.edu# Generate a file with all of the compile options in it 4353356Sbinkertn@umich.eduenv.Command('python/m5/defines.py', defines_info, 4363356Sbinkertn@umich.edu MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 4371869SN/APySource('m5', 'python/m5/defines.py') 4381858SN/A 4391869SN/A# Generate python file containing info about the M5 source code 4401869SN/Adef makeInfoPyFile(target, source, env): 4411869SN/A code = code_formatter() 4421858SN/A for src in source: 4432761Sstever@eecs.umich.edu data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 4441869SN/A code('$src = ${{repr(data)}}') 4452733Sktlim@umich.edu code.write(str(target[0])) 4463584Ssaidi@eecs.umich.edu 4471869SN/A# Generate a file that wraps the basic top level files 4481869SN/Aenv.Command('python/m5/info.py', 4491869SN/A [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ], 4501869SN/A MakeAction(makeInfoPyFile, Transform("INFO"))) 4511869SN/APySource('m5', 'python/m5/info.py') 4521869SN/A 4531858SN/A######################################################################## 454955SN/A# 455955SN/A# Create all of the SimObject param headers and enum headers 4561869SN/A# 4571869SN/A 4581869SN/Adef createSimObjectParam(target, source, env): 4591869SN/A assert len(target) == 1 and len(source) == 1 4601869SN/A 4611869SN/A name = str(source[0].get_contents()) 4621869SN/A obj = sim_objects[name] 4631869SN/A 4641869SN/A code = code_formatter() 4651869SN/A obj.cxx_decl(code) 4661869SN/A code.write(target[0].abspath) 4671869SN/A 4681869SN/Adef createSwigParam(target, source, env): 4691869SN/A assert len(target) == 1 and len(source) == 1 4701869SN/A 4711869SN/A name = str(source[0].get_contents()) 4721869SN/A param = all_params[name] 4731869SN/A 4741869SN/A code = code_formatter() 4751869SN/A code('%module(package="m5.internal") $0_${name}', param.file_ext) 4761869SN/A param.swig_decl(code) 4771869SN/A code.write(target[0].abspath) 4781869SN/A 4791869SN/Adef createEnumStrings(target, source, env): 4801869SN/A assert len(target) == 1 and len(source) == 1 4811869SN/A 4821869SN/A name = str(source[0].get_contents()) 4831869SN/A obj = all_enums[name] 4841869SN/A 4853716Sstever@eecs.umich.edu code = code_formatter() 4863356Sbinkertn@umich.edu obj.cxx_def(code) 4873356Sbinkertn@umich.edu code.write(target[0].abspath) 4883356Sbinkertn@umich.edu 4893356Sbinkertn@umich.edudef createEnumParam(target, source, env): 4903356Sbinkertn@umich.edu assert len(target) == 1 and len(source) == 1 4913356Sbinkertn@umich.edu 4923356Sbinkertn@umich.edu name = str(source[0].get_contents()) 4931869SN/A obj = all_enums[name] 4941869SN/A 4951869SN/A code = code_formatter() 4961869SN/A obj.cxx_decl(code) 4971869SN/A code.write(target[0].abspath) 4981869SN/A 4991869SN/Adef createEnumSwig(target, source, env): 5002655Sstever@eecs.umich.edu assert len(target) == 1 and len(source) == 1 5012655Sstever@eecs.umich.edu 5022655Sstever@eecs.umich.edu name = str(source[0].get_contents()) 5032655Sstever@eecs.umich.edu obj = all_enums[name] 5042655Sstever@eecs.umich.edu 5052655Sstever@eecs.umich.edu code = code_formatter() 5062655Sstever@eecs.umich.edu code('''\ 5072655Sstever@eecs.umich.edu%module(package="m5.internal") enum_$name 5082655Sstever@eecs.umich.edu 5092655Sstever@eecs.umich.edu%{ 5102655Sstever@eecs.umich.edu#include "enums/$name.hh" 5112655Sstever@eecs.umich.edu%} 5122655Sstever@eecs.umich.edu 5132655Sstever@eecs.umich.edu%include "enums/$name.hh" 5142655Sstever@eecs.umich.edu''') 5152655Sstever@eecs.umich.edu code.write(target[0].abspath) 5162655Sstever@eecs.umich.edu 5172655Sstever@eecs.umich.edu# Generate all of the SimObject param struct header files 5182655Sstever@eecs.umich.eduparams_hh_files = [] 5192655Sstever@eecs.umich.edufor name,simobj in sorted(sim_objects.iteritems()): 5202655Sstever@eecs.umich.edu py_source = PySource.modules[simobj.__module__] 5212655Sstever@eecs.umich.edu extra_deps = [ py_source.tnode ] 5222655Sstever@eecs.umich.edu 5232655Sstever@eecs.umich.edu hh_file = File('params/%s.hh' % name) 5242655Sstever@eecs.umich.edu params_hh_files.append(hh_file) 5252655Sstever@eecs.umich.edu env.Command(hh_file, Value(name), 5262634Sstever@eecs.umich.edu MakeAction(createSimObjectParam, Transform("SO PARAM"))) 5272634Sstever@eecs.umich.edu env.Depends(hh_file, depends + extra_deps) 5282634Sstever@eecs.umich.edu 5292634Sstever@eecs.umich.edu# Generate any parameter header files needed 5302634Sstever@eecs.umich.eduparams_i_files = [] 5312634Sstever@eecs.umich.edufor name,param in all_params.iteritems(): 5322638Sstever@eecs.umich.edu i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name)) 5332638Sstever@eecs.umich.edu params_i_files.append(i_file) 5343716Sstever@eecs.umich.edu env.Command(i_file, Value(name), 5352638Sstever@eecs.umich.edu MakeAction(createSwigParam, Transform("SW PARAM"))) 5362638Sstever@eecs.umich.edu env.Depends(i_file, depends) 5371869SN/A SwigSource('m5.internal', i_file) 5381869SN/A 5393546Sgblack@eecs.umich.edu# Generate all enum header files 5403546Sgblack@eecs.umich.edufor name,enum in sorted(all_enums.iteritems()): 5413546Sgblack@eecs.umich.edu py_source = PySource.modules[enum.__module__] 5423546Sgblack@eecs.umich.edu extra_deps = [ py_source.tnode ] 5434202Sbinkertn@umich.edu 5443546Sgblack@eecs.umich.edu cc_file = File('enums/%s.cc' % name) 5453546Sgblack@eecs.umich.edu env.Command(cc_file, Value(name), 5463546Sgblack@eecs.umich.edu MakeAction(createEnumStrings, Transform("ENUM STR"))) 5473546Sgblack@eecs.umich.edu env.Depends(cc_file, depends + extra_deps) 5483546Sgblack@eecs.umich.edu Source(cc_file) 5493546Sgblack@eecs.umich.edu 5503546Sgblack@eecs.umich.edu hh_file = File('enums/%s.hh' % name) 5513546Sgblack@eecs.umich.edu env.Command(hh_file, Value(name), 5523546Sgblack@eecs.umich.edu MakeAction(createEnumParam, Transform("EN PARAM"))) 5533546Sgblack@eecs.umich.edu env.Depends(hh_file, depends + extra_deps) 5544202Sbinkertn@umich.edu 5553546Sgblack@eecs.umich.edu i_file = File('python/m5/internal/enum_%s.i' % name) 5563546Sgblack@eecs.umich.edu env.Command(i_file, Value(name), 5573546Sgblack@eecs.umich.edu MakeAction(createEnumSwig, Transform("ENUMSWIG"))) 5583546Sgblack@eecs.umich.edu env.Depends(i_file, depends + extra_deps) 5593546Sgblack@eecs.umich.edu SwigSource('m5.internal', i_file) 5603546Sgblack@eecs.umich.edu 5613546Sgblack@eecs.umich.edudef buildParam(target, source, env): 5623546Sgblack@eecs.umich.edu name = source[0].get_contents() 5633546Sgblack@eecs.umich.edu obj = sim_objects[name] 5643546Sgblack@eecs.umich.edu class_path = obj.cxx_class.split('::') 5653546Sgblack@eecs.umich.edu classname = class_path[-1] 5663546Sgblack@eecs.umich.edu namespaces = class_path[:-1] 5673546Sgblack@eecs.umich.edu params = obj._params.local.values() 5683546Sgblack@eecs.umich.edu 5693546Sgblack@eecs.umich.edu code = code_formatter() 5703546Sgblack@eecs.umich.edu 5713546Sgblack@eecs.umich.edu code('%module(package="m5.internal") param_$name') 5723546Sgblack@eecs.umich.edu code() 5733546Sgblack@eecs.umich.edu code('%{') 5743546Sgblack@eecs.umich.edu code('#include "params/$obj.hh"') 5754202Sbinkertn@umich.edu for param in params: 5763546Sgblack@eecs.umich.edu param.cxx_predecls(code) 5773546Sgblack@eecs.umich.edu code('%}') 5783546Sgblack@eecs.umich.edu code() 579955SN/A 580955SN/A for param in params: 581955SN/A param.swig_predecls(code) 582955SN/A 5831858SN/A code() 5841858SN/A if obj._base: 5851858SN/A code('%import "python/m5/internal/param_${{obj._base}}.i"') 5862632Sstever@eecs.umich.edu code() 5872632Sstever@eecs.umich.edu obj.swig_objdecls(code) 5882632Sstever@eecs.umich.edu code() 5892632Sstever@eecs.umich.edu 5902632Sstever@eecs.umich.edu code('%include "params/$obj.hh"') 5912634Sstever@eecs.umich.edu 5922638Sstever@eecs.umich.edu code.write(target[0].abspath) 5932023SN/A 5942632Sstever@eecs.umich.edufor name in sim_objects.iterkeys(): 5952632Sstever@eecs.umich.edu params_file = File('python/m5/internal/param_%s.i' % name) 5962632Sstever@eecs.umich.edu env.Command(params_file, Value(name), 5972632Sstever@eecs.umich.edu MakeAction(buildParam, Transform("BLDPARAM"))) 5982632Sstever@eecs.umich.edu env.Depends(params_file, depends) 5993716Sstever@eecs.umich.edu SwigSource('m5.internal', params_file) 6002632Sstever@eecs.umich.edu 6012632Sstever@eecs.umich.edu# Generate the main swig init file 6022632Sstever@eecs.umich.edudef makeEmbeddedSwigInit(target, source, env): 6032632Sstever@eecs.umich.edu code = code_formatter() 6042632Sstever@eecs.umich.edu module = source[0].get_contents() 6052023SN/A code('''\ 6062632Sstever@eecs.umich.edu#include "sim/init.hh" 6072632Sstever@eecs.umich.edu 6081889SN/Aextern "C" { 6091889SN/A void init_${module}(); 6102632Sstever@eecs.umich.edu} 6112632Sstever@eecs.umich.edu 6122632Sstever@eecs.umich.eduEmbeddedSwig embed_swig_${module}(init_${module}); 6132632Sstever@eecs.umich.edu''') 6143716Sstever@eecs.umich.edu code.write(str(target[0])) 6153716Sstever@eecs.umich.edu 6162632Sstever@eecs.umich.edu# Build all swig modules 6172632Sstever@eecs.umich.edufor swig in SwigSource.all: 6182632Sstever@eecs.umich.edu env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 6192632Sstever@eecs.umich.edu MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 6202632Sstever@eecs.umich.edu '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 6212632Sstever@eecs.umich.edu init_file = 'python/swig/init_%s.cc' % swig.module 6222632Sstever@eecs.umich.edu env.Command(init_file, Value(swig.module), 6232632Sstever@eecs.umich.edu MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) 6241888SN/A Source(init_file) 6251888SN/A 6261869SN/Adef getFlags(source_flags): 6271869SN/A flagsMap = {} 6281858SN/A flagsList = [] 6292598SN/A for s in source_flags: 6302598SN/A val = eval(s.get_contents()) 6312598SN/A name, compound, desc = val 6322598SN/A flagsList.append(val) 6332598SN/A flagsMap[name] = bool(compound) 6341858SN/A 6351858SN/A for name, compound, desc in flagsList: 6361858SN/A for flag in compound: 6371858SN/A if flag not in flagsMap: 6381858SN/A raise AttributeError, "Trace flag %s not found" % flag 6391858SN/A if flagsMap[flag]: 6401858SN/A raise AttributeError, \ 6411858SN/A "Compound flag can't point to another compound flag" 6421858SN/A 6431871SN/A flagsList.sort() 6441858SN/A return flagsList 6451858SN/A 6461858SN/A 6471858SN/A# Generate traceflags.py 6481858SN/Adef traceFlagsPy(target, source, env): 6491858SN/A assert(len(target) == 1) 6501858SN/A code = code_formatter() 6511858SN/A 6521858SN/A allFlags = getFlags(source) 6531858SN/A 6541858SN/A code('basic = [') 6551859SN/A code.indent() 6561859SN/A for flag, compound, desc in allFlags: 6571869SN/A if not compound: 6581888SN/A code("'$flag',") 6592632Sstever@eecs.umich.edu code(']') 6601869SN/A code.dedent() 6611884SN/A code() 6621884SN/A 6631884SN/A code('compound = [') 6641884SN/A code.indent() 6651884SN/A code("'All',") 6661884SN/A for flag, compound, desc in allFlags: 6671965SN/A if compound: 6681965SN/A code("'$flag',") 6691965SN/A code("]") 6702761Sstever@eecs.umich.edu code.dedent() 6711869SN/A code() 6721869SN/A 6732632Sstever@eecs.umich.edu code("all = frozenset(basic + compound)") 6742667Sstever@eecs.umich.edu code() 6751869SN/A 6761869SN/A code('compoundMap = {') 6772929Sktlim@umich.edu code.indent() 6782929Sktlim@umich.edu all = tuple([flag for flag,compound,desc in allFlags if not compound]) 6793716Sstever@eecs.umich.edu code("'All' : $all,") 6802929Sktlim@umich.edu for flag, compound, desc in allFlags: 681955SN/A if compound: 6822598SN/A code("'$flag' : $compound,") 6832598SN/A code('}') 6843546Sgblack@eecs.umich.edu code.dedent() 685955SN/A code() 686955SN/A 687955SN/A code('descriptions = {') 6881530SN/A code.indent() 689955SN/A code("'All' : 'All flags',") 690955SN/A for flag, compound, desc in allFlags: 691955SN/A code("'$flag' : '$desc',") 692 code("}") 693 code.dedent() 694 695 code.write(str(target[0])) 696 697def traceFlagsCC(target, source, env): 698 assert(len(target) == 1) 699 700 allFlags = getFlags(source) 701 code = code_formatter() 702 703 # file header 704 code(''' 705/* 706 * DO NOT EDIT THIS FILE! Automatically generated 707 */ 708 709#include "base/traceflags.hh" 710 711using namespace Trace; 712 713const char *Trace::flagStrings[] = 714{''') 715 716 code.indent() 717 # The string array is used by SimpleEnumParam to map the strings 718 # provided by the user to enum values. 719 for flag, compound, desc in allFlags: 720 if not compound: 721 code('"$flag",') 722 723 code('"All",') 724 for flag, compound, desc in allFlags: 725 if compound: 726 code('"$flag",') 727 code.dedent() 728 729 code('''\ 730}; 731 732const int Trace::numFlagStrings = ${{len(allFlags) + 1}}; 733 734''') 735 736 # Now define the individual compound flag arrays. There is an array 737 # for each compound flag listing the component base flags. 738 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 739 code('static const Flags AllMap[] = {') 740 code.indent() 741 for flag, compound, desc in allFlags: 742 if not compound: 743 code('$flag,') 744 code.dedent() 745 code('};') 746 code() 747 748 for flag, compound, desc in allFlags: 749 if not compound: 750 continue 751 code('static const Flags ${flag}Map[] = {') 752 code.indent() 753 for flag in compound: 754 code('$flag,') 755 code('(Flags)-1') 756 code.dedent() 757 code('};') 758 code() 759 760 # Finally the compoundFlags[] array maps the compound flags 761 # to their individual arrays/ 762 code('const Flags *Trace::compoundFlags[] = {') 763 code.indent() 764 code('AllMap,') 765 for flag, compound, desc in allFlags: 766 if compound: 767 code('${flag}Map,') 768 # file trailer 769 code.dedent() 770 code('};') 771 772 code.write(str(target[0])) 773 774def traceFlagsHH(target, source, env): 775 assert(len(target) == 1) 776 777 allFlags = getFlags(source) 778 code = code_formatter() 779 780 # file header boilerplate 781 code('''\ 782/* 783 * DO NOT EDIT THIS FILE! 784 * 785 * Automatically generated from traceflags.py 786 */ 787 788#ifndef __BASE_TRACE_FLAGS_HH__ 789#define __BASE_TRACE_FLAGS_HH__ 790 791namespace Trace { 792 793enum Flags {''') 794 795 # Generate the enum. Base flags come first, then compound flags. 796 idx = 0 797 code.indent() 798 for flag, compound, desc in allFlags: 799 if not compound: 800 code('$flag = $idx,') 801 idx += 1 802 803 numBaseFlags = idx 804 code('NumFlags = $idx,') 805 code.dedent() 806 code() 807 808 # put a comment in here to separate base from compound flags 809 code(''' 810// The remaining enum values are *not* valid indices for Trace::flags. 811// They are "compound" flags, which correspond to sets of base 812// flags, and are used by changeFlag.''') 813 814 code.indent() 815 code('All = $idx,') 816 idx += 1 817 for flag, compound, desc in allFlags: 818 if compound: 819 code('$flag = $idx,') 820 idx += 1 821 822 numCompoundFlags = idx - numBaseFlags 823 code('NumCompoundFlags = $numCompoundFlags') 824 code.dedent() 825 826 # trailer boilerplate 827 code('''\ 828}; // enum Flags 829 830// Array of strings for SimpleEnumParam 831extern const char *flagStrings[]; 832extern const int numFlagStrings; 833 834// Array of arraay pointers: for each compound flag, gives the list of 835// base flags to set. Inidividual flag arrays are terminated by -1. 836extern const Flags *compoundFlags[]; 837 838} // namespace Trace 839 840#endif // __BASE_TRACE_FLAGS_HH__ 841''') 842 843 code.write(str(target[0])) 844 845flags = map(Value, trace_flags.values()) 846env.Command('base/traceflags.py', flags, 847 MakeAction(traceFlagsPy, Transform("TRACING", 0))) 848PySource('m5', 'base/traceflags.py') 849 850env.Command('base/traceflags.hh', flags, 851 MakeAction(traceFlagsHH, Transform("TRACING", 0))) 852env.Command('base/traceflags.cc', flags, 853 MakeAction(traceFlagsCC, Transform("TRACING", 0))) 854Source('base/traceflags.cc') 855 856# Embed python files. All .py files that have been indicated by a 857# PySource() call in a SConscript need to be embedded into the M5 858# library. To do that, we compile the file to byte code, marshal the 859# byte code, compress it, and then generate a c++ file that 860# inserts the result into an array. 861def embedPyFile(target, source, env): 862 def c_str(string): 863 if string is None: 864 return "0" 865 return '"%s"' % string 866 867 '''Action function to compile a .py into a code object, marshal 868 it, compress it, and stick it into an asm file so the code appears 869 as just bytes with a label in the data section''' 870 871 src = file(str(source[0]), 'r').read() 872 873 pysource = PySource.tnodes[source[0]] 874 compiled = compile(src, pysource.abspath, 'exec') 875 marshalled = marshal.dumps(compiled) 876 compressed = zlib.compress(marshalled) 877 data = compressed 878 sym = pysource.symname 879 880 code = code_formatter() 881 code('''\ 882#include "sim/init.hh" 883 884namespace { 885 886const char data_${sym}[] = { 887''') 888 code.indent() 889 step = 16 890 for i in xrange(0, len(data), step): 891 x = array.array('B', data[i:i+step]) 892 code(''.join('%d,' % d for d in x)) 893 code.dedent() 894 895 code('''}; 896 897EmbeddedPython embedded_${sym}( 898 ${{c_str(pysource.arcname)}}, 899 ${{c_str(pysource.abspath)}}, 900 ${{c_str(pysource.modpath)}}, 901 data_${sym}, 902 ${{len(data)}}, 903 ${{len(marshalled)}}); 904 905} // anonymous namespace 906''') 907 code.write(str(target[0])) 908 909for source in PySource.all: 910 env.Command(source.cpp, source.tnode, 911 MakeAction(embedPyFile, Transform("EMBED PY"))) 912 Source(source.cpp) 913 914######################################################################## 915# 916# Define binaries. Each different build type (debug, opt, etc.) gets 917# a slightly different build environment. 918# 919 920# List of constructed environments to pass back to SConstruct 921envList = [] 922 923date_source = Source('base/date.cc', skip_lib=True) 924 925# Function to create a new build environment as clone of current 926# environment 'env' with modified object suffix and optional stripped 927# binary. Additional keyword arguments are appended to corresponding 928# build environment vars. 929def makeEnv(label, objsfx, strip = False, **kwargs): 930 # SCons doesn't know to append a library suffix when there is a '.' in the 931 # name. Use '_' instead. 932 libname = 'm5_' + label 933 exename = 'm5.' + label 934 935 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 936 new_env.Label = label 937 new_env.Append(**kwargs) 938 939 swig_env = new_env.Clone() 940 swig_env.Append(CCFLAGS='-Werror') 941 if env['GCC']: 942 swig_env.Append(CCFLAGS='-Wno-uninitialized') 943 swig_env.Append(CCFLAGS='-Wno-sign-compare') 944 swig_env.Append(CCFLAGS='-Wno-parentheses') 945 946 werror_env = new_env.Clone() 947 werror_env.Append(CCFLAGS='-Werror') 948 949 def make_obj(source, static, extra_deps = None): 950 '''This function adds the specified source to the correct 951 build environment, and returns the corresponding SCons Object 952 nodes''' 953 954 if source.swig: 955 env = swig_env 956 elif source.Werror: 957 env = werror_env 958 else: 959 env = new_env 960 961 if static: 962 obj = env.StaticObject(source.tnode) 963 else: 964 obj = env.SharedObject(source.tnode) 965 966 if extra_deps: 967 env.Depends(obj, extra_deps) 968 969 return obj 970 971 static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)] 972 shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)] 973 974 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 975 static_objs.append(static_date) 976 977 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 978 shared_objs.append(shared_date) 979 980 # First make a library of everything but main() so other programs can 981 # link against m5. 982 static_lib = new_env.StaticLibrary(libname, static_objs) 983 shared_lib = new_env.SharedLibrary(libname, shared_objs) 984 985 for target, sources in unit_tests: 986 objs = [ make_obj(s, static=True) for s in sources ] 987 new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs) 988 989 # Now link a stub with main() and the static library. 990 bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ] 991 progname = exename 992 if strip: 993 progname += '.unstripped' 994 995 targets = new_env.Program(progname, bin_objs + static_objs) 996 997 if strip: 998 if sys.platform == 'sunos5': 999 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1000 else: 1001 cmd = 'strip $SOURCE -o $TARGET' 1002 targets = new_env.Command(exename, progname, 1003 MakeAction(cmd, Transform("STRIP"))) 1004 1005 new_env.M5Binary = targets[0] 1006 envList.append(new_env) 1007 1008# Debug binary 1009ccflags = {} 1010if env['GCC']: 1011 if sys.platform == 'sunos5': 1012 ccflags['debug'] = '-gstabs+' 1013 else: 1014 ccflags['debug'] = '-ggdb3' 1015 ccflags['opt'] = '-g -O3' 1016 ccflags['fast'] = '-O3' 1017 ccflags['prof'] = '-O3 -g -pg' 1018elif env['SUNCC']: 1019 ccflags['debug'] = '-g0' 1020 ccflags['opt'] = '-g -O' 1021 ccflags['fast'] = '-fast' 1022 ccflags['prof'] = '-fast -g -pg' 1023elif env['ICC']: 1024 ccflags['debug'] = '-g -O0' 1025 ccflags['opt'] = '-g -O' 1026 ccflags['fast'] = '-fast' 1027 ccflags['prof'] = '-fast -g -pg' 1028else: 1029 print 'Unknown compiler, please fix compiler options' 1030 Exit(1) 1031 1032makeEnv('debug', '.do', 1033 CCFLAGS = Split(ccflags['debug']), 1034 CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 1035 1036# Optimized binary 1037makeEnv('opt', '.o', 1038 CCFLAGS = Split(ccflags['opt']), 1039 CPPDEFINES = ['TRACING_ON=1']) 1040 1041# "Fast" binary 1042makeEnv('fast', '.fo', strip = True, 1043 CCFLAGS = Split(ccflags['fast']), 1044 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 1045 1046# Profiled binary 1047makeEnv('prof', '.po', 1048 CCFLAGS = Split(ccflags['prof']), 1049 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1050 LINKFLAGS = '-pg') 1051 1052Return('envList') 1053