1# -*- mode:python -*- 2 3# Copyright (c) 2004-2005 The Regents of The University of Michigan 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer; 10# redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution; 13# neither the name of the copyright holders nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29# Authors: Nathan Binkert 30 31import array 32import bisect 33import imp 34import marshal 35import os 36import re 37import sys 38import zlib 39 40from os.path import basename, dirname, exists, isdir, isfile, join as joinpath 41 42import SCons 43 44# This file defines how to build a particular configuration of M5 45# based on variable settings in the 'env' build environment. 46 47Import('*') 48 49# Children need to see the environment 50Export('env') 51 52build_env = [(opt, env[opt]) for opt in export_vars] 53 54from m5.util import code_formatter 55 56######################################################################## 57# Code for adding source files of various types 58# 59class SourceMeta(type): 60 def __init__(cls, name, bases, dict): 61 super(SourceMeta, cls).__init__(name, bases, dict) 62 cls.all = [] 63 64 def get(cls, **kwargs): 65 for src in cls.all: 66 for attr,value in kwargs.iteritems(): 67 if getattr(src, attr) != value: 68 break 69 else: 70 yield src 71 72class SourceFile(object): 73 __metaclass__ = SourceMeta 74 def __init__(self, source): 75 tnode = source 76 if not isinstance(source, SCons.Node.FS.File): 77 tnode = File(source) 78 79 self.tnode = tnode 80 self.snode = tnode.srcnode() 81 self.filename = str(tnode) 82 self.dirname = dirname(self.filename) 83 self.basename = basename(self.filename) 84 index = self.basename.rfind('.') 85 if index <= 0: 86 # dot files aren't extensions 87 self.extname = self.basename, None 88 else: 89 self.extname = self.basename[:index], self.basename[index+1:] 90 91 for base in type(self).__mro__: 92 if issubclass(base, SourceFile): 93 base.all.append(self) 94 95 def __lt__(self, other): return self.filename < other.filename 96 def __le__(self, other): return self.filename <= other.filename 97 def __gt__(self, other): return self.filename > other.filename 98 def __ge__(self, other): return self.filename >= other.filename 99 def __eq__(self, other): return self.filename == other.filename 100 def __ne__(self, other): return self.filename != other.filename 101 102class Source(SourceFile): 103 '''Add a c/c++ source file to the build''' 104 def __init__(self, source, Werror=True, swig=False, bin_only=False, 105 skip_lib=False): 106 super(Source, self).__init__(source) 107 108 self.Werror = Werror 109 self.swig = swig 110 self.bin_only = bin_only 111 self.skip_lib = bin_only or skip_lib 112 113class PySource(SourceFile): 114 '''Add a python source file to the named package''' 115 invalid_sym_char = re.compile('[^A-z0-9_]') 116 modules = {} 117 tnodes = {} 118 symnames = {} 119 120 def __init__(self, package, source): 121 super(PySource, self).__init__(source) 122 123 modname,ext = self.extname 124 assert ext == 'py' 125 126 if package: 127 path = package.split('.') 128 else: 129 path = [] 130 131 modpath = path[:] 132 if modname != '__init__': 133 modpath += [ modname ] 134 modpath = '.'.join(modpath) 135 136 arcpath = path + [ self.basename ] 137 abspath = self.snode.abspath 138 if not exists(abspath): 139 abspath = self.tnode.abspath 140 141 self.package = package 142 self.modname = modname 143 self.modpath = modpath 144 self.arcname = joinpath(*arcpath) 145 self.abspath = abspath 146 self.compiled = File(self.filename + 'c') 147 self.cpp = File(self.filename + '.cc') 148 self.symname = PySource.invalid_sym_char.sub('_', modpath) 149 150 PySource.modules[modpath] = self 151 PySource.tnodes[self.tnode] = self 152 PySource.symnames[self.symname] = self 153 154class SimObject(PySource): 155 '''Add a SimObject python file as a python source object and add 156 it to a list of sim object modules''' 157 158 fixed = False 159 modnames = [] 160 161 def __init__(self, source): 162 super(SimObject, self).__init__('m5.objects', source) 163 if self.fixed: 164 raise AttributeError, "Too late to call SimObject now." 165 166 bisect.insort_right(SimObject.modnames, self.modname) 167 168class SwigSource(SourceFile): 169 '''Add a swig file to build''' 170 171 def __init__(self, package, source): 172 super(SwigSource, self).__init__(source) 173 174 modname,ext = self.extname 175 assert ext == 'i' 176 177 self.module = modname 178 cc_file = joinpath(self.dirname, modname + '_wrap.cc') 179 py_file = joinpath(self.dirname, modname + '.py') 180 181 self.cc_source = Source(cc_file, swig=True) 182 self.py_source = PySource(package, py_file) 183 184unit_tests = [] 185def UnitTest(target, sources): 186 if not isinstance(sources, (list, tuple)): 187 sources = [ sources ] 188 189 sources = [ Source(src, skip_lib=True) for src in sources ] 190 unit_tests.append((target, sources)) 191 192# Children should have access 193Export('Source') 194Export('PySource') 195Export('SimObject') 196Export('SwigSource') 197Export('UnitTest') 198 199######################################################################## 200# 201# Trace Flags 202# 203trace_flags = {} 204def TraceFlag(name, desc=None): 205 if name in trace_flags: 206 raise AttributeError, "Flag %s already specified" % name 207 trace_flags[name] = (name, (), desc) 208 209def CompoundFlag(name, flags, desc=None): 210 if name in trace_flags: 211 raise AttributeError, "Flag %s already specified" % name 212 213 compound = tuple(flags) 214 trace_flags[name] = (name, compound, desc) 215 216Export('TraceFlag') 217Export('CompoundFlag') 218 219######################################################################## 220# 221# Set some compiler variables 222# 223 224# Include file paths are rooted in this directory. SCons will 225# automatically expand '.' to refer to both the source directory and 226# the corresponding build directory to pick up generated include 227# files. 228env.Append(CPPPATH=Dir('.')) 229 230for extra_dir in extras_dir_list: 231 env.Append(CPPPATH=Dir(extra_dir)) 232 233# Workaround for bug in SCons version > 0.97d20071212 234# Scons bug id: 2006 M5 Bug id: 308 235for root, dirs, files in os.walk(base_dir, topdown=True): 236 Dir(root[len(base_dir) + 1:]) 237 238######################################################################## 239# 240# Walk the tree and execute all SConscripts in subdirectories 241# 242 243here = Dir('.').srcnode().abspath 244for root, dirs, files in os.walk(base_dir, topdown=True): 245 if root == here: 246 # we don't want to recurse back into this SConscript 247 continue 248 249 if 'SConscript' in files: 250 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 251 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 252 253for extra_dir in extras_dir_list: 254 prefix_len = len(dirname(extra_dir)) + 1 255 for root, dirs, files in os.walk(extra_dir, topdown=True): 256 if 'SConscript' in files: 257 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 258 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 259 260for opt in export_vars: 261 env.ConfigFile(opt) 262 263def makeTheISA(source, target, env): 264 isas = [ src.get_contents() for src in source ] 265 target_isa = env['TARGET_ISA'] 266 def define(isa): 267 return isa.upper() + '_ISA' 268 269 def namespace(isa): 270 return isa[0].upper() + isa[1:].lower() + 'ISA' 271 272 273 code = code_formatter() 274 code('''\ 275#ifndef __CONFIG_THE_ISA_HH__ 276#define __CONFIG_THE_ISA_HH__ 277 278''') 279 280 for i,isa in enumerate(isas): 281 code('#define $0 $1', define(isa), i + 1) 282 283 code(''' 284 285#define THE_ISA ${{define(target_isa)}} 286#define TheISA ${{namespace(target_isa)}} 287 288#endif // __CONFIG_THE_ISA_HH__''') 289 290 code.write(str(target[0])) 291
| 1# -*- mode:python -*- 2 3# Copyright (c) 2004-2005 The Regents of The University of Michigan 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer; 10# redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution; 13# neither the name of the copyright holders nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29# Authors: Nathan Binkert 30 31import array 32import bisect 33import imp 34import marshal 35import os 36import re 37import sys 38import zlib 39 40from os.path import basename, dirname, exists, isdir, isfile, join as joinpath 41 42import SCons 43 44# This file defines how to build a particular configuration of M5 45# based on variable settings in the 'env' build environment. 46 47Import('*') 48 49# Children need to see the environment 50Export('env') 51 52build_env = [(opt, env[opt]) for opt in export_vars] 53 54from m5.util import code_formatter 55 56######################################################################## 57# Code for adding source files of various types 58# 59class SourceMeta(type): 60 def __init__(cls, name, bases, dict): 61 super(SourceMeta, cls).__init__(name, bases, dict) 62 cls.all = [] 63 64 def get(cls, **kwargs): 65 for src in cls.all: 66 for attr,value in kwargs.iteritems(): 67 if getattr(src, attr) != value: 68 break 69 else: 70 yield src 71 72class SourceFile(object): 73 __metaclass__ = SourceMeta 74 def __init__(self, source): 75 tnode = source 76 if not isinstance(source, SCons.Node.FS.File): 77 tnode = File(source) 78 79 self.tnode = tnode 80 self.snode = tnode.srcnode() 81 self.filename = str(tnode) 82 self.dirname = dirname(self.filename) 83 self.basename = basename(self.filename) 84 index = self.basename.rfind('.') 85 if index <= 0: 86 # dot files aren't extensions 87 self.extname = self.basename, None 88 else: 89 self.extname = self.basename[:index], self.basename[index+1:] 90 91 for base in type(self).__mro__: 92 if issubclass(base, SourceFile): 93 base.all.append(self) 94 95 def __lt__(self, other): return self.filename < other.filename 96 def __le__(self, other): return self.filename <= other.filename 97 def __gt__(self, other): return self.filename > other.filename 98 def __ge__(self, other): return self.filename >= other.filename 99 def __eq__(self, other): return self.filename == other.filename 100 def __ne__(self, other): return self.filename != other.filename 101 102class Source(SourceFile): 103 '''Add a c/c++ source file to the build''' 104 def __init__(self, source, Werror=True, swig=False, bin_only=False, 105 skip_lib=False): 106 super(Source, self).__init__(source) 107 108 self.Werror = Werror 109 self.swig = swig 110 self.bin_only = bin_only 111 self.skip_lib = bin_only or skip_lib 112 113class PySource(SourceFile): 114 '''Add a python source file to the named package''' 115 invalid_sym_char = re.compile('[^A-z0-9_]') 116 modules = {} 117 tnodes = {} 118 symnames = {} 119 120 def __init__(self, package, source): 121 super(PySource, self).__init__(source) 122 123 modname,ext = self.extname 124 assert ext == 'py' 125 126 if package: 127 path = package.split('.') 128 else: 129 path = [] 130 131 modpath = path[:] 132 if modname != '__init__': 133 modpath += [ modname ] 134 modpath = '.'.join(modpath) 135 136 arcpath = path + [ self.basename ] 137 abspath = self.snode.abspath 138 if not exists(abspath): 139 abspath = self.tnode.abspath 140 141 self.package = package 142 self.modname = modname 143 self.modpath = modpath 144 self.arcname = joinpath(*arcpath) 145 self.abspath = abspath 146 self.compiled = File(self.filename + 'c') 147 self.cpp = File(self.filename + '.cc') 148 self.symname = PySource.invalid_sym_char.sub('_', modpath) 149 150 PySource.modules[modpath] = self 151 PySource.tnodes[self.tnode] = self 152 PySource.symnames[self.symname] = self 153 154class SimObject(PySource): 155 '''Add a SimObject python file as a python source object and add 156 it to a list of sim object modules''' 157 158 fixed = False 159 modnames = [] 160 161 def __init__(self, source): 162 super(SimObject, self).__init__('m5.objects', source) 163 if self.fixed: 164 raise AttributeError, "Too late to call SimObject now." 165 166 bisect.insort_right(SimObject.modnames, self.modname) 167 168class SwigSource(SourceFile): 169 '''Add a swig file to build''' 170 171 def __init__(self, package, source): 172 super(SwigSource, self).__init__(source) 173 174 modname,ext = self.extname 175 assert ext == 'i' 176 177 self.module = modname 178 cc_file = joinpath(self.dirname, modname + '_wrap.cc') 179 py_file = joinpath(self.dirname, modname + '.py') 180 181 self.cc_source = Source(cc_file, swig=True) 182 self.py_source = PySource(package, py_file) 183 184unit_tests = [] 185def UnitTest(target, sources): 186 if not isinstance(sources, (list, tuple)): 187 sources = [ sources ] 188 189 sources = [ Source(src, skip_lib=True) for src in sources ] 190 unit_tests.append((target, sources)) 191 192# Children should have access 193Export('Source') 194Export('PySource') 195Export('SimObject') 196Export('SwigSource') 197Export('UnitTest') 198 199######################################################################## 200# 201# Trace Flags 202# 203trace_flags = {} 204def TraceFlag(name, desc=None): 205 if name in trace_flags: 206 raise AttributeError, "Flag %s already specified" % name 207 trace_flags[name] = (name, (), desc) 208 209def CompoundFlag(name, flags, desc=None): 210 if name in trace_flags: 211 raise AttributeError, "Flag %s already specified" % name 212 213 compound = tuple(flags) 214 trace_flags[name] = (name, compound, desc) 215 216Export('TraceFlag') 217Export('CompoundFlag') 218 219######################################################################## 220# 221# Set some compiler variables 222# 223 224# Include file paths are rooted in this directory. SCons will 225# automatically expand '.' to refer to both the source directory and 226# the corresponding build directory to pick up generated include 227# files. 228env.Append(CPPPATH=Dir('.')) 229 230for extra_dir in extras_dir_list: 231 env.Append(CPPPATH=Dir(extra_dir)) 232 233# Workaround for bug in SCons version > 0.97d20071212 234# Scons bug id: 2006 M5 Bug id: 308 235for root, dirs, files in os.walk(base_dir, topdown=True): 236 Dir(root[len(base_dir) + 1:]) 237 238######################################################################## 239# 240# Walk the tree and execute all SConscripts in subdirectories 241# 242 243here = Dir('.').srcnode().abspath 244for root, dirs, files in os.walk(base_dir, topdown=True): 245 if root == here: 246 # we don't want to recurse back into this SConscript 247 continue 248 249 if 'SConscript' in files: 250 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 251 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 252 253for extra_dir in extras_dir_list: 254 prefix_len = len(dirname(extra_dir)) + 1 255 for root, dirs, files in os.walk(extra_dir, topdown=True): 256 if 'SConscript' in files: 257 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 258 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 259 260for opt in export_vars: 261 env.ConfigFile(opt) 262 263def makeTheISA(source, target, env): 264 isas = [ src.get_contents() for src in source ] 265 target_isa = env['TARGET_ISA'] 266 def define(isa): 267 return isa.upper() + '_ISA' 268 269 def namespace(isa): 270 return isa[0].upper() + isa[1:].lower() + 'ISA' 271 272 273 code = code_formatter() 274 code('''\ 275#ifndef __CONFIG_THE_ISA_HH__ 276#define __CONFIG_THE_ISA_HH__ 277 278''') 279 280 for i,isa in enumerate(isas): 281 code('#define $0 $1', define(isa), i + 1) 282 283 code(''' 284 285#define THE_ISA ${{define(target_isa)}} 286#define TheISA ${{namespace(target_isa)}} 287 288#endif // __CONFIG_THE_ISA_HH__''') 289 290 code.write(str(target[0])) 291
|
292env.Command('config/the_isa.hh', map(Value, all_isa_list), makeTheISA)
| 292env.Command('config/the_isa.hh', map(Value, all_isa_list), 293 MakeAction(makeTheISA, " [ CFG ISA] $STRIP_TARGET"))
|
293 294######################################################################## 295# 296# Prevent any SimObjects from being added after this point, they 297# should all have been added in the SConscripts above 298# 299SimObject.fixed = True 300 301class DictImporter(object): 302 '''This importer takes a dictionary of arbitrary module names that 303 map to arbitrary filenames.''' 304 def __init__(self, modules): 305 self.modules = modules 306 self.installed = set() 307 308 def __del__(self): 309 self.unload() 310 311 def unload(self): 312 import sys 313 for module in self.installed: 314 del sys.modules[module] 315 self.installed = set() 316 317 def find_module(self, fullname, path): 318 if fullname == 'm5.defines': 319 return self 320 321 if fullname == 'm5.objects': 322 return self 323 324 if fullname.startswith('m5.internal'): 325 return None 326 327 source = self.modules.get(fullname, None) 328 if source is not None and fullname.startswith('m5.objects'): 329 return self 330 331 return None 332 333 def load_module(self, fullname): 334 mod = imp.new_module(fullname) 335 sys.modules[fullname] = mod 336 self.installed.add(fullname) 337 338 mod.__loader__ = self 339 if fullname == 'm5.objects': 340 mod.__path__ = fullname.split('.') 341 return mod 342 343 if fullname == 'm5.defines': 344 mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 345 return mod 346 347 source = self.modules[fullname] 348 if source.modname == '__init__': 349 mod.__path__ = source.modpath 350 mod.__file__ = source.abspath 351 352 exec file(source.abspath, 'r') in mod.__dict__ 353 354 return mod 355 356import m5.SimObject 357import m5.params 358from m5.util import code_formatter 359 360m5.SimObject.clear() 361m5.params.clear() 362 363# install the python importer so we can grab stuff from the source 364# tree itself. We can't have SimObjects added after this point or 365# else we won't know about them for the rest of the stuff. 366importer = DictImporter(PySource.modules) 367sys.meta_path[0:0] = [ importer ] 368 369# import all sim objects so we can populate the all_objects list 370# make sure that we're working with a list, then let's sort it 371for modname in SimObject.modnames: 372 exec('from m5.objects import %s' % modname) 373 374# we need to unload all of the currently imported modules so that they 375# will be re-imported the next time the sconscript is run 376importer.unload() 377sys.meta_path.remove(importer) 378 379sim_objects = m5.SimObject.allClasses 380all_enums = m5.params.allEnums 381 382all_params = {} 383for name,obj in sorted(sim_objects.iteritems()): 384 for param in obj._params.local.values(): 385 # load the ptype attribute now because it depends on the 386 # current version of SimObject.allClasses, but when scons 387 # actually uses the value, all versions of 388 # SimObject.allClasses will have been loaded 389 param.ptype 390 391 if not hasattr(param, 'swig_decl'): 392 continue 393 pname = param.ptype_str 394 if pname not in all_params: 395 all_params[pname] = param 396 397######################################################################## 398# 399# calculate extra dependencies 400# 401module_depends = ["m5", "m5.SimObject", "m5.params"] 402depends = [ PySource.modules[dep].snode for dep in module_depends ] 403 404######################################################################## 405# 406# Commands for the basic automatically generated python files 407# 408 409# Generate Python file containing a dict specifying the current 410# buildEnv flags. 411def makeDefinesPyFile(target, source, env): 412 build_env, hg_info = [ x.get_contents() for x in source ] 413 414 code = code_formatter() 415 code(""" 416import m5.internal 417import m5.util 418 419buildEnv = m5.util.SmartDict($build_env) 420hgRev = '$hg_info' 421 422compileDate = m5.internal.core.compileDate 423_globals = globals() 424for key,val in m5.internal.core.__dict__.iteritems(): 425 if key.startswith('flag_'): 426 flag = key[5:] 427 _globals[flag] = val 428del _globals 429""") 430 code.write(target[0].abspath) 431 432defines_info = [ Value(build_env), Value(env['HG_INFO']) ] 433# Generate a file with all of the compile options in it
| 294 295######################################################################## 296# 297# Prevent any SimObjects from being added after this point, they 298# should all have been added in the SConscripts above 299# 300SimObject.fixed = True 301 302class DictImporter(object): 303 '''This importer takes a dictionary of arbitrary module names that 304 map to arbitrary filenames.''' 305 def __init__(self, modules): 306 self.modules = modules 307 self.installed = set() 308 309 def __del__(self): 310 self.unload() 311 312 def unload(self): 313 import sys 314 for module in self.installed: 315 del sys.modules[module] 316 self.installed = set() 317 318 def find_module(self, fullname, path): 319 if fullname == 'm5.defines': 320 return self 321 322 if fullname == 'm5.objects': 323 return self 324 325 if fullname.startswith('m5.internal'): 326 return None 327 328 source = self.modules.get(fullname, None) 329 if source is not None and fullname.startswith('m5.objects'): 330 return self 331 332 return None 333 334 def load_module(self, fullname): 335 mod = imp.new_module(fullname) 336 sys.modules[fullname] = mod 337 self.installed.add(fullname) 338 339 mod.__loader__ = self 340 if fullname == 'm5.objects': 341 mod.__path__ = fullname.split('.') 342 return mod 343 344 if fullname == 'm5.defines': 345 mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 346 return mod 347 348 source = self.modules[fullname] 349 if source.modname == '__init__': 350 mod.__path__ = source.modpath 351 mod.__file__ = source.abspath 352 353 exec file(source.abspath, 'r') in mod.__dict__ 354 355 return mod 356 357import m5.SimObject 358import m5.params 359from m5.util import code_formatter 360 361m5.SimObject.clear() 362m5.params.clear() 363 364# install the python importer so we can grab stuff from the source 365# tree itself. We can't have SimObjects added after this point or 366# else we won't know about them for the rest of the stuff. 367importer = DictImporter(PySource.modules) 368sys.meta_path[0:0] = [ importer ] 369 370# import all sim objects so we can populate the all_objects list 371# make sure that we're working with a list, then let's sort it 372for modname in SimObject.modnames: 373 exec('from m5.objects import %s' % modname) 374 375# we need to unload all of the currently imported modules so that they 376# will be re-imported the next time the sconscript is run 377importer.unload() 378sys.meta_path.remove(importer) 379 380sim_objects = m5.SimObject.allClasses 381all_enums = m5.params.allEnums 382 383all_params = {} 384for name,obj in sorted(sim_objects.iteritems()): 385 for param in obj._params.local.values(): 386 # load the ptype attribute now because it depends on the 387 # current version of SimObject.allClasses, but when scons 388 # actually uses the value, all versions of 389 # SimObject.allClasses will have been loaded 390 param.ptype 391 392 if not hasattr(param, 'swig_decl'): 393 continue 394 pname = param.ptype_str 395 if pname not in all_params: 396 all_params[pname] = param 397 398######################################################################## 399# 400# calculate extra dependencies 401# 402module_depends = ["m5", "m5.SimObject", "m5.params"] 403depends = [ PySource.modules[dep].snode for dep in module_depends ] 404 405######################################################################## 406# 407# Commands for the basic automatically generated python files 408# 409 410# Generate Python file containing a dict specifying the current 411# buildEnv flags. 412def makeDefinesPyFile(target, source, env): 413 build_env, hg_info = [ x.get_contents() for x in source ] 414 415 code = code_formatter() 416 code(""" 417import m5.internal 418import m5.util 419 420buildEnv = m5.util.SmartDict($build_env) 421hgRev = '$hg_info' 422 423compileDate = m5.internal.core.compileDate 424_globals = globals() 425for key,val in m5.internal.core.__dict__.iteritems(): 426 if key.startswith('flag_'): 427 flag = key[5:] 428 _globals[flag] = val 429del _globals 430""") 431 code.write(target[0].abspath) 432 433defines_info = [ Value(build_env), Value(env['HG_INFO']) ] 434# Generate a file with all of the compile options in it
|
434env.Command('python/m5/defines.py', defines_info, makeDefinesPyFile)
| 435env.Command('python/m5/defines.py', defines_info, 436 MakeAction(makeDefinesPyFile, " [ DEFINES] $STRIP_TARGET"))
|
435PySource('m5', 'python/m5/defines.py') 436 437# Generate python file containing info about the M5 source code 438def makeInfoPyFile(target, source, env): 439 code = code_formatter() 440 for src in source: 441 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 442 code('$src = ${{repr(data)}}') 443 code.write(str(target[0])) 444 445# Generate a file that wraps the basic top level files 446env.Command('python/m5/info.py', 447 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
| 437PySource('m5', 'python/m5/defines.py') 438 439# Generate python file containing info about the M5 source code 440def makeInfoPyFile(target, source, env): 441 code = code_formatter() 442 for src in source: 443 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 444 code('$src = ${{repr(data)}}') 445 code.write(str(target[0])) 446 447# Generate a file that wraps the basic top level files 448env.Command('python/m5/info.py', 449 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
|
448 makeInfoPyFile)
| 450 MakeAction(makeInfoPyFile, " [ INFO] $STRIP_TARGET"))
|
449PySource('m5', 'python/m5/info.py') 450 451######################################################################## 452# 453# Create all of the SimObject param headers and enum headers 454# 455 456def createSimObjectParam(target, source, env): 457 assert len(target) == 1 and len(source) == 1 458 459 name = str(source[0].get_contents()) 460 obj = sim_objects[name] 461 462 code = code_formatter() 463 obj.cxx_decl(code) 464 code.write(target[0].abspath) 465 466def createSwigParam(target, source, env): 467 assert len(target) == 1 and len(source) == 1 468 469 name = str(source[0].get_contents()) 470 param = all_params[name] 471 472 code = code_formatter() 473 code('%module(package="m5.internal") $0_${name}', param.file_ext) 474 param.swig_decl(code) 475 code.write(target[0].abspath) 476 477def createEnumStrings(target, source, env): 478 assert len(target) == 1 and len(source) == 1 479 480 name = str(source[0].get_contents()) 481 obj = all_enums[name] 482 483 code = code_formatter() 484 obj.cxx_def(code) 485 code.write(target[0].abspath) 486 487def createEnumParam(target, source, env): 488 assert len(target) == 1 and len(source) == 1 489 490 name = str(source[0].get_contents()) 491 obj = all_enums[name] 492 493 code = code_formatter() 494 obj.cxx_decl(code) 495 code.write(target[0].abspath) 496 497def createEnumSwig(target, source, env): 498 assert len(target) == 1 and len(source) == 1 499 500 name = str(source[0].get_contents()) 501 obj = all_enums[name] 502 503 code = code_formatter() 504 code('''\ 505%module(package="m5.internal") enum_$name 506 507%{ 508#include "enums/$name.hh" 509%} 510 511%include "enums/$name.hh" 512''') 513 code.write(target[0].abspath) 514 515# Generate all of the SimObject param struct header files 516params_hh_files = [] 517for name,simobj in sorted(sim_objects.iteritems()): 518 py_source = PySource.modules[simobj.__module__] 519 extra_deps = [ py_source.tnode ] 520 521 hh_file = File('params/%s.hh' % name) 522 params_hh_files.append(hh_file)
| 451PySource('m5', 'python/m5/info.py') 452 453######################################################################## 454# 455# Create all of the SimObject param headers and enum headers 456# 457 458def createSimObjectParam(target, source, env): 459 assert len(target) == 1 and len(source) == 1 460 461 name = str(source[0].get_contents()) 462 obj = sim_objects[name] 463 464 code = code_formatter() 465 obj.cxx_decl(code) 466 code.write(target[0].abspath) 467 468def createSwigParam(target, source, env): 469 assert len(target) == 1 and len(source) == 1 470 471 name = str(source[0].get_contents()) 472 param = all_params[name] 473 474 code = code_formatter() 475 code('%module(package="m5.internal") $0_${name}', param.file_ext) 476 param.swig_decl(code) 477 code.write(target[0].abspath) 478 479def createEnumStrings(target, source, env): 480 assert len(target) == 1 and len(source) == 1 481 482 name = str(source[0].get_contents()) 483 obj = all_enums[name] 484 485 code = code_formatter() 486 obj.cxx_def(code) 487 code.write(target[0].abspath) 488 489def createEnumParam(target, source, env): 490 assert len(target) == 1 and len(source) == 1 491 492 name = str(source[0].get_contents()) 493 obj = all_enums[name] 494 495 code = code_formatter() 496 obj.cxx_decl(code) 497 code.write(target[0].abspath) 498 499def createEnumSwig(target, source, env): 500 assert len(target) == 1 and len(source) == 1 501 502 name = str(source[0].get_contents()) 503 obj = all_enums[name] 504 505 code = code_formatter() 506 code('''\ 507%module(package="m5.internal") enum_$name 508 509%{ 510#include "enums/$name.hh" 511%} 512 513%include "enums/$name.hh" 514''') 515 code.write(target[0].abspath) 516 517# Generate all of the SimObject param struct header files 518params_hh_files = [] 519for name,simobj in sorted(sim_objects.iteritems()): 520 py_source = PySource.modules[simobj.__module__] 521 extra_deps = [ py_source.tnode ] 522 523 hh_file = File('params/%s.hh' % name) 524 params_hh_files.append(hh_file)
|
523 env.Command(hh_file, Value(name), createSimObjectParam)
| 525 env.Command(hh_file, Value(name), 526 MakeAction(createSimObjectParam, " [SO PARAM] $STRIP_TARGET"))
|
524 env.Depends(hh_file, depends + extra_deps) 525 526# Generate any parameter header files needed 527params_i_files = [] 528for name,param in all_params.iteritems(): 529 i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name)) 530 params_i_files.append(i_file)
| 527 env.Depends(hh_file, depends + extra_deps) 528 529# Generate any parameter header files needed 530params_i_files = [] 531for name,param in all_params.iteritems(): 532 i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name)) 533 params_i_files.append(i_file)
|
531 env.Command(i_file, Value(name), createSwigParam)
| 534 env.Command(i_file, Value(name), 535 MakeAction(createSwigParam, " [SW PARAM] $STRIP_TARGET"))
|
532 env.Depends(i_file, depends) 533 SwigSource('m5.internal', i_file) 534 535# Generate all enum header files 536for name,enum in sorted(all_enums.iteritems()): 537 py_source = PySource.modules[enum.__module__] 538 extra_deps = [ py_source.tnode ] 539 540 cc_file = File('enums/%s.cc' % name)
| 536 env.Depends(i_file, depends) 537 SwigSource('m5.internal', i_file) 538 539# Generate all enum header files 540for name,enum in sorted(all_enums.iteritems()): 541 py_source = PySource.modules[enum.__module__] 542 extra_deps = [ py_source.tnode ] 543 544 cc_file = File('enums/%s.cc' % name)
|
541 env.Command(cc_file, Value(name), createEnumStrings)
| 545 env.Command(cc_file, Value(name), 546 MakeAction(createEnumStrings, " [ENUM STR] $STRIP_TARGET"))
|
542 env.Depends(cc_file, depends + extra_deps) 543 Source(cc_file) 544 545 hh_file = File('enums/%s.hh' % name)
| 547 env.Depends(cc_file, depends + extra_deps) 548 Source(cc_file) 549 550 hh_file = File('enums/%s.hh' % name)
|
546 env.Command(hh_file, Value(name), createEnumParam)
| 551 env.Command(hh_file, Value(name), 552 MakeAction(createEnumParam, " [EN PARAM] $STRIP_TARGET"))
|
547 env.Depends(hh_file, depends + extra_deps) 548 549 i_file = File('python/m5/internal/enum_%s.i' % name)
| 553 env.Depends(hh_file, depends + extra_deps) 554 555 i_file = File('python/m5/internal/enum_%s.i' % name)
|
550 env.Command(i_file, Value(name), createEnumSwig)
| 556 env.Command(i_file, Value(name), 557 MakeAction(createEnumSwig, " [ENUMSWIG] $STRIP_TARGET"))
|
551 env.Depends(i_file, depends + extra_deps) 552 SwigSource('m5.internal', i_file) 553 554def buildParam(target, source, env): 555 name = source[0].get_contents() 556 obj = sim_objects[name] 557 class_path = obj.cxx_class.split('::') 558 classname = class_path[-1] 559 namespaces = class_path[:-1] 560 params = obj._params.local.values() 561 562 code = code_formatter() 563 564 code('%module(package="m5.internal") param_$name') 565 code() 566 code('%{') 567 code('#include "params/$obj.hh"') 568 for param in params: 569 param.cxx_predecls(code) 570 code('%}') 571 code() 572 573 for param in params: 574 param.swig_predecls(code) 575 576 code() 577 if obj._base: 578 code('%import "python/m5/internal/param_${{obj._base}}.i"') 579 code() 580 obj.swig_objdecls(code) 581 code() 582 583 code('%include "params/$obj.hh"') 584 585 code.write(target[0].abspath) 586 587for name in sim_objects.iterkeys(): 588 params_file = File('python/m5/internal/param_%s.i' % name)
| 558 env.Depends(i_file, depends + extra_deps) 559 SwigSource('m5.internal', i_file) 560 561def buildParam(target, source, env): 562 name = source[0].get_contents() 563 obj = sim_objects[name] 564 class_path = obj.cxx_class.split('::') 565 classname = class_path[-1] 566 namespaces = class_path[:-1] 567 params = obj._params.local.values() 568 569 code = code_formatter() 570 571 code('%module(package="m5.internal") param_$name') 572 code() 573 code('%{') 574 code('#include "params/$obj.hh"') 575 for param in params: 576 param.cxx_predecls(code) 577 code('%}') 578 code() 579 580 for param in params: 581 param.swig_predecls(code) 582 583 code() 584 if obj._base: 585 code('%import "python/m5/internal/param_${{obj._base}}.i"') 586 code() 587 obj.swig_objdecls(code) 588 code() 589 590 code('%include "params/$obj.hh"') 591 592 code.write(target[0].abspath) 593 594for name in sim_objects.iterkeys(): 595 params_file = File('python/m5/internal/param_%s.i' % name)
|
589 env.Command(params_file, Value(name), buildParam)
| 596 env.Command(params_file, Value(name), 597 MakeAction(buildParam, " [BLDPARAM] $STRIP_TARGET"))
|
590 env.Depends(params_file, depends) 591 SwigSource('m5.internal', params_file) 592 593# Generate the main swig init file 594def makeEmbeddedSwigInit(target, source, env): 595 code = code_formatter() 596 module = source[0].get_contents() 597 code('''\ 598#include "sim/init.hh" 599 600extern "C" { 601 void init_${module}(); 602} 603 604EmbeddedSwig embed_swig_${module}(init_${module}); 605''') 606 code.write(str(target[0])) 607 608# Build all swig modules 609for swig in SwigSource.all: 610 env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode,
| 598 env.Depends(params_file, depends) 599 SwigSource('m5.internal', params_file) 600 601# Generate the main swig init file 602def makeEmbeddedSwigInit(target, source, env): 603 code = code_formatter() 604 module = source[0].get_contents() 605 code('''\ 606#include "sim/init.hh" 607 608extern "C" { 609 void init_${module}(); 610} 611 612EmbeddedSwig embed_swig_${module}(init_${module}); 613''') 614 code.write(str(target[0])) 615 616# Build all swig modules 617for swig in SwigSource.all: 618 env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode,
|
611 '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 612 '-o ${TARGETS[0]} $SOURCES')
| 619 MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 620 '-o ${TARGETS[0]} $SOURCES', " [ SWIG] $STRIP_TARGET"))
|
613 init_file = 'python/swig/init_%s.cc' % swig.module
| 621 init_file = 'python/swig/init_%s.cc' % swig.module
|
614 env.Command(init_file, Value(swig.module), makeEmbeddedSwigInit)
| 622 env.Command(init_file, Value(swig.module), 623 MakeAction(makeEmbeddedSwigInit, " [EMBED SW] $STRIP_TARGET"))
|
615 Source(init_file) 616 env.Depends(swig.py_source.tnode, swig.tnode) 617 env.Depends(swig.cc_source.tnode, swig.tnode) 618 619def getFlags(source_flags): 620 flagsMap = {} 621 flagsList = [] 622 for s in source_flags: 623 val = eval(s.get_contents()) 624 name, compound, desc = val 625 flagsList.append(val) 626 flagsMap[name] = bool(compound) 627 628 for name, compound, desc in flagsList: 629 for flag in compound: 630 if flag not in flagsMap: 631 raise AttributeError, "Trace flag %s not found" % flag 632 if flagsMap[flag]: 633 raise AttributeError, \ 634 "Compound flag can't point to another compound flag" 635 636 flagsList.sort() 637 return flagsList 638 639 640# Generate traceflags.py 641def traceFlagsPy(target, source, env): 642 assert(len(target) == 1) 643 code = code_formatter() 644 645 allFlags = getFlags(source) 646 647 code('basic = [') 648 code.indent() 649 for flag, compound, desc in allFlags: 650 if not compound: 651 code("'$flag',") 652 code(']') 653 code.dedent() 654 code() 655 656 code('compound = [') 657 code.indent() 658 code("'All',") 659 for flag, compound, desc in allFlags: 660 if compound: 661 code("'$flag',") 662 code("]") 663 code.dedent() 664 code() 665 666 code("all = frozenset(basic + compound)") 667 code() 668 669 code('compoundMap = {') 670 code.indent() 671 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 672 code("'All' : $all,") 673 for flag, compound, desc in allFlags: 674 if compound: 675 code("'$flag' : $compound,") 676 code('}') 677 code.dedent() 678 code() 679 680 code('descriptions = {') 681 code.indent() 682 code("'All' : 'All flags',") 683 for flag, compound, desc in allFlags: 684 code("'$flag' : '$desc',") 685 code("}") 686 code.dedent() 687 688 code.write(str(target[0])) 689 690def traceFlagsCC(target, source, env): 691 assert(len(target) == 1) 692 693 allFlags = getFlags(source) 694 code = code_formatter() 695 696 # file header 697 code(''' 698/* 699 * DO NOT EDIT THIS FILE! Automatically generated 700 */ 701 702#include "base/traceflags.hh" 703 704using namespace Trace; 705 706const char *Trace::flagStrings[] = 707{''') 708 709 code.indent() 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 code('"$flag",') 715 716 code('"All",') 717 for flag, compound, desc in allFlags: 718 if compound: 719 code('"$flag",') 720 code.dedent() 721 722 code('''\ 723}; 724 725const int Trace::numFlagStrings = ${{len(allFlags) + 1}}; 726 727''') 728 729 # Now define the individual compound flag arrays. There is an array 730 # for each compound flag listing the component base flags. 731 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 732 code('static const Flags AllMap[] = {') 733 code.indent() 734 for flag, compound, desc in allFlags: 735 if not compound: 736 code('$flag,') 737 code.dedent() 738 code('};') 739 code() 740 741 for flag, compound, desc in allFlags: 742 if not compound: 743 continue 744 code('static const Flags ${flag}Map[] = {') 745 code.indent() 746 for flag in compound: 747 code('$flag,') 748 code('(Flags)-1') 749 code.dedent() 750 code('};') 751 code() 752 753 # Finally the compoundFlags[] array maps the compound flags 754 # to their individual arrays/ 755 code('const Flags *Trace::compoundFlags[] = {') 756 code.indent() 757 code('AllMap,') 758 for flag, compound, desc in allFlags: 759 if compound: 760 code('${flag}Map,') 761 # file trailer 762 code.dedent() 763 code('};') 764 765 code.write(str(target[0])) 766 767def traceFlagsHH(target, source, env): 768 assert(len(target) == 1) 769 770 allFlags = getFlags(source) 771 code = code_formatter() 772 773 # file header boilerplate 774 code('''\ 775/* 776 * DO NOT EDIT THIS FILE! 777 * 778 * Automatically generated from traceflags.py 779 */ 780 781#ifndef __BASE_TRACE_FLAGS_HH__ 782#define __BASE_TRACE_FLAGS_HH__ 783 784namespace Trace { 785 786enum Flags {''') 787 788 # Generate the enum. Base flags come first, then compound flags. 789 idx = 0 790 code.indent() 791 for flag, compound, desc in allFlags: 792 if not compound: 793 code('$flag = $idx,') 794 idx += 1 795 796 numBaseFlags = idx 797 code('NumFlags = $idx,') 798 code.dedent() 799 code() 800 801 # put a comment in here to separate base from compound flags 802 code(''' 803// The remaining enum values are *not* valid indices for Trace::flags. 804// They are "compound" flags, which correspond to sets of base 805// flags, and are used by changeFlag.''') 806 807 code.indent() 808 code('All = $idx,') 809 idx += 1 810 for flag, compound, desc in allFlags: 811 if compound: 812 code('$flag = $idx,') 813 idx += 1 814 815 numCompoundFlags = idx - numBaseFlags 816 code('NumCompoundFlags = $numCompoundFlags') 817 code.dedent() 818 819 # trailer boilerplate 820 code('''\ 821}; // enum Flags 822 823// Array of strings for SimpleEnumParam 824extern const char *flagStrings[]; 825extern const int numFlagStrings; 826 827// Array of arraay pointers: for each compound flag, gives the list of 828// base flags to set. Inidividual flag arrays are terminated by -1. 829extern const Flags *compoundFlags[]; 830 831/* namespace Trace */ } 832 833#endif // __BASE_TRACE_FLAGS_HH__ 834''') 835 836 code.write(str(target[0])) 837 838flags = map(Value, trace_flags.values())
| 624 Source(init_file) 625 env.Depends(swig.py_source.tnode, swig.tnode) 626 env.Depends(swig.cc_source.tnode, swig.tnode) 627 628def getFlags(source_flags): 629 flagsMap = {} 630 flagsList = [] 631 for s in source_flags: 632 val = eval(s.get_contents()) 633 name, compound, desc = val 634 flagsList.append(val) 635 flagsMap[name] = bool(compound) 636 637 for name, compound, desc in flagsList: 638 for flag in compound: 639 if flag not in flagsMap: 640 raise AttributeError, "Trace flag %s not found" % flag 641 if flagsMap[flag]: 642 raise AttributeError, \ 643 "Compound flag can't point to another compound flag" 644 645 flagsList.sort() 646 return flagsList 647 648 649# Generate traceflags.py 650def traceFlagsPy(target, source, env): 651 assert(len(target) == 1) 652 code = code_formatter() 653 654 allFlags = getFlags(source) 655 656 code('basic = [') 657 code.indent() 658 for flag, compound, desc in allFlags: 659 if not compound: 660 code("'$flag',") 661 code(']') 662 code.dedent() 663 code() 664 665 code('compound = [') 666 code.indent() 667 code("'All',") 668 for flag, compound, desc in allFlags: 669 if compound: 670 code("'$flag',") 671 code("]") 672 code.dedent() 673 code() 674 675 code("all = frozenset(basic + compound)") 676 code() 677 678 code('compoundMap = {') 679 code.indent() 680 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 681 code("'All' : $all,") 682 for flag, compound, desc in allFlags: 683 if compound: 684 code("'$flag' : $compound,") 685 code('}') 686 code.dedent() 687 code() 688 689 code('descriptions = {') 690 code.indent() 691 code("'All' : 'All flags',") 692 for flag, compound, desc in allFlags: 693 code("'$flag' : '$desc',") 694 code("}") 695 code.dedent() 696 697 code.write(str(target[0])) 698 699def traceFlagsCC(target, source, env): 700 assert(len(target) == 1) 701 702 allFlags = getFlags(source) 703 code = code_formatter() 704 705 # file header 706 code(''' 707/* 708 * DO NOT EDIT THIS FILE! Automatically generated 709 */ 710 711#include "base/traceflags.hh" 712 713using namespace Trace; 714 715const char *Trace::flagStrings[] = 716{''') 717 718 code.indent() 719 # The string array is used by SimpleEnumParam to map the strings 720 # provided by the user to enum values. 721 for flag, compound, desc in allFlags: 722 if not compound: 723 code('"$flag",') 724 725 code('"All",') 726 for flag, compound, desc in allFlags: 727 if compound: 728 code('"$flag",') 729 code.dedent() 730 731 code('''\ 732}; 733 734const int Trace::numFlagStrings = ${{len(allFlags) + 1}}; 735 736''') 737 738 # Now define the individual compound flag arrays. There is an array 739 # for each compound flag listing the component base flags. 740 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 741 code('static const Flags AllMap[] = {') 742 code.indent() 743 for flag, compound, desc in allFlags: 744 if not compound: 745 code('$flag,') 746 code.dedent() 747 code('};') 748 code() 749 750 for flag, compound, desc in allFlags: 751 if not compound: 752 continue 753 code('static const Flags ${flag}Map[] = {') 754 code.indent() 755 for flag in compound: 756 code('$flag,') 757 code('(Flags)-1') 758 code.dedent() 759 code('};') 760 code() 761 762 # Finally the compoundFlags[] array maps the compound flags 763 # to their individual arrays/ 764 code('const Flags *Trace::compoundFlags[] = {') 765 code.indent() 766 code('AllMap,') 767 for flag, compound, desc in allFlags: 768 if compound: 769 code('${flag}Map,') 770 # file trailer 771 code.dedent() 772 code('};') 773 774 code.write(str(target[0])) 775 776def traceFlagsHH(target, source, env): 777 assert(len(target) == 1) 778 779 allFlags = getFlags(source) 780 code = code_formatter() 781 782 # file header boilerplate 783 code('''\ 784/* 785 * DO NOT EDIT THIS FILE! 786 * 787 * Automatically generated from traceflags.py 788 */ 789 790#ifndef __BASE_TRACE_FLAGS_HH__ 791#define __BASE_TRACE_FLAGS_HH__ 792 793namespace Trace { 794 795enum Flags {''') 796 797 # Generate the enum. Base flags come first, then compound flags. 798 idx = 0 799 code.indent() 800 for flag, compound, desc in allFlags: 801 if not compound: 802 code('$flag = $idx,') 803 idx += 1 804 805 numBaseFlags = idx 806 code('NumFlags = $idx,') 807 code.dedent() 808 code() 809 810 # put a comment in here to separate base from compound flags 811 code(''' 812// The remaining enum values are *not* valid indices for Trace::flags. 813// They are "compound" flags, which correspond to sets of base 814// flags, and are used by changeFlag.''') 815 816 code.indent() 817 code('All = $idx,') 818 idx += 1 819 for flag, compound, desc in allFlags: 820 if compound: 821 code('$flag = $idx,') 822 idx += 1 823 824 numCompoundFlags = idx - numBaseFlags 825 code('NumCompoundFlags = $numCompoundFlags') 826 code.dedent() 827 828 # trailer boilerplate 829 code('''\ 830}; // enum Flags 831 832// Array of strings for SimpleEnumParam 833extern const char *flagStrings[]; 834extern const int numFlagStrings; 835 836// Array of arraay pointers: for each compound flag, gives the list of 837// base flags to set. Inidividual flag arrays are terminated by -1. 838extern const Flags *compoundFlags[]; 839 840/* namespace Trace */ } 841 842#endif // __BASE_TRACE_FLAGS_HH__ 843''') 844 845 code.write(str(target[0])) 846 847flags = map(Value, trace_flags.values())
|
839env.Command('base/traceflags.py', flags, traceFlagsPy)
| 848env.Command('base/traceflags.py', flags, 849 MakeAction(traceFlagsPy, " [ TRACING] $STRIP_TARGET"))
|
840PySource('m5', 'base/traceflags.py') 841
| 850PySource('m5', 'base/traceflags.py') 851
|
842env.Command('base/traceflags.hh', flags, traceFlagsHH) 843env.Command('base/traceflags.cc', flags, traceFlagsCC)
| 852env.Command('base/traceflags.hh', flags, 853 MakeAction(traceFlagsHH, " [ TRACING] $STRIP_TARGET")) 854env.Command('base/traceflags.cc', flags, 855 MakeAction(traceFlagsCC, " [ TRACING] $STRIP_TARGET"))
|
844Source('base/traceflags.cc') 845 846# Embed python files. All .py files that have been indicated by a 847# PySource() call in a SConscript need to be embedded into the M5 848# library. To do that, we compile the file to byte code, marshal the 849# byte code, compress it, and then generate a c++ file that 850# inserts the result into an array. 851def embedPyFile(target, source, env): 852 def c_str(string): 853 if string is None: 854 return "0" 855 return '"%s"' % string 856 857 '''Action function to compile a .py into a code object, marshal 858 it, compress it, and stick it into an asm file so the code appears 859 as just bytes with a label in the data section''' 860 861 src = file(str(source[0]), 'r').read() 862 863 pysource = PySource.tnodes[source[0]] 864 compiled = compile(src, pysource.abspath, 'exec') 865 marshalled = marshal.dumps(compiled) 866 compressed = zlib.compress(marshalled) 867 data = compressed 868 sym = pysource.symname 869 870 code = code_formatter() 871 code('''\ 872#include "sim/init.hh" 873 874namespace { 875 876const char data_${sym}[] = { 877''') 878 code.indent() 879 step = 16 880 for i in xrange(0, len(data), step): 881 x = array.array('B', data[i:i+step]) 882 code(''.join('%d,' % d for d in x)) 883 code.dedent() 884 885 code('''}; 886 887EmbeddedPython embedded_${sym}( 888 ${{c_str(pysource.arcname)}}, 889 ${{c_str(pysource.abspath)}}, 890 ${{c_str(pysource.modpath)}}, 891 data_${sym}, 892 ${{len(data)}}, 893 ${{len(marshalled)}}); 894 895/* namespace */ } 896''') 897 code.write(str(target[0])) 898 899for source in PySource.all:
| 856Source('base/traceflags.cc') 857 858# Embed python files. All .py files that have been indicated by a 859# PySource() call in a SConscript need to be embedded into the M5 860# library. To do that, we compile the file to byte code, marshal the 861# byte code, compress it, and then generate a c++ file that 862# inserts the result into an array. 863def embedPyFile(target, source, env): 864 def c_str(string): 865 if string is None: 866 return "0" 867 return '"%s"' % string 868 869 '''Action function to compile a .py into a code object, marshal 870 it, compress it, and stick it into an asm file so the code appears 871 as just bytes with a label in the data section''' 872 873 src = file(str(source[0]), 'r').read() 874 875 pysource = PySource.tnodes[source[0]] 876 compiled = compile(src, pysource.abspath, 'exec') 877 marshalled = marshal.dumps(compiled) 878 compressed = zlib.compress(marshalled) 879 data = compressed 880 sym = pysource.symname 881 882 code = code_formatter() 883 code('''\ 884#include "sim/init.hh" 885 886namespace { 887 888const char data_${sym}[] = { 889''') 890 code.indent() 891 step = 16 892 for i in xrange(0, len(data), step): 893 x = array.array('B', data[i:i+step]) 894 code(''.join('%d,' % d for d in x)) 895 code.dedent() 896 897 code('''}; 898 899EmbeddedPython embedded_${sym}( 900 ${{c_str(pysource.arcname)}}, 901 ${{c_str(pysource.abspath)}}, 902 ${{c_str(pysource.modpath)}}, 903 data_${sym}, 904 ${{len(data)}}, 905 ${{len(marshalled)}}); 906 907/* namespace */ } 908''') 909 code.write(str(target[0])) 910 911for source in PySource.all:
|
900 env.Command(source.cpp, source.tnode, embedPyFile)
| 912 env.Command(source.cpp, source.tnode, 913 MakeAction(embedPyFile, " [EMBED PY] $STRIP_TARGET"))
|
901 Source(source.cpp) 902 903######################################################################## 904# 905# Define binaries. Each different build type (debug, opt, etc.) gets 906# a slightly different build environment. 907# 908 909# List of constructed environments to pass back to SConstruct 910envList = [] 911 912date_source = Source('base/date.cc', skip_lib=True) 913 914# Function to create a new build environment as clone of current 915# environment 'env' with modified object suffix and optional stripped 916# binary. Additional keyword arguments are appended to corresponding 917# build environment vars. 918def makeEnv(label, objsfx, strip = False, **kwargs): 919 # SCons doesn't know to append a library suffix when there is a '.' in the 920 # name. Use '_' instead. 921 libname = 'm5_' + label 922 exename = 'm5.' + label 923 924 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 925 new_env.Label = label 926 new_env.Append(**kwargs) 927 928 swig_env = new_env.Clone() 929 swig_env.Append(CCFLAGS='-Werror') 930 if env['GCC']: 931 swig_env.Append(CCFLAGS='-Wno-uninitialized') 932 swig_env.Append(CCFLAGS='-Wno-sign-compare') 933 swig_env.Append(CCFLAGS='-Wno-parentheses') 934 935 werror_env = new_env.Clone() 936 werror_env.Append(CCFLAGS='-Werror') 937 938 def make_obj(source, static, extra_deps = None): 939 '''This function adds the specified source to the correct 940 build environment, and returns the corresponding SCons Object 941 nodes''' 942 943 if source.swig: 944 env = swig_env 945 elif source.Werror: 946 env = werror_env 947 else: 948 env = new_env 949 950 if static: 951 obj = env.StaticObject(source.tnode) 952 else: 953 obj = env.SharedObject(source.tnode) 954 955 if extra_deps: 956 env.Depends(obj, extra_deps) 957 958 return obj 959 960 static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)] 961 shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)] 962 963 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 964 static_objs.append(static_date) 965 966 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 967 shared_objs.append(shared_date) 968 969 # First make a library of everything but main() so other programs can 970 # link against m5. 971 static_lib = new_env.StaticLibrary(libname, static_objs) 972 shared_lib = new_env.SharedLibrary(libname, shared_objs) 973 974 for target, sources in unit_tests: 975 objs = [ make_obj(s, static=True) for s in sources ] 976 new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs) 977 978 # Now link a stub with main() and the static library. 979 bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ] 980 progname = exename 981 if strip: 982 progname += '.unstripped' 983 984 targets = new_env.Program(progname, bin_objs + static_objs) 985 986 if strip: 987 if sys.platform == 'sunos5': 988 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 989 else: 990 cmd = 'strip $SOURCE -o $TARGET'
| 914 Source(source.cpp) 915 916######################################################################## 917# 918# Define binaries. Each different build type (debug, opt, etc.) gets 919# a slightly different build environment. 920# 921 922# List of constructed environments to pass back to SConstruct 923envList = [] 924 925date_source = Source('base/date.cc', skip_lib=True) 926 927# Function to create a new build environment as clone of current 928# environment 'env' with modified object suffix and optional stripped 929# binary. Additional keyword arguments are appended to corresponding 930# build environment vars. 931def makeEnv(label, objsfx, strip = False, **kwargs): 932 # SCons doesn't know to append a library suffix when there is a '.' in the 933 # name. Use '_' instead. 934 libname = 'm5_' + label 935 exename = 'm5.' + label 936 937 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 938 new_env.Label = label 939 new_env.Append(**kwargs) 940 941 swig_env = new_env.Clone() 942 swig_env.Append(CCFLAGS='-Werror') 943 if env['GCC']: 944 swig_env.Append(CCFLAGS='-Wno-uninitialized') 945 swig_env.Append(CCFLAGS='-Wno-sign-compare') 946 swig_env.Append(CCFLAGS='-Wno-parentheses') 947 948 werror_env = new_env.Clone() 949 werror_env.Append(CCFLAGS='-Werror') 950 951 def make_obj(source, static, extra_deps = None): 952 '''This function adds the specified source to the correct 953 build environment, and returns the corresponding SCons Object 954 nodes''' 955 956 if source.swig: 957 env = swig_env 958 elif source.Werror: 959 env = werror_env 960 else: 961 env = new_env 962 963 if static: 964 obj = env.StaticObject(source.tnode) 965 else: 966 obj = env.SharedObject(source.tnode) 967 968 if extra_deps: 969 env.Depends(obj, extra_deps) 970 971 return obj 972 973 static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)] 974 shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)] 975 976 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 977 static_objs.append(static_date) 978 979 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 980 shared_objs.append(shared_date) 981 982 # First make a library of everything but main() so other programs can 983 # link against m5. 984 static_lib = new_env.StaticLibrary(libname, static_objs) 985 shared_lib = new_env.SharedLibrary(libname, shared_objs) 986 987 for target, sources in unit_tests: 988 objs = [ make_obj(s, static=True) for s in sources ] 989 new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs) 990 991 # Now link a stub with main() and the static library. 992 bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ] 993 progname = exename 994 if strip: 995 progname += '.unstripped' 996 997 targets = new_env.Program(progname, bin_objs + static_objs) 998 999 if strip: 1000 if sys.platform == 'sunos5': 1001 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1002 else: 1003 cmd = 'strip $SOURCE -o $TARGET'
|
991 targets = new_env.Command(exename, progname, cmd)
| 1004 targets = new_env.Command(exename, progname, 1005 MakeAction(cmd, " [ STRIP] $STRIP_TARGET"))
|
992 993 new_env.M5Binary = targets[0] 994 envList.append(new_env) 995 996# Debug binary 997ccflags = {} 998if env['GCC']: 999 if sys.platform == 'sunos5': 1000 ccflags['debug'] = '-gstabs+' 1001 else: 1002 ccflags['debug'] = '-ggdb3' 1003 ccflags['opt'] = '-g -O3' 1004 ccflags['fast'] = '-O3' 1005 ccflags['prof'] = '-O3 -g -pg' 1006elif env['SUNCC']: 1007 ccflags['debug'] = '-g0' 1008 ccflags['opt'] = '-g -O' 1009 ccflags['fast'] = '-fast' 1010 ccflags['prof'] = '-fast -g -pg' 1011elif env['ICC']: 1012 ccflags['debug'] = '-g -O0' 1013 ccflags['opt'] = '-g -O' 1014 ccflags['fast'] = '-fast' 1015 ccflags['prof'] = '-fast -g -pg' 1016else: 1017 print 'Unknown compiler, please fix compiler options' 1018 Exit(1) 1019 1020makeEnv('debug', '.do', 1021 CCFLAGS = Split(ccflags['debug']), 1022 CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 1023 1024# Optimized binary 1025makeEnv('opt', '.o', 1026 CCFLAGS = Split(ccflags['opt']), 1027 CPPDEFINES = ['TRACING_ON=1']) 1028 1029# "Fast" binary 1030makeEnv('fast', '.fo', strip = True, 1031 CCFLAGS = Split(ccflags['fast']), 1032 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 1033 1034# Profiled binary 1035makeEnv('prof', '.po', 1036 CCFLAGS = Split(ccflags['prof']), 1037 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1038 LINKFLAGS = '-pg') 1039 1040Return('envList')
| 1006 1007 new_env.M5Binary = targets[0] 1008 envList.append(new_env) 1009 1010# Debug binary 1011ccflags = {} 1012if env['GCC']: 1013 if sys.platform == 'sunos5': 1014 ccflags['debug'] = '-gstabs+' 1015 else: 1016 ccflags['debug'] = '-ggdb3' 1017 ccflags['opt'] = '-g -O3' 1018 ccflags['fast'] = '-O3' 1019 ccflags['prof'] = '-O3 -g -pg' 1020elif env['SUNCC']: 1021 ccflags['debug'] = '-g0' 1022 ccflags['opt'] = '-g -O' 1023 ccflags['fast'] = '-fast' 1024 ccflags['prof'] = '-fast -g -pg' 1025elif env['ICC']: 1026 ccflags['debug'] = '-g -O0' 1027 ccflags['opt'] = '-g -O' 1028 ccflags['fast'] = '-fast' 1029 ccflags['prof'] = '-fast -g -pg' 1030else: 1031 print 'Unknown compiler, please fix compiler options' 1032 Exit(1) 1033 1034makeEnv('debug', '.do', 1035 CCFLAGS = Split(ccflags['debug']), 1036 CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 1037 1038# Optimized binary 1039makeEnv('opt', '.o', 1040 CCFLAGS = Split(ccflags['opt']), 1041 CPPDEFINES = ['TRACING_ON=1']) 1042 1043# "Fast" binary 1044makeEnv('fast', '.fo', strip = True, 1045 CCFLAGS = Split(ccflags['fast']), 1046 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 1047 1048# Profiled binary 1049makeEnv('prof', '.po', 1050 CCFLAGS = Split(ccflags['prof']), 1051 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1052 LINKFLAGS = '-pg') 1053 1054Return('envList')
|