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 imp 33import marshal 34import os 35import re 36import sys 37import zlib 38 39from os.path import basename, dirname, exists, isdir, isfile, join as joinpath 40 41import SCons 42 43# This file defines how to build a particular configuration of M5 44# based on variable settings in the 'env' build environment. 45 46Import('*') 47 48# Children need to see the environment 49Export('env') 50 51build_env = dict([(opt, env[opt]) for opt in env.ExportOptions]) 52 53def sort_list(_list): 54 """return a sorted copy of '_list'""" 55 if isinstance(_list, list): 56 _list = _list[:] 57 else: 58 _list = list(_list) 59 _list.sort() 60 return _list 61 62class PySourceFile(object): 63 invalid_sym_char = re.compile('[^A-z0-9_]') 64 def __init__(self, package, tnode): 65 snode = tnode.srcnode() 66 filename = str(tnode) 67 pyname = basename(filename) 68 assert pyname.endswith('.py') 69 name = pyname[:-3] 70 if package: 71 path = package.split('.') 72 else: 73 path = [] 74 75 modpath = path[:] 76 if name != '__init__': 77 modpath += [name] 78 modpath = '.'.join(modpath) 79 80 arcpath = path + [ pyname ] 81 arcname = joinpath(*arcpath) 82 83 debugname = snode.abspath 84 if not exists(debugname): 85 debugname = tnode.abspath 86 87 self.tnode = tnode 88 self.snode = snode 89 self.pyname = pyname 90 self.package = package 91 self.modpath = modpath 92 self.arcname = arcname 93 self.debugname = debugname 94 self.compiled = File(filename + 'c') 95 self.assembly = File(filename + '.s') 96 self.symname = "PyEMB_" + self.invalid_sym_char.sub('_', modpath) 97 98 99######################################################################## 100# Code for adding source files of various types 101# 102cc_lib_sources = [] 103def Source(source): 104 '''Add a source file to the libm5 build''' 105 if not isinstance(source, SCons.Node.FS.File): 106 source = File(source) 107 108 cc_lib_sources.append(source) 109 110cc_bin_sources = [] 111def BinSource(source): 112 '''Add a source file to the m5 binary build''' 113 if not isinstance(source, SCons.Node.FS.File): 114 source = File(source) 115 116 cc_bin_sources.append(source) 117 118py_sources = [] 119def PySource(package, source): 120 '''Add a python source file to the named package''' 121 if not isinstance(source, SCons.Node.FS.File): 122 source = File(source) 123 124 source = PySourceFile(package, source) 125 py_sources.append(source) 126 127sim_objects_fixed = False 128sim_object_modfiles = set() 129def SimObject(source): 130 '''Add a SimObject python file as a python source object and add 131 it to a list of sim object modules''' 132 133 if sim_objects_fixed: 134 raise AttributeError, "Too late to call SimObject now." 135 136 if not isinstance(source, SCons.Node.FS.File): 137 source = File(source) 138 139 PySource('m5.objects', source) 140 modfile = basename(str(source)) 141 assert modfile.endswith('.py') 142 modname = modfile[:-3] 143 sim_object_modfiles.add(modname) 144 145swig_sources = [] 146def SwigSource(package, source): 147 '''Add a swig file to build''' 148 if not isinstance(source, SCons.Node.FS.File): 149 source = File(source) 150 val = source,package 151 swig_sources.append(val) 152 153unit_tests = [] 154def UnitTest(target, sources): 155 if not isinstance(sources, (list, tuple)): 156 sources = [ sources ] 157 158 srcs = [] 159 for source in sources: 160 if not isinstance(source, SCons.Node.FS.File): 161 source = File(source) 162 srcs.append(source) 163 164 unit_tests.append((target, srcs)) 165 166# Children should have access 167Export('Source') 168Export('BinSource') 169Export('PySource') 170Export('SimObject') 171Export('SwigSource') 172Export('UnitTest') 173 174######################################################################## 175# 176# Trace Flags 177#
| 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 imp 33import marshal 34import os 35import re 36import sys 37import zlib 38 39from os.path import basename, dirname, exists, isdir, isfile, join as joinpath 40 41import SCons 42 43# This file defines how to build a particular configuration of M5 44# based on variable settings in the 'env' build environment. 45 46Import('*') 47 48# Children need to see the environment 49Export('env') 50 51build_env = dict([(opt, env[opt]) for opt in env.ExportOptions]) 52 53def sort_list(_list): 54 """return a sorted copy of '_list'""" 55 if isinstance(_list, list): 56 _list = _list[:] 57 else: 58 _list = list(_list) 59 _list.sort() 60 return _list 61 62class PySourceFile(object): 63 invalid_sym_char = re.compile('[^A-z0-9_]') 64 def __init__(self, package, tnode): 65 snode = tnode.srcnode() 66 filename = str(tnode) 67 pyname = basename(filename) 68 assert pyname.endswith('.py') 69 name = pyname[:-3] 70 if package: 71 path = package.split('.') 72 else: 73 path = [] 74 75 modpath = path[:] 76 if name != '__init__': 77 modpath += [name] 78 modpath = '.'.join(modpath) 79 80 arcpath = path + [ pyname ] 81 arcname = joinpath(*arcpath) 82 83 debugname = snode.abspath 84 if not exists(debugname): 85 debugname = tnode.abspath 86 87 self.tnode = tnode 88 self.snode = snode 89 self.pyname = pyname 90 self.package = package 91 self.modpath = modpath 92 self.arcname = arcname 93 self.debugname = debugname 94 self.compiled = File(filename + 'c') 95 self.assembly = File(filename + '.s') 96 self.symname = "PyEMB_" + self.invalid_sym_char.sub('_', modpath) 97 98 99######################################################################## 100# Code for adding source files of various types 101# 102cc_lib_sources = [] 103def Source(source): 104 '''Add a source file to the libm5 build''' 105 if not isinstance(source, SCons.Node.FS.File): 106 source = File(source) 107 108 cc_lib_sources.append(source) 109 110cc_bin_sources = [] 111def BinSource(source): 112 '''Add a source file to the m5 binary build''' 113 if not isinstance(source, SCons.Node.FS.File): 114 source = File(source) 115 116 cc_bin_sources.append(source) 117 118py_sources = [] 119def PySource(package, source): 120 '''Add a python source file to the named package''' 121 if not isinstance(source, SCons.Node.FS.File): 122 source = File(source) 123 124 source = PySourceFile(package, source) 125 py_sources.append(source) 126 127sim_objects_fixed = False 128sim_object_modfiles = set() 129def SimObject(source): 130 '''Add a SimObject python file as a python source object and add 131 it to a list of sim object modules''' 132 133 if sim_objects_fixed: 134 raise AttributeError, "Too late to call SimObject now." 135 136 if not isinstance(source, SCons.Node.FS.File): 137 source = File(source) 138 139 PySource('m5.objects', source) 140 modfile = basename(str(source)) 141 assert modfile.endswith('.py') 142 modname = modfile[:-3] 143 sim_object_modfiles.add(modname) 144 145swig_sources = [] 146def SwigSource(package, source): 147 '''Add a swig file to build''' 148 if not isinstance(source, SCons.Node.FS.File): 149 source = File(source) 150 val = source,package 151 swig_sources.append(val) 152 153unit_tests = [] 154def UnitTest(target, sources): 155 if not isinstance(sources, (list, tuple)): 156 sources = [ sources ] 157 158 srcs = [] 159 for source in sources: 160 if not isinstance(source, SCons.Node.FS.File): 161 source = File(source) 162 srcs.append(source) 163 164 unit_tests.append((target, srcs)) 165 166# Children should have access 167Export('Source') 168Export('BinSource') 169Export('PySource') 170Export('SimObject') 171Export('SwigSource') 172Export('UnitTest') 173 174######################################################################## 175# 176# Trace Flags 177#
|
178all_flags = {} 179trace_flags = [] 180def TraceFlag(name, desc=''): 181 if name in all_flags:
| 178trace_flags = {} 179def TraceFlag(name, desc=None): 180 if name in trace_flags:
|
182 raise AttributeError, "Flag %s already specified" % name
| 181 raise AttributeError, "Flag %s already specified" % name
|
183 flag = (name, (), desc) 184 trace_flags.append(flag) 185 all_flags[name] = ()
| 182 trace_flags[name] = (name, (), desc)
|
186
| 183
|
187def CompoundFlag(name, flags, desc=''): 188 if name in all_flags:
| 184def CompoundFlag(name, flags, desc=None): 185 if name in trace_flags:
|
189 raise AttributeError, "Flag %s already specified" % name 190 191 compound = tuple(flags) 192 for flag in compound:
| 186 raise AttributeError, "Flag %s already specified" % name 187 188 compound = tuple(flags) 189 for flag in compound:
|
193 if flag not in all_flags:
| 190 if flag not in trace_flags:
|
194 raise AttributeError, "Trace flag %s not found" % flag
| 191 raise AttributeError, "Trace flag %s not found" % flag
|
195 if all_flags[flag]:
| 192 if trace_flags[flag][1]:
|
196 raise AttributeError, \ 197 "Compound flag can't point to another compound flag" 198
| 193 raise AttributeError, \ 194 "Compound flag can't point to another compound flag" 195
|
199 flag = (name, compound, desc) 200 trace_flags.append(flag) 201 all_flags[name] = compound
| 196 trace_flags[name] = (name, compound, desc)
|
202 203Export('TraceFlag') 204Export('CompoundFlag') 205 206######################################################################## 207# 208# Set some compiler variables 209# 210 211# Include file paths are rooted in this directory. SCons will 212# automatically expand '.' to refer to both the source directory and 213# the corresponding build directory to pick up generated include 214# files. 215env.Append(CPPPATH=Dir('.')) 216 217for extra_dir in extras_dir_list: 218 env.Append(CPPPATH=Dir(extra_dir)) 219 220# Add a flag defining what THE_ISA should be for all compilation 221env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) 222 223# Workaround for bug in SCons version > 0.97d20071212 224# Scons bug id: 2006 M5 Bug id: 308 225for root, dirs, files in os.walk(base_dir, topdown=True): 226 Dir(root[len(base_dir) + 1:]) 227 228######################################################################## 229# 230# Walk the tree and execute all SConscripts in subdirectories 231# 232 233here = Dir('.').srcnode().abspath 234for root, dirs, files in os.walk(base_dir, topdown=True): 235 if root == here: 236 # we don't want to recurse back into this SConscript 237 continue 238 239 if 'SConscript' in files: 240 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 241 SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) 242 243for extra_dir in extras_dir_list: 244 prefix_len = len(dirname(extra_dir)) + 1 245 for root, dirs, files in os.walk(extra_dir, topdown=True): 246 if 'SConscript' in files: 247 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 248 SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) 249 250for opt in env.ExportOptions: 251 env.ConfigFile(opt) 252 253######################################################################## 254# 255# Prevent any SimObjects from being added after this point, they 256# should all have been added in the SConscripts above 257# 258class DictImporter(object): 259 '''This importer takes a dictionary of arbitrary module names that 260 map to arbitrary filenames.''' 261 def __init__(self, modules): 262 self.modules = modules 263 self.installed = set() 264 265 def __del__(self): 266 self.unload() 267 268 def unload(self): 269 import sys 270 for module in self.installed: 271 del sys.modules[module] 272 self.installed = set() 273 274 def find_module(self, fullname, path): 275 if fullname == 'defines': 276 return self 277 278 if fullname == 'm5.objects': 279 return self 280 281 if fullname.startswith('m5.internal'): 282 return None 283 284 if fullname in self.modules and exists(self.modules[fullname]): 285 return self 286 287 return None 288 289 def load_module(self, fullname): 290 mod = imp.new_module(fullname) 291 sys.modules[fullname] = mod 292 self.installed.add(fullname) 293 294 mod.__loader__ = self 295 if fullname == 'm5.objects': 296 mod.__path__ = fullname.split('.') 297 return mod 298 299 if fullname == 'defines': 300 mod.__dict__['buildEnv'] = build_env 301 return mod 302 303 srcfile = self.modules[fullname] 304 if basename(srcfile) == '__init__.py': 305 mod.__path__ = fullname.split('.') 306 mod.__file__ = srcfile 307 308 exec file(srcfile, 'r') in mod.__dict__ 309 310 return mod 311 312py_modules = {} 313for source in py_sources: 314 py_modules[source.modpath] = source.snode.abspath 315 316# install the python importer so we can grab stuff from the source 317# tree itself. We can't have SimObjects added after this point or 318# else we won't know about them for the rest of the stuff. 319sim_objects_fixed = True 320importer = DictImporter(py_modules) 321sys.meta_path[0:0] = [ importer ] 322 323import m5 324 325# import all sim objects so we can populate the all_objects list 326# make sure that we're working with a list, then let's sort it 327sim_objects = list(sim_object_modfiles) 328sim_objects.sort() 329for simobj in sim_objects: 330 exec('from m5.objects import %s' % simobj) 331 332# we need to unload all of the currently imported modules so that they 333# will be re-imported the next time the sconscript is run 334importer.unload() 335sys.meta_path.remove(importer) 336 337sim_objects = m5.SimObject.allClasses 338all_enums = m5.params.allEnums 339 340all_params = {} 341for name,obj in sim_objects.iteritems(): 342 for param in obj._params.local.values(): 343 if not hasattr(param, 'swig_decl'): 344 continue 345 pname = param.ptype_str 346 if pname not in all_params: 347 all_params[pname] = param 348 349######################################################################## 350# 351# calculate extra dependencies 352# 353module_depends = ["m5", "m5.SimObject", "m5.params"] 354depends = [ File(py_modules[dep]) for dep in module_depends ] 355 356######################################################################## 357# 358# Commands for the basic automatically generated python files 359# 360 361scons_dir = str(SCons.Node.FS.default_fs.SConstruct_dir) 362 363hg_info = ("Unknown", "Unknown", "Unknown") 364hg_demandimport = False 365try: 366 if not exists(scons_dir) or not isdir(scons_dir) or \ 367 not exists(joinpath(scons_dir, ".hg")): 368 raise ValueError(".hg directory not found") 369 370 import mercurial.demandimport, mercurial.hg, mercurial.ui 371 import mercurial.util, mercurial.node 372 hg_demandimport = True 373 374 repo = mercurial.hg.repository(mercurial.ui.ui(), scons_dir) 375 rev = mercurial.node.nullrev + repo.changelog.count() 376 changenode = repo.changelog.node(rev) 377 changes = repo.changelog.read(changenode) 378 id = mercurial.node.hex(changenode) 379 date = mercurial.util.datestr(changes[2]) 380 381 hg_info = (rev, id, date) 382except ImportError, e: 383 print "Mercurial not found" 384except ValueError, e: 385 print e 386except Exception, e: 387 print "Other mercurial exception: %s" % e 388 389if hg_demandimport: 390 mercurial.demandimport.disable() 391 392# Generate Python file containing a dict specifying the current 393# build_env flags. 394def makeDefinesPyFile(target, source, env): 395 f = file(str(target[0]), 'w') 396 build_env, hg_info = [ x.get_contents() for x in source ] 397 print >>f, "buildEnv = %s" % build_env 398 print >>f, "hgRev, hgId, hgDate = %s" % hg_info 399 f.close() 400 401defines_info = [ Value(build_env), Value(hg_info) ] 402# Generate a file with all of the compile options in it 403env.Command('python/m5/defines.py', defines_info, makeDefinesPyFile) 404PySource('m5', 'python/m5/defines.py') 405 406# Generate python file containing info about the M5 source code 407def makeInfoPyFile(target, source, env): 408 f = file(str(target[0]), 'w') 409 for src in source: 410 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 411 print >>f, "%s = %s" % (src, repr(data)) 412 f.close() 413 414# Generate a file that wraps the basic top level files 415env.Command('python/m5/info.py', 416 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ], 417 makeInfoPyFile) 418PySource('m5', 'python/m5/info.py') 419 420# Generate the __init__.py file for m5.objects 421def makeObjectsInitFile(target, source, env): 422 f = file(str(target[0]), 'w') 423 print >>f, 'from params import *' 424 print >>f, 'from m5.SimObject import *' 425 for module in source: 426 print >>f, 'from %s import *' % module.get_contents() 427 f.close() 428 429# Generate an __init__.py file for the objects package 430env.Command('python/m5/objects/__init__.py', 431 [ Value(o) for o in sort_list(sim_object_modfiles) ], 432 makeObjectsInitFile) 433PySource('m5.objects', 'python/m5/objects/__init__.py') 434 435######################################################################## 436# 437# Create all of the SimObject param headers and enum headers 438# 439 440def createSimObjectParam(target, source, env): 441 assert len(target) == 1 and len(source) == 1 442 443 hh_file = file(target[0].abspath, 'w') 444 name = str(source[0].get_contents()) 445 obj = sim_objects[name] 446 447 print >>hh_file, obj.cxx_decl() 448 449def createSwigParam(target, source, env): 450 assert len(target) == 1 and len(source) == 1 451 452 i_file = file(target[0].abspath, 'w') 453 name = str(source[0].get_contents()) 454 param = all_params[name] 455 456 for line in param.swig_decl(): 457 print >>i_file, line 458 459def createEnumStrings(target, source, env): 460 assert len(target) == 1 and len(source) == 1 461 462 cc_file = file(target[0].abspath, 'w') 463 name = str(source[0].get_contents()) 464 obj = all_enums[name] 465 466 print >>cc_file, obj.cxx_def() 467 cc_file.close() 468 469def createEnumParam(target, source, env): 470 assert len(target) == 1 and len(source) == 1 471 472 hh_file = file(target[0].abspath, 'w') 473 name = str(source[0].get_contents()) 474 obj = all_enums[name] 475 476 print >>hh_file, obj.cxx_decl() 477 478# Generate all of the SimObject param struct header files 479params_hh_files = [] 480for name,simobj in sim_objects.iteritems(): 481 extra_deps = [ File(py_modules[simobj.__module__]) ] 482 483 hh_file = File('params/%s.hh' % name) 484 params_hh_files.append(hh_file) 485 env.Command(hh_file, Value(name), createSimObjectParam) 486 env.Depends(hh_file, depends + extra_deps) 487 488# Generate any parameter header files needed 489params_i_files = [] 490for name,param in all_params.iteritems(): 491 if isinstance(param, m5.params.VectorParamDesc): 492 ext = 'vptype' 493 else: 494 ext = 'ptype' 495 496 i_file = File('params/%s_%s.i' % (name, ext)) 497 params_i_files.append(i_file) 498 env.Command(i_file, Value(name), createSwigParam) 499 env.Depends(i_file, depends) 500 501# Generate all enum header files 502for name,enum in all_enums.iteritems(): 503 extra_deps = [ File(py_modules[enum.__module__]) ] 504 505 cc_file = File('enums/%s.cc' % name) 506 env.Command(cc_file, Value(name), createEnumStrings) 507 env.Depends(cc_file, depends + extra_deps) 508 Source(cc_file) 509 510 hh_file = File('enums/%s.hh' % name) 511 env.Command(hh_file, Value(name), createEnumParam) 512 env.Depends(hh_file, depends + extra_deps) 513 514# Build the big monolithic swigged params module (wraps all SimObject 515# param structs and enum structs) 516def buildParams(target, source, env): 517 names = [ s.get_contents() for s in source ] 518 objs = [ sim_objects[name] for name in names ] 519 out = file(target[0].abspath, 'w') 520 521 ordered_objs = [] 522 obj_seen = set() 523 def order_obj(obj): 524 name = str(obj) 525 if name in obj_seen: 526 return 527 528 obj_seen.add(name) 529 if str(obj) != 'SimObject': 530 order_obj(obj.__bases__[0]) 531 532 ordered_objs.append(obj) 533 534 for obj in objs: 535 order_obj(obj) 536 537 enums = set() 538 predecls = [] 539 pd_seen = set() 540 541 def add_pds(*pds): 542 for pd in pds: 543 if pd not in pd_seen: 544 predecls.append(pd) 545 pd_seen.add(pd) 546 547 for obj in ordered_objs: 548 params = obj._params.local.values() 549 for param in params: 550 ptype = param.ptype 551 if issubclass(ptype, m5.params.Enum): 552 if ptype not in enums: 553 enums.add(ptype) 554 pds = param.swig_predecls() 555 if isinstance(pds, (list, tuple)): 556 add_pds(*pds) 557 else: 558 add_pds(pds) 559 560 print >>out, '%module params' 561 562 print >>out, '%{' 563 for obj in ordered_objs: 564 print >>out, '#include "params/%s.hh"' % obj 565 print >>out, '%}' 566 567 for pd in predecls: 568 print >>out, pd 569 570 enums = list(enums) 571 enums.sort() 572 for enum in enums: 573 print >>out, '%%include "enums/%s.hh"' % enum.__name__ 574 print >>out 575 576 for obj in ordered_objs: 577 if obj.swig_objdecls: 578 for decl in obj.swig_objdecls: 579 print >>out, decl 580 continue 581 582 class_path = obj.cxx_class.split('::') 583 classname = class_path[-1] 584 namespaces = class_path[:-1] 585 namespaces.reverse() 586 587 code = '' 588 589 if namespaces: 590 code += '// avoid name conflicts\n' 591 sep_string = '_COLONS_' 592 flat_name = sep_string.join(class_path) 593 code += '%%rename(%s) %s;\n' % (flat_name, classname) 594 595 code += '// stop swig from creating/wrapping default ctor/dtor\n' 596 code += '%%nodefault %s;\n' % classname 597 code += 'class %s ' % classname 598 if obj._base: 599 code += ': public %s' % obj._base.cxx_class 600 code += ' {};\n' 601 602 for ns in namespaces: 603 new_code = 'namespace %s {\n' % ns 604 new_code += code 605 new_code += '}\n' 606 code = new_code 607 608 print >>out, code 609 610 print >>out, '%%include "src/sim/sim_object_params.hh"' % obj 611 for obj in ordered_objs: 612 print >>out, '%%include "params/%s.hh"' % obj 613 614params_file = File('params/params.i') 615names = sort_list(sim_objects.keys()) 616env.Command(params_file, [ Value(v) for v in names ], buildParams) 617env.Depends(params_file, params_hh_files + params_i_files + depends) 618SwigSource('m5.objects', params_file) 619 620# Build all swig modules 621swig_modules = [] 622cc_swig_sources = [] 623for source,package in swig_sources: 624 filename = str(source) 625 assert filename.endswith('.i') 626 627 base = '.'.join(filename.split('.')[:-1]) 628 module = basename(base) 629 cc_file = base + '_wrap.cc' 630 py_file = base + '.py' 631 632 env.Command([cc_file, py_file], source, 633 '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 634 '-o ${TARGETS[0]} $SOURCES') 635 env.Depends(py_file, source) 636 env.Depends(cc_file, source) 637 638 swig_modules.append(Value(module)) 639 cc_swig_sources.append(File(cc_file)) 640 PySource(package, py_file) 641 642# Generate the main swig init file 643def makeSwigInit(target, source, env): 644 f = file(str(target[0]), 'w') 645 print >>f, 'extern "C" {' 646 for module in source: 647 print >>f, ' void init_%s();' % module.get_contents() 648 print >>f, '}' 649 print >>f, 'void initSwig() {' 650 for module in source: 651 print >>f, ' init_%s();' % module.get_contents() 652 print >>f, '}' 653 f.close() 654 655env.Command('python/swig/init.cc', swig_modules, makeSwigInit) 656Source('python/swig/init.cc') 657 658# Generate traceflags.py 659def traceFlagsPy(target, source, env): 660 assert(len(target) == 1) 661 662 f = file(str(target[0]), 'w') 663 664 allFlags = [] 665 for s in source: 666 val = eval(s.get_contents()) 667 allFlags.append(val) 668
| 197 198Export('TraceFlag') 199Export('CompoundFlag') 200 201######################################################################## 202# 203# Set some compiler variables 204# 205 206# Include file paths are rooted in this directory. SCons will 207# automatically expand '.' to refer to both the source directory and 208# the corresponding build directory to pick up generated include 209# files. 210env.Append(CPPPATH=Dir('.')) 211 212for extra_dir in extras_dir_list: 213 env.Append(CPPPATH=Dir(extra_dir)) 214 215# Add a flag defining what THE_ISA should be for all compilation 216env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) 217 218# Workaround for bug in SCons version > 0.97d20071212 219# Scons bug id: 2006 M5 Bug id: 308 220for root, dirs, files in os.walk(base_dir, topdown=True): 221 Dir(root[len(base_dir) + 1:]) 222 223######################################################################## 224# 225# Walk the tree and execute all SConscripts in subdirectories 226# 227 228here = Dir('.').srcnode().abspath 229for root, dirs, files in os.walk(base_dir, topdown=True): 230 if root == here: 231 # we don't want to recurse back into this SConscript 232 continue 233 234 if 'SConscript' in files: 235 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 236 SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) 237 238for extra_dir in extras_dir_list: 239 prefix_len = len(dirname(extra_dir)) + 1 240 for root, dirs, files in os.walk(extra_dir, topdown=True): 241 if 'SConscript' in files: 242 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 243 SConscript(joinpath(root, 'SConscript'), build_dir=build_dir) 244 245for opt in env.ExportOptions: 246 env.ConfigFile(opt) 247 248######################################################################## 249# 250# Prevent any SimObjects from being added after this point, they 251# should all have been added in the SConscripts above 252# 253class DictImporter(object): 254 '''This importer takes a dictionary of arbitrary module names that 255 map to arbitrary filenames.''' 256 def __init__(self, modules): 257 self.modules = modules 258 self.installed = set() 259 260 def __del__(self): 261 self.unload() 262 263 def unload(self): 264 import sys 265 for module in self.installed: 266 del sys.modules[module] 267 self.installed = set() 268 269 def find_module(self, fullname, path): 270 if fullname == 'defines': 271 return self 272 273 if fullname == 'm5.objects': 274 return self 275 276 if fullname.startswith('m5.internal'): 277 return None 278 279 if fullname in self.modules and exists(self.modules[fullname]): 280 return self 281 282 return None 283 284 def load_module(self, fullname): 285 mod = imp.new_module(fullname) 286 sys.modules[fullname] = mod 287 self.installed.add(fullname) 288 289 mod.__loader__ = self 290 if fullname == 'm5.objects': 291 mod.__path__ = fullname.split('.') 292 return mod 293 294 if fullname == 'defines': 295 mod.__dict__['buildEnv'] = build_env 296 return mod 297 298 srcfile = self.modules[fullname] 299 if basename(srcfile) == '__init__.py': 300 mod.__path__ = fullname.split('.') 301 mod.__file__ = srcfile 302 303 exec file(srcfile, 'r') in mod.__dict__ 304 305 return mod 306 307py_modules = {} 308for source in py_sources: 309 py_modules[source.modpath] = source.snode.abspath 310 311# install the python importer so we can grab stuff from the source 312# tree itself. We can't have SimObjects added after this point or 313# else we won't know about them for the rest of the stuff. 314sim_objects_fixed = True 315importer = DictImporter(py_modules) 316sys.meta_path[0:0] = [ importer ] 317 318import m5 319 320# import all sim objects so we can populate the all_objects list 321# make sure that we're working with a list, then let's sort it 322sim_objects = list(sim_object_modfiles) 323sim_objects.sort() 324for simobj in sim_objects: 325 exec('from m5.objects import %s' % simobj) 326 327# we need to unload all of the currently imported modules so that they 328# will be re-imported the next time the sconscript is run 329importer.unload() 330sys.meta_path.remove(importer) 331 332sim_objects = m5.SimObject.allClasses 333all_enums = m5.params.allEnums 334 335all_params = {} 336for name,obj in sim_objects.iteritems(): 337 for param in obj._params.local.values(): 338 if not hasattr(param, 'swig_decl'): 339 continue 340 pname = param.ptype_str 341 if pname not in all_params: 342 all_params[pname] = param 343 344######################################################################## 345# 346# calculate extra dependencies 347# 348module_depends = ["m5", "m5.SimObject", "m5.params"] 349depends = [ File(py_modules[dep]) for dep in module_depends ] 350 351######################################################################## 352# 353# Commands for the basic automatically generated python files 354# 355 356scons_dir = str(SCons.Node.FS.default_fs.SConstruct_dir) 357 358hg_info = ("Unknown", "Unknown", "Unknown") 359hg_demandimport = False 360try: 361 if not exists(scons_dir) or not isdir(scons_dir) or \ 362 not exists(joinpath(scons_dir, ".hg")): 363 raise ValueError(".hg directory not found") 364 365 import mercurial.demandimport, mercurial.hg, mercurial.ui 366 import mercurial.util, mercurial.node 367 hg_demandimport = True 368 369 repo = mercurial.hg.repository(mercurial.ui.ui(), scons_dir) 370 rev = mercurial.node.nullrev + repo.changelog.count() 371 changenode = repo.changelog.node(rev) 372 changes = repo.changelog.read(changenode) 373 id = mercurial.node.hex(changenode) 374 date = mercurial.util.datestr(changes[2]) 375 376 hg_info = (rev, id, date) 377except ImportError, e: 378 print "Mercurial not found" 379except ValueError, e: 380 print e 381except Exception, e: 382 print "Other mercurial exception: %s" % e 383 384if hg_demandimport: 385 mercurial.demandimport.disable() 386 387# Generate Python file containing a dict specifying the current 388# build_env flags. 389def makeDefinesPyFile(target, source, env): 390 f = file(str(target[0]), 'w') 391 build_env, hg_info = [ x.get_contents() for x in source ] 392 print >>f, "buildEnv = %s" % build_env 393 print >>f, "hgRev, hgId, hgDate = %s" % hg_info 394 f.close() 395 396defines_info = [ Value(build_env), Value(hg_info) ] 397# Generate a file with all of the compile options in it 398env.Command('python/m5/defines.py', defines_info, makeDefinesPyFile) 399PySource('m5', 'python/m5/defines.py') 400 401# Generate python file containing info about the M5 source code 402def makeInfoPyFile(target, source, env): 403 f = file(str(target[0]), 'w') 404 for src in source: 405 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 406 print >>f, "%s = %s" % (src, repr(data)) 407 f.close() 408 409# Generate a file that wraps the basic top level files 410env.Command('python/m5/info.py', 411 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ], 412 makeInfoPyFile) 413PySource('m5', 'python/m5/info.py') 414 415# Generate the __init__.py file for m5.objects 416def makeObjectsInitFile(target, source, env): 417 f = file(str(target[0]), 'w') 418 print >>f, 'from params import *' 419 print >>f, 'from m5.SimObject import *' 420 for module in source: 421 print >>f, 'from %s import *' % module.get_contents() 422 f.close() 423 424# Generate an __init__.py file for the objects package 425env.Command('python/m5/objects/__init__.py', 426 [ Value(o) for o in sort_list(sim_object_modfiles) ], 427 makeObjectsInitFile) 428PySource('m5.objects', 'python/m5/objects/__init__.py') 429 430######################################################################## 431# 432# Create all of the SimObject param headers and enum headers 433# 434 435def createSimObjectParam(target, source, env): 436 assert len(target) == 1 and len(source) == 1 437 438 hh_file = file(target[0].abspath, 'w') 439 name = str(source[0].get_contents()) 440 obj = sim_objects[name] 441 442 print >>hh_file, obj.cxx_decl() 443 444def createSwigParam(target, source, env): 445 assert len(target) == 1 and len(source) == 1 446 447 i_file = file(target[0].abspath, 'w') 448 name = str(source[0].get_contents()) 449 param = all_params[name] 450 451 for line in param.swig_decl(): 452 print >>i_file, line 453 454def createEnumStrings(target, source, env): 455 assert len(target) == 1 and len(source) == 1 456 457 cc_file = file(target[0].abspath, 'w') 458 name = str(source[0].get_contents()) 459 obj = all_enums[name] 460 461 print >>cc_file, obj.cxx_def() 462 cc_file.close() 463 464def createEnumParam(target, source, env): 465 assert len(target) == 1 and len(source) == 1 466 467 hh_file = file(target[0].abspath, 'w') 468 name = str(source[0].get_contents()) 469 obj = all_enums[name] 470 471 print >>hh_file, obj.cxx_decl() 472 473# Generate all of the SimObject param struct header files 474params_hh_files = [] 475for name,simobj in sim_objects.iteritems(): 476 extra_deps = [ File(py_modules[simobj.__module__]) ] 477 478 hh_file = File('params/%s.hh' % name) 479 params_hh_files.append(hh_file) 480 env.Command(hh_file, Value(name), createSimObjectParam) 481 env.Depends(hh_file, depends + extra_deps) 482 483# Generate any parameter header files needed 484params_i_files = [] 485for name,param in all_params.iteritems(): 486 if isinstance(param, m5.params.VectorParamDesc): 487 ext = 'vptype' 488 else: 489 ext = 'ptype' 490 491 i_file = File('params/%s_%s.i' % (name, ext)) 492 params_i_files.append(i_file) 493 env.Command(i_file, Value(name), createSwigParam) 494 env.Depends(i_file, depends) 495 496# Generate all enum header files 497for name,enum in all_enums.iteritems(): 498 extra_deps = [ File(py_modules[enum.__module__]) ] 499 500 cc_file = File('enums/%s.cc' % name) 501 env.Command(cc_file, Value(name), createEnumStrings) 502 env.Depends(cc_file, depends + extra_deps) 503 Source(cc_file) 504 505 hh_file = File('enums/%s.hh' % name) 506 env.Command(hh_file, Value(name), createEnumParam) 507 env.Depends(hh_file, depends + extra_deps) 508 509# Build the big monolithic swigged params module (wraps all SimObject 510# param structs and enum structs) 511def buildParams(target, source, env): 512 names = [ s.get_contents() for s in source ] 513 objs = [ sim_objects[name] for name in names ] 514 out = file(target[0].abspath, 'w') 515 516 ordered_objs = [] 517 obj_seen = set() 518 def order_obj(obj): 519 name = str(obj) 520 if name in obj_seen: 521 return 522 523 obj_seen.add(name) 524 if str(obj) != 'SimObject': 525 order_obj(obj.__bases__[0]) 526 527 ordered_objs.append(obj) 528 529 for obj in objs: 530 order_obj(obj) 531 532 enums = set() 533 predecls = [] 534 pd_seen = set() 535 536 def add_pds(*pds): 537 for pd in pds: 538 if pd not in pd_seen: 539 predecls.append(pd) 540 pd_seen.add(pd) 541 542 for obj in ordered_objs: 543 params = obj._params.local.values() 544 for param in params: 545 ptype = param.ptype 546 if issubclass(ptype, m5.params.Enum): 547 if ptype not in enums: 548 enums.add(ptype) 549 pds = param.swig_predecls() 550 if isinstance(pds, (list, tuple)): 551 add_pds(*pds) 552 else: 553 add_pds(pds) 554 555 print >>out, '%module params' 556 557 print >>out, '%{' 558 for obj in ordered_objs: 559 print >>out, '#include "params/%s.hh"' % obj 560 print >>out, '%}' 561 562 for pd in predecls: 563 print >>out, pd 564 565 enums = list(enums) 566 enums.sort() 567 for enum in enums: 568 print >>out, '%%include "enums/%s.hh"' % enum.__name__ 569 print >>out 570 571 for obj in ordered_objs: 572 if obj.swig_objdecls: 573 for decl in obj.swig_objdecls: 574 print >>out, decl 575 continue 576 577 class_path = obj.cxx_class.split('::') 578 classname = class_path[-1] 579 namespaces = class_path[:-1] 580 namespaces.reverse() 581 582 code = '' 583 584 if namespaces: 585 code += '// avoid name conflicts\n' 586 sep_string = '_COLONS_' 587 flat_name = sep_string.join(class_path) 588 code += '%%rename(%s) %s;\n' % (flat_name, classname) 589 590 code += '// stop swig from creating/wrapping default ctor/dtor\n' 591 code += '%%nodefault %s;\n' % classname 592 code += 'class %s ' % classname 593 if obj._base: 594 code += ': public %s' % obj._base.cxx_class 595 code += ' {};\n' 596 597 for ns in namespaces: 598 new_code = 'namespace %s {\n' % ns 599 new_code += code 600 new_code += '}\n' 601 code = new_code 602 603 print >>out, code 604 605 print >>out, '%%include "src/sim/sim_object_params.hh"' % obj 606 for obj in ordered_objs: 607 print >>out, '%%include "params/%s.hh"' % obj 608 609params_file = File('params/params.i') 610names = sort_list(sim_objects.keys()) 611env.Command(params_file, [ Value(v) for v in names ], buildParams) 612env.Depends(params_file, params_hh_files + params_i_files + depends) 613SwigSource('m5.objects', params_file) 614 615# Build all swig modules 616swig_modules = [] 617cc_swig_sources = [] 618for source,package in swig_sources: 619 filename = str(source) 620 assert filename.endswith('.i') 621 622 base = '.'.join(filename.split('.')[:-1]) 623 module = basename(base) 624 cc_file = base + '_wrap.cc' 625 py_file = base + '.py' 626 627 env.Command([cc_file, py_file], source, 628 '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 629 '-o ${TARGETS[0]} $SOURCES') 630 env.Depends(py_file, source) 631 env.Depends(cc_file, source) 632 633 swig_modules.append(Value(module)) 634 cc_swig_sources.append(File(cc_file)) 635 PySource(package, py_file) 636 637# Generate the main swig init file 638def makeSwigInit(target, source, env): 639 f = file(str(target[0]), 'w') 640 print >>f, 'extern "C" {' 641 for module in source: 642 print >>f, ' void init_%s();' % module.get_contents() 643 print >>f, '}' 644 print >>f, 'void initSwig() {' 645 for module in source: 646 print >>f, ' init_%s();' % module.get_contents() 647 print >>f, '}' 648 f.close() 649 650env.Command('python/swig/init.cc', swig_modules, makeSwigInit) 651Source('python/swig/init.cc') 652 653# Generate traceflags.py 654def traceFlagsPy(target, source, env): 655 assert(len(target) == 1) 656 657 f = file(str(target[0]), 'w') 658 659 allFlags = [] 660 for s in source: 661 val = eval(s.get_contents()) 662 allFlags.append(val) 663
|
669 print >>f, 'baseFlags = ['
| 664 allFlags.sort() 665 666 print >>f, 'basic = ['
|
670 for flag, compound, desc in allFlags: 671 if not compound: 672 print >>f, " '%s'," % flag 673 print >>f, " ]" 674 print >>f 675
| 667 for flag, compound, desc in allFlags: 668 if not compound: 669 print >>f, " '%s'," % flag 670 print >>f, " ]" 671 print >>f 672
|
676 print >>f, 'compoundFlags = ['
| 673 print >>f, 'compound = ['
|
677 print >>f, " 'All'," 678 for flag, compound, desc in allFlags: 679 if compound: 680 print >>f, " '%s'," % flag 681 print >>f, " ]" 682 print >>f 683
| 674 print >>f, " 'All'," 675 for flag, compound, desc in allFlags: 676 if compound: 677 print >>f, " '%s'," % flag 678 print >>f, " ]" 679 print >>f 680
|
684 print >>f, "allFlags = frozenset(baseFlags + compoundFlags)"
| 681 print >>f, "all = frozenset(basic + compound)"
|
685 print >>f 686
| 682 print >>f 683
|
687 print >>f, 'compoundFlagMap = {'
| 684 print >>f, 'compoundMap = {'
|
688 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 689 print >>f, " 'All' : %s," % (all, ) 690 for flag, compound, desc in allFlags: 691 if compound: 692 print >>f, " '%s' : %s," % (flag, compound) 693 print >>f, " }" 694 print >>f 695
| 685 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 686 print >>f, " 'All' : %s," % (all, ) 687 for flag, compound, desc in allFlags: 688 if compound: 689 print >>f, " '%s' : %s," % (flag, compound) 690 print >>f, " }" 691 print >>f 692
|
696 print >>f, 'flagDescriptions = {'
| 693 print >>f, 'descriptions = {'
|
697 print >>f, " 'All' : 'All flags'," 698 for flag, compound, desc in allFlags: 699 print >>f, " '%s' : '%s'," % (flag, desc) 700 print >>f, " }" 701 702 f.close() 703 704def traceFlagsCC(target, source, env): 705 assert(len(target) == 1) 706 707 f = file(str(target[0]), 'w') 708 709 allFlags = [] 710 for s in source: 711 val = eval(s.get_contents()) 712 allFlags.append(val) 713 714 # file header 715 print >>f, ''' 716/* 717 * DO NOT EDIT THIS FILE! Automatically generated 718 */ 719 720#include "base/traceflags.hh" 721 722using namespace Trace; 723 724const char *Trace::flagStrings[] = 725{''' 726 727 # The string array is used by SimpleEnumParam to map the strings 728 # provided by the user to enum values. 729 for flag, compound, desc in allFlags: 730 if not compound: 731 print >>f, ' "%s",' % flag 732 733 print >>f, ' "All",' 734 for flag, compound, desc in allFlags: 735 if compound: 736 print >>f, ' "%s",' % flag 737 738 print >>f, '};' 739 print >>f 740 print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1) 741 print >>f 742 743 # 744 # Now define the individual compound flag arrays. There is an array 745 # for each compound flag listing the component base flags. 746 # 747 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 748 print >>f, 'static const Flags AllMap[] = {' 749 for flag, compound, desc in allFlags: 750 if not compound: 751 print >>f, " %s," % flag 752 print >>f, '};' 753 print >>f 754 755 for flag, compound, desc in allFlags: 756 if not compound: 757 continue 758 print >>f, 'static const Flags %sMap[] = {' % flag 759 for flag in compound: 760 print >>f, " %s," % flag 761 print >>f, " (Flags)-1" 762 print >>f, '};' 763 print >>f 764 765 # 766 # Finally the compoundFlags[] array maps the compound flags 767 # to their individual arrays/ 768 # 769 print >>f, 'const Flags *Trace::compoundFlags[] =' 770 print >>f, '{' 771 print >>f, ' AllMap,' 772 for flag, compound, desc in allFlags: 773 if compound: 774 print >>f, ' %sMap,' % flag 775 # file trailer 776 print >>f, '};' 777 778 f.close() 779 780def traceFlagsHH(target, source, env): 781 assert(len(target) == 1) 782 783 f = file(str(target[0]), 'w') 784 785 allFlags = [] 786 for s in source: 787 val = eval(s.get_contents()) 788 allFlags.append(val) 789 790 # file header boilerplate 791 print >>f, ''' 792/* 793 * DO NOT EDIT THIS FILE! 794 * 795 * Automatically generated from traceflags.py 796 */ 797 798#ifndef __BASE_TRACE_FLAGS_HH__ 799#define __BASE_TRACE_FLAGS_HH__ 800 801namespace Trace { 802 803enum Flags {''' 804 805 # Generate the enum. Base flags come first, then compound flags. 806 idx = 0 807 for flag, compound, desc in allFlags: 808 if not compound: 809 print >>f, ' %s = %d,' % (flag, idx) 810 idx += 1 811 812 numBaseFlags = idx 813 print >>f, ' NumFlags = %d,' % idx 814 815 # put a comment in here to separate base from compound flags 816 print >>f, ''' 817// The remaining enum values are *not* valid indices for Trace::flags. 818// They are "compound" flags, which correspond to sets of base 819// flags, and are used by changeFlag.''' 820 821 print >>f, ' All = %d,' % idx 822 idx += 1 823 for flag, compound, desc in allFlags: 824 if compound: 825 print >>f, ' %s = %d,' % (flag, idx) 826 idx += 1 827 828 numCompoundFlags = idx - numBaseFlags 829 print >>f, ' NumCompoundFlags = %d' % numCompoundFlags 830 831 # trailer boilerplate 832 print >>f, '''\ 833}; // enum Flags 834 835// Array of strings for SimpleEnumParam 836extern const char *flagStrings[]; 837extern const int numFlagStrings; 838 839// Array of arraay pointers: for each compound flag, gives the list of 840// base flags to set. Inidividual flag arrays are terminated by -1. 841extern const Flags *compoundFlags[]; 842 843/* namespace Trace */ } 844 845#endif // __BASE_TRACE_FLAGS_HH__ 846''' 847 848 f.close() 849
| 694 print >>f, " 'All' : 'All flags'," 695 for flag, compound, desc in allFlags: 696 print >>f, " '%s' : '%s'," % (flag, desc) 697 print >>f, " }" 698 699 f.close() 700 701def traceFlagsCC(target, source, env): 702 assert(len(target) == 1) 703 704 f = file(str(target[0]), 'w') 705 706 allFlags = [] 707 for s in source: 708 val = eval(s.get_contents()) 709 allFlags.append(val) 710 711 # file header 712 print >>f, ''' 713/* 714 * DO NOT EDIT THIS FILE! Automatically generated 715 */ 716 717#include "base/traceflags.hh" 718 719using namespace Trace; 720 721const char *Trace::flagStrings[] = 722{''' 723 724 # The string array is used by SimpleEnumParam to map the strings 725 # provided by the user to enum values. 726 for flag, compound, desc in allFlags: 727 if not compound: 728 print >>f, ' "%s",' % flag 729 730 print >>f, ' "All",' 731 for flag, compound, desc in allFlags: 732 if compound: 733 print >>f, ' "%s",' % flag 734 735 print >>f, '};' 736 print >>f 737 print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1) 738 print >>f 739 740 # 741 # Now define the individual compound flag arrays. There is an array 742 # for each compound flag listing the component base flags. 743 # 744 all = tuple([flag for flag,compound,desc in allFlags if not compound]) 745 print >>f, 'static const Flags AllMap[] = {' 746 for flag, compound, desc in allFlags: 747 if not compound: 748 print >>f, " %s," % flag 749 print >>f, '};' 750 print >>f 751 752 for flag, compound, desc in allFlags: 753 if not compound: 754 continue 755 print >>f, 'static const Flags %sMap[] = {' % flag 756 for flag in compound: 757 print >>f, " %s," % flag 758 print >>f, " (Flags)-1" 759 print >>f, '};' 760 print >>f 761 762 # 763 # Finally the compoundFlags[] array maps the compound flags 764 # to their individual arrays/ 765 # 766 print >>f, 'const Flags *Trace::compoundFlags[] =' 767 print >>f, '{' 768 print >>f, ' AllMap,' 769 for flag, compound, desc in allFlags: 770 if compound: 771 print >>f, ' %sMap,' % flag 772 # file trailer 773 print >>f, '};' 774 775 f.close() 776 777def traceFlagsHH(target, source, env): 778 assert(len(target) == 1) 779 780 f = file(str(target[0]), 'w') 781 782 allFlags = [] 783 for s in source: 784 val = eval(s.get_contents()) 785 allFlags.append(val) 786 787 # file header boilerplate 788 print >>f, ''' 789/* 790 * DO NOT EDIT THIS FILE! 791 * 792 * Automatically generated from traceflags.py 793 */ 794 795#ifndef __BASE_TRACE_FLAGS_HH__ 796#define __BASE_TRACE_FLAGS_HH__ 797 798namespace Trace { 799 800enum Flags {''' 801 802 # Generate the enum. Base flags come first, then compound flags. 803 idx = 0 804 for flag, compound, desc in allFlags: 805 if not compound: 806 print >>f, ' %s = %d,' % (flag, idx) 807 idx += 1 808 809 numBaseFlags = idx 810 print >>f, ' NumFlags = %d,' % idx 811 812 # put a comment in here to separate base from compound flags 813 print >>f, ''' 814// The remaining enum values are *not* valid indices for Trace::flags. 815// They are "compound" flags, which correspond to sets of base 816// flags, and are used by changeFlag.''' 817 818 print >>f, ' All = %d,' % idx 819 idx += 1 820 for flag, compound, desc in allFlags: 821 if compound: 822 print >>f, ' %s = %d,' % (flag, idx) 823 idx += 1 824 825 numCompoundFlags = idx - numBaseFlags 826 print >>f, ' NumCompoundFlags = %d' % numCompoundFlags 827 828 # trailer boilerplate 829 print >>f, '''\ 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 f.close() 846
|
850flags = [ Value(f) for f in trace_flags ]
| 847flags = [ Value(f) for f in trace_flags.values() ]
|
851env.Command('base/traceflags.py', flags, traceFlagsPy) 852PySource('m5', 'base/traceflags.py') 853 854env.Command('base/traceflags.hh', flags, traceFlagsHH) 855env.Command('base/traceflags.cc', flags, traceFlagsCC) 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 an assembly file that 862# inserts the result into the data section with symbols indicating the 863# beginning, and end (and with the size at the end) 864py_sources_tnodes = {} 865for pysource in py_sources: 866 py_sources_tnodes[pysource.tnode] = pysource 867 868def objectifyPyFile(target, source, env): 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 dst = file(str(target[0]), 'w') 875 876 pysource = py_sources_tnodes[source[0]] 877 compiled = compile(src, pysource.debugname, 'exec') 878 marshalled = marshal.dumps(compiled) 879 compressed = zlib.compress(marshalled) 880 data = compressed 881 882 # Some C/C++ compilers prepend an underscore to global symbol 883 # names, so if they're going to do that, we need to prepend that 884 # leading underscore to globals in the assembly file. 885 if env['LEADING_UNDERSCORE']: 886 sym = '_' + pysource.symname 887 else: 888 sym = pysource.symname 889 890 step = 16 891 print >>dst, ".data" 892 print >>dst, ".globl %s_beg" % sym 893 print >>dst, ".globl %s_end" % sym 894 print >>dst, "%s_beg:" % sym 895 for i in xrange(0, len(data), step): 896 x = array.array('B', data[i:i+step]) 897 print >>dst, ".byte", ','.join([str(d) for d in x]) 898 print >>dst, "%s_end:" % sym 899 print >>dst, ".long %d" % len(marshalled) 900 901for source in py_sources: 902 env.Command(source.assembly, source.tnode, objectifyPyFile) 903 Source(source.assembly) 904 905# Generate init_python.cc which creates a bunch of EmbeddedPyModule 906# structs that describe the embedded python code. One such struct 907# contains information about the importer that python uses to get at 908# the embedded files, and then there's a list of all of the rest that 909# the importer uses to load the rest on demand. 910py_sources_symbols = {} 911for pysource in py_sources: 912 py_sources_symbols[pysource.symname] = pysource 913def pythonInit(target, source, env): 914 dst = file(str(target[0]), 'w') 915 916 def dump_mod(sym, endchar=','): 917 pysource = py_sources_symbols[sym] 918 print >>dst, ' { "%s",' % pysource.arcname 919 print >>dst, ' "%s",' % pysource.modpath 920 print >>dst, ' %s_beg, %s_end,' % (sym, sym) 921 print >>dst, ' %s_end - %s_beg,' % (sym, sym) 922 print >>dst, ' *(int *)%s_end }%s' % (sym, endchar) 923 924 print >>dst, '#include "sim/init.hh"' 925 926 for sym in source: 927 sym = sym.get_contents() 928 print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym) 929 930 print >>dst, "const EmbeddedPyModule embeddedPyImporter = " 931 dump_mod("PyEMB_importer", endchar=';'); 932 print >>dst 933 934 print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {" 935 for i,sym in enumerate(source): 936 sym = sym.get_contents() 937 if sym == "PyEMB_importer": 938 # Skip the importer since we've already exported it 939 continue 940 dump_mod(sym) 941 print >>dst, " { 0, 0, 0, 0, 0, 0 }" 942 print >>dst, "};" 943 944symbols = [Value(s.symname) for s in py_sources] 945env.Command('sim/init_python.cc', symbols, pythonInit) 946Source('sim/init_python.cc') 947 948######################################################################## 949# 950# Define binaries. Each different build type (debug, opt, etc.) gets 951# a slightly different build environment. 952# 953 954# List of constructed environments to pass back to SConstruct 955envList = [] 956 957# This function adds the specified sources to the given build 958# environment, and returns a list of all the corresponding SCons 959# Object nodes (including an extra one for date.cc). We explicitly 960# add the Object nodes so we can set up special dependencies for 961# date.cc. 962def make_objs(sources, env, static): 963 if static: 964 XObject = env.StaticObject 965 else: 966 XObject = env.SharedObject 967 968 objs = [ XObject(s) for s in sources ] 969 970 # make date.cc depend on all other objects so it always gets 971 # recompiled whenever anything else does 972 date_obj = XObject('base/date.cc') 973 974 env.Depends(date_obj, objs) 975 objs.append(date_obj) 976 return objs 977 978# Function to create a new build environment as clone of current 979# environment 'env' with modified object suffix and optional stripped 980# binary. Additional keyword arguments are appended to corresponding 981# build environment vars. 982def makeEnv(label, objsfx, strip = False, **kwargs): 983 # SCons doesn't know to append a library suffix when there is a '.' in the 984 # name. Use '_' instead. 985 libname = 'm5_' + label 986 exename = 'm5.' + label 987 988 new_env = env.Copy(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 989 new_env.Label = label 990 new_env.Append(**kwargs) 991 992 swig_env = new_env.Copy() 993 if env['GCC']: 994 swig_env.Append(CCFLAGS='-Wno-uninitialized') 995 swig_env.Append(CCFLAGS='-Wno-sign-compare') 996 swig_env.Append(CCFLAGS='-Wno-parentheses') 997 998 static_objs = make_objs(cc_lib_sources, new_env, static=True) 999 shared_objs = make_objs(cc_lib_sources, new_env, static=False) 1000 static_objs += [ swig_env.StaticObject(s) for s in cc_swig_sources ] 1001 shared_objs += [ swig_env.SharedObject(s) for s in cc_swig_sources ] 1002 1003 # First make a library of everything but main() so other programs can 1004 # link against m5. 1005 static_lib = new_env.StaticLibrary(libname, static_objs) 1006 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1007 1008 for target, sources in unit_tests: 1009 objs = [ new_env.StaticObject(s) for s in sources ] 1010 new_env.Program("unittest/%s.%s" % (target, label), objs + static_lib) 1011 1012 # Now link a stub with main() and the static library. 1013 objects = [new_env.Object(s) for s in cc_bin_sources] + static_lib 1014 if strip: 1015 unstripped_exe = exename + '.unstripped' 1016 new_env.Program(unstripped_exe, objects) 1017 if sys.platform == 'sunos5': 1018 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1019 else: 1020 cmd = 'strip $SOURCE -o $TARGET' 1021 targets = new_env.Command(exename, unstripped_exe, cmd) 1022 else: 1023 targets = new_env.Program(exename, objects) 1024 1025 new_env.M5Binary = targets[0] 1026 envList.append(new_env) 1027 1028# Debug binary 1029ccflags = {} 1030if env['GCC']: 1031 if sys.platform == 'sunos5': 1032 ccflags['debug'] = '-gstabs+' 1033 else: 1034 ccflags['debug'] = '-ggdb3' 1035 ccflags['opt'] = '-g -O3' 1036 ccflags['fast'] = '-O3' 1037 ccflags['prof'] = '-O3 -g -pg' 1038elif env['SUNCC']: 1039 ccflags['debug'] = '-g0' 1040 ccflags['opt'] = '-g -O' 1041 ccflags['fast'] = '-fast' 1042 ccflags['prof'] = '-fast -g -pg' 1043elif env['ICC']: 1044 ccflags['debug'] = '-g -O0' 1045 ccflags['opt'] = '-g -O' 1046 ccflags['fast'] = '-fast' 1047 ccflags['prof'] = '-fast -g -pg' 1048else: 1049 print 'Unknown compiler, please fix compiler options' 1050 Exit(1) 1051 1052makeEnv('debug', '.do', 1053 CCFLAGS = Split(ccflags['debug']), 1054 CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 1055 1056# Optimized binary 1057makeEnv('opt', '.o', 1058 CCFLAGS = Split(ccflags['opt']), 1059 CPPDEFINES = ['TRACING_ON=1']) 1060 1061# "Fast" binary 1062makeEnv('fast', '.fo', strip = True, 1063 CCFLAGS = Split(ccflags['fast']), 1064 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 1065 1066# Profiled binary 1067makeEnv('prof', '.po', 1068 CCFLAGS = Split(ccflags['prof']), 1069 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1070 LINKFLAGS = '-pg') 1071 1072Return('envList')
| 848env.Command('base/traceflags.py', flags, traceFlagsPy) 849PySource('m5', 'base/traceflags.py') 850 851env.Command('base/traceflags.hh', flags, traceFlagsHH) 852env.Command('base/traceflags.cc', flags, traceFlagsCC) 853Source('base/traceflags.cc') 854 855# embed python files. All .py files that have been indicated by a 856# PySource() call in a SConscript need to be embedded into the M5 857# library. To do that, we compile the file to byte code, marshal the 858# byte code, compress it, and then generate an assembly file that 859# inserts the result into the data section with symbols indicating the 860# beginning, and end (and with the size at the end) 861py_sources_tnodes = {} 862for pysource in py_sources: 863 py_sources_tnodes[pysource.tnode] = pysource 864 865def objectifyPyFile(target, source, env): 866 '''Action function to compile a .py into a code object, marshal 867 it, compress it, and stick it into an asm file so the code appears 868 as just bytes with a label in the data section''' 869 870 src = file(str(source[0]), 'r').read() 871 dst = file(str(target[0]), 'w') 872 873 pysource = py_sources_tnodes[source[0]] 874 compiled = compile(src, pysource.debugname, 'exec') 875 marshalled = marshal.dumps(compiled) 876 compressed = zlib.compress(marshalled) 877 data = compressed 878 879 # Some C/C++ compilers prepend an underscore to global symbol 880 # names, so if they're going to do that, we need to prepend that 881 # leading underscore to globals in the assembly file. 882 if env['LEADING_UNDERSCORE']: 883 sym = '_' + pysource.symname 884 else: 885 sym = pysource.symname 886 887 step = 16 888 print >>dst, ".data" 889 print >>dst, ".globl %s_beg" % sym 890 print >>dst, ".globl %s_end" % sym 891 print >>dst, "%s_beg:" % sym 892 for i in xrange(0, len(data), step): 893 x = array.array('B', data[i:i+step]) 894 print >>dst, ".byte", ','.join([str(d) for d in x]) 895 print >>dst, "%s_end:" % sym 896 print >>dst, ".long %d" % len(marshalled) 897 898for source in py_sources: 899 env.Command(source.assembly, source.tnode, objectifyPyFile) 900 Source(source.assembly) 901 902# Generate init_python.cc which creates a bunch of EmbeddedPyModule 903# structs that describe the embedded python code. One such struct 904# contains information about the importer that python uses to get at 905# the embedded files, and then there's a list of all of the rest that 906# the importer uses to load the rest on demand. 907py_sources_symbols = {} 908for pysource in py_sources: 909 py_sources_symbols[pysource.symname] = pysource 910def pythonInit(target, source, env): 911 dst = file(str(target[0]), 'w') 912 913 def dump_mod(sym, endchar=','): 914 pysource = py_sources_symbols[sym] 915 print >>dst, ' { "%s",' % pysource.arcname 916 print >>dst, ' "%s",' % pysource.modpath 917 print >>dst, ' %s_beg, %s_end,' % (sym, sym) 918 print >>dst, ' %s_end - %s_beg,' % (sym, sym) 919 print >>dst, ' *(int *)%s_end }%s' % (sym, endchar) 920 921 print >>dst, '#include "sim/init.hh"' 922 923 for sym in source: 924 sym = sym.get_contents() 925 print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym) 926 927 print >>dst, "const EmbeddedPyModule embeddedPyImporter = " 928 dump_mod("PyEMB_importer", endchar=';'); 929 print >>dst 930 931 print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {" 932 for i,sym in enumerate(source): 933 sym = sym.get_contents() 934 if sym == "PyEMB_importer": 935 # Skip the importer since we've already exported it 936 continue 937 dump_mod(sym) 938 print >>dst, " { 0, 0, 0, 0, 0, 0 }" 939 print >>dst, "};" 940 941symbols = [Value(s.symname) for s in py_sources] 942env.Command('sim/init_python.cc', symbols, pythonInit) 943Source('sim/init_python.cc') 944 945######################################################################## 946# 947# Define binaries. Each different build type (debug, opt, etc.) gets 948# a slightly different build environment. 949# 950 951# List of constructed environments to pass back to SConstruct 952envList = [] 953 954# This function adds the specified sources to the given build 955# environment, and returns a list of all the corresponding SCons 956# Object nodes (including an extra one for date.cc). We explicitly 957# add the Object nodes so we can set up special dependencies for 958# date.cc. 959def make_objs(sources, env, static): 960 if static: 961 XObject = env.StaticObject 962 else: 963 XObject = env.SharedObject 964 965 objs = [ XObject(s) for s in sources ] 966 967 # make date.cc depend on all other objects so it always gets 968 # recompiled whenever anything else does 969 date_obj = XObject('base/date.cc') 970 971 env.Depends(date_obj, objs) 972 objs.append(date_obj) 973 return objs 974 975# Function to create a new build environment as clone of current 976# environment 'env' with modified object suffix and optional stripped 977# binary. Additional keyword arguments are appended to corresponding 978# build environment vars. 979def makeEnv(label, objsfx, strip = False, **kwargs): 980 # SCons doesn't know to append a library suffix when there is a '.' in the 981 # name. Use '_' instead. 982 libname = 'm5_' + label 983 exename = 'm5.' + label 984 985 new_env = env.Copy(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 986 new_env.Label = label 987 new_env.Append(**kwargs) 988 989 swig_env = new_env.Copy() 990 if env['GCC']: 991 swig_env.Append(CCFLAGS='-Wno-uninitialized') 992 swig_env.Append(CCFLAGS='-Wno-sign-compare') 993 swig_env.Append(CCFLAGS='-Wno-parentheses') 994 995 static_objs = make_objs(cc_lib_sources, new_env, static=True) 996 shared_objs = make_objs(cc_lib_sources, new_env, static=False) 997 static_objs += [ swig_env.StaticObject(s) for s in cc_swig_sources ] 998 shared_objs += [ swig_env.SharedObject(s) for s in cc_swig_sources ] 999 1000 # First make a library of everything but main() so other programs can 1001 # link against m5. 1002 static_lib = new_env.StaticLibrary(libname, static_objs) 1003 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1004 1005 for target, sources in unit_tests: 1006 objs = [ new_env.StaticObject(s) for s in sources ] 1007 new_env.Program("unittest/%s.%s" % (target, label), objs + static_lib) 1008 1009 # Now link a stub with main() and the static library. 1010 objects = [new_env.Object(s) for s in cc_bin_sources] + static_lib 1011 if strip: 1012 unstripped_exe = exename + '.unstripped' 1013 new_env.Program(unstripped_exe, objects) 1014 if sys.platform == 'sunos5': 1015 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1016 else: 1017 cmd = 'strip $SOURCE -o $TARGET' 1018 targets = new_env.Command(exename, unstripped_exe, cmd) 1019 else: 1020 targets = new_env.Program(exename, objects) 1021 1022 new_env.M5Binary = targets[0] 1023 envList.append(new_env) 1024 1025# Debug binary 1026ccflags = {} 1027if env['GCC']: 1028 if sys.platform == 'sunos5': 1029 ccflags['debug'] = '-gstabs+' 1030 else: 1031 ccflags['debug'] = '-ggdb3' 1032 ccflags['opt'] = '-g -O3' 1033 ccflags['fast'] = '-O3' 1034 ccflags['prof'] = '-O3 -g -pg' 1035elif env['SUNCC']: 1036 ccflags['debug'] = '-g0' 1037 ccflags['opt'] = '-g -O' 1038 ccflags['fast'] = '-fast' 1039 ccflags['prof'] = '-fast -g -pg' 1040elif env['ICC']: 1041 ccflags['debug'] = '-g -O0' 1042 ccflags['opt'] = '-g -O' 1043 ccflags['fast'] = '-fast' 1044 ccflags['prof'] = '-fast -g -pg' 1045else: 1046 print 'Unknown compiler, please fix compiler options' 1047 Exit(1) 1048 1049makeEnv('debug', '.do', 1050 CCFLAGS = Split(ccflags['debug']), 1051 CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 1052 1053# Optimized binary 1054makeEnv('opt', '.o', 1055 CCFLAGS = Split(ccflags['opt']), 1056 CPPDEFINES = ['TRACING_ON=1']) 1057 1058# "Fast" binary 1059makeEnv('fast', '.fo', strip = True, 1060 CCFLAGS = Split(ccflags['fast']), 1061 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 1062 1063# Profiled binary 1064makeEnv('prof', '.po', 1065 CCFLAGS = Split(ccflags['prof']), 1066 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1067 LINKFLAGS = '-pg') 1068 1069Return('envList')
|