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