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 subprocess 38import sys 39import zlib 40 41from os.path import basename, dirname, exists, isdir, isfile, join as joinpath 42 43import SCons 44 45# This file defines how to build a particular configuration of gem5 46# based on variable settings in the 'env' build environment. 47 48Import('*') 49 50# Children need to see the environment 51Export('env') 52 53build_env = [(opt, env[opt]) for opt in export_vars] 54 55from m5.util import code_formatter, compareVersions 56 57######################################################################## 58# Code for adding source files of various types 59# 60# When specifying a source file of some type, a set of guards can be 61# specified for that file. When get() is used to find the files, if 62# get specifies a set of filters, only files that match those filters 63# will be accepted (unspecified filters on files are assumed to be 64# false). Current filters are: 65# main -- specifies the gem5 main() function 66# skip_lib -- do not put this file into the gem5 library 67# skip_no_python -- do not put this file into a no_python library 68# as it embeds compiled Python 69# <unittest> -- unit tests use filters based on the unit test name 70# 71# A parent can now be specified for a source file and default filter 72# values will be retrieved recursively from parents (children override 73# parents). 74# 75def guarded_source_iterator(sources, **guards): 76 '''Iterate over a set of sources, gated by a set of guards.''' 77 for src in sources: 78 for flag,value in guards.iteritems(): 79 # if the flag is found and has a different value, skip 80 # this file 81 if src.all_guards.get(flag, False) != value: 82 break 83 else: 84 yield src 85 86class SourceMeta(type): 87 '''Meta class for source files that keeps track of all files of a 88 particular type and has a get function for finding all functions 89 of a certain type that match a set of guards''' 90 def __init__(cls, name, bases, dict): 91 super(SourceMeta, cls).__init__(name, bases, dict) 92 cls.all = [] 93 94 def get(cls, **guards): 95 '''Find all files that match the specified guards. If a source 96 file does not specify a flag, the default is False''' 97 for s in guarded_source_iterator(cls.all, **guards): 98 yield s 99 100class SourceFile(object): 101 '''Base object that encapsulates the notion of a source file. 102 This includes, the source node, target node, various manipulations 103 of those. A source file also specifies a set of guards which 104 describing which builds the source file applies to. A parent can 105 also be specified to get default guards from''' 106 __metaclass__ = SourceMeta 107 def __init__(self, source, parent=None, **guards): 108 self.guards = guards 109 self.parent = parent 110 111 tnode = source 112 if not isinstance(source, SCons.Node.FS.File): 113 tnode = File(source) 114 115 self.tnode = tnode 116 self.snode = tnode.srcnode() 117 118 for base in type(self).__mro__: 119 if issubclass(base, SourceFile): 120 base.all.append(self) 121 122 @property 123 def filename(self): 124 return str(self.tnode) 125 126 @property 127 def dirname(self): 128 return dirname(self.filename) 129 130 @property 131 def basename(self): 132 return basename(self.filename) 133 134 @property 135 def extname(self): 136 index = self.basename.rfind('.') 137 if index <= 0: 138 # dot files aren't extensions 139 return self.basename, None 140 141 return self.basename[:index], self.basename[index+1:] 142 143 @property 144 def all_guards(self): 145 '''find all guards for this object getting default values 146 recursively from its parents''' 147 guards = {} 148 if self.parent: 149 guards.update(self.parent.guards) 150 guards.update(self.guards) 151 return guards 152 153 def __lt__(self, other): return self.filename < other.filename 154 def __le__(self, other): return self.filename <= other.filename 155 def __gt__(self, other): return self.filename > other.filename 156 def __ge__(self, other): return self.filename >= other.filename 157 def __eq__(self, other): return self.filename == other.filename 158 def __ne__(self, other): return self.filename != other.filename 159 160 @staticmethod 161 def done(): 162 def disabled(cls, name, *ignored): 163 raise RuntimeError("Additional SourceFile '%s'" % name,\ 164 "declared, but targets deps are already fixed.") 165 SourceFile.__init__ = disabled 166 167 168class Source(SourceFile): 169 current_group = None 170 source_groups = { None : [] } 171 172 @classmethod 173 def set_group(cls, group): 174 if not group in Source.source_groups: 175 Source.source_groups[group] = [] 176 Source.current_group = group 177 178 '''Add a c/c++ source file to the build'''
| 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 subprocess 38import sys 39import zlib 40 41from os.path import basename, dirname, exists, isdir, isfile, join as joinpath 42 43import SCons 44 45# This file defines how to build a particular configuration of gem5 46# based on variable settings in the 'env' build environment. 47 48Import('*') 49 50# Children need to see the environment 51Export('env') 52 53build_env = [(opt, env[opt]) for opt in export_vars] 54 55from m5.util import code_formatter, compareVersions 56 57######################################################################## 58# Code for adding source files of various types 59# 60# When specifying a source file of some type, a set of guards can be 61# specified for that file. When get() is used to find the files, if 62# get specifies a set of filters, only files that match those filters 63# will be accepted (unspecified filters on files are assumed to be 64# false). Current filters are: 65# main -- specifies the gem5 main() function 66# skip_lib -- do not put this file into the gem5 library 67# skip_no_python -- do not put this file into a no_python library 68# as it embeds compiled Python 69# <unittest> -- unit tests use filters based on the unit test name 70# 71# A parent can now be specified for a source file and default filter 72# values will be retrieved recursively from parents (children override 73# parents). 74# 75def guarded_source_iterator(sources, **guards): 76 '''Iterate over a set of sources, gated by a set of guards.''' 77 for src in sources: 78 for flag,value in guards.iteritems(): 79 # if the flag is found and has a different value, skip 80 # this file 81 if src.all_guards.get(flag, False) != value: 82 break 83 else: 84 yield src 85 86class SourceMeta(type): 87 '''Meta class for source files that keeps track of all files of a 88 particular type and has a get function for finding all functions 89 of a certain type that match a set of guards''' 90 def __init__(cls, name, bases, dict): 91 super(SourceMeta, cls).__init__(name, bases, dict) 92 cls.all = [] 93 94 def get(cls, **guards): 95 '''Find all files that match the specified guards. If a source 96 file does not specify a flag, the default is False''' 97 for s in guarded_source_iterator(cls.all, **guards): 98 yield s 99 100class SourceFile(object): 101 '''Base object that encapsulates the notion of a source file. 102 This includes, the source node, target node, various manipulations 103 of those. A source file also specifies a set of guards which 104 describing which builds the source file applies to. A parent can 105 also be specified to get default guards from''' 106 __metaclass__ = SourceMeta 107 def __init__(self, source, parent=None, **guards): 108 self.guards = guards 109 self.parent = parent 110 111 tnode = source 112 if not isinstance(source, SCons.Node.FS.File): 113 tnode = File(source) 114 115 self.tnode = tnode 116 self.snode = tnode.srcnode() 117 118 for base in type(self).__mro__: 119 if issubclass(base, SourceFile): 120 base.all.append(self) 121 122 @property 123 def filename(self): 124 return str(self.tnode) 125 126 @property 127 def dirname(self): 128 return dirname(self.filename) 129 130 @property 131 def basename(self): 132 return basename(self.filename) 133 134 @property 135 def extname(self): 136 index = self.basename.rfind('.') 137 if index <= 0: 138 # dot files aren't extensions 139 return self.basename, None 140 141 return self.basename[:index], self.basename[index+1:] 142 143 @property 144 def all_guards(self): 145 '''find all guards for this object getting default values 146 recursively from its parents''' 147 guards = {} 148 if self.parent: 149 guards.update(self.parent.guards) 150 guards.update(self.guards) 151 return guards 152 153 def __lt__(self, other): return self.filename < other.filename 154 def __le__(self, other): return self.filename <= other.filename 155 def __gt__(self, other): return self.filename > other.filename 156 def __ge__(self, other): return self.filename >= other.filename 157 def __eq__(self, other): return self.filename == other.filename 158 def __ne__(self, other): return self.filename != other.filename 159 160 @staticmethod 161 def done(): 162 def disabled(cls, name, *ignored): 163 raise RuntimeError("Additional SourceFile '%s'" % name,\ 164 "declared, but targets deps are already fixed.") 165 SourceFile.__init__ = disabled 166 167 168class Source(SourceFile): 169 current_group = None 170 source_groups = { None : [] } 171 172 @classmethod 173 def set_group(cls, group): 174 if not group in Source.source_groups: 175 Source.source_groups[group] = [] 176 Source.current_group = group 177 178 '''Add a c/c++ source file to the build'''
|
179 def __init__(self, source, Werror=True, swig=False, **guards):
| 179 def __init__(self, source, Werror=True, **guards):
|
180 '''specify the source file, and any guards''' 181 super(Source, self).__init__(source, **guards) 182 183 self.Werror = Werror
| 180 '''specify the source file, and any guards''' 181 super(Source, self).__init__(source, **guards) 182 183 self.Werror = Werror
|
184 self.swig = swig
| |
185 186 Source.source_groups[Source.current_group].append(self) 187 188class PySource(SourceFile): 189 '''Add a python source file to the named package''' 190 invalid_sym_char = re.compile('[^A-z0-9_]') 191 modules = {} 192 tnodes = {} 193 symnames = {} 194 195 def __init__(self, package, source, **guards): 196 '''specify the python package, the source file, and any guards''' 197 super(PySource, self).__init__(source, **guards) 198 199 modname,ext = self.extname 200 assert ext == 'py' 201 202 if package: 203 path = package.split('.') 204 else: 205 path = [] 206 207 modpath = path[:] 208 if modname != '__init__': 209 modpath += [ modname ] 210 modpath = '.'.join(modpath) 211 212 arcpath = path + [ self.basename ] 213 abspath = self.snode.abspath 214 if not exists(abspath): 215 abspath = self.tnode.abspath 216 217 self.package = package 218 self.modname = modname 219 self.modpath = modpath 220 self.arcname = joinpath(*arcpath) 221 self.abspath = abspath 222 self.compiled = File(self.filename + 'c') 223 self.cpp = File(self.filename + '.cc') 224 self.symname = PySource.invalid_sym_char.sub('_', modpath) 225 226 PySource.modules[modpath] = self 227 PySource.tnodes[self.tnode] = self 228 PySource.symnames[self.symname] = self 229 230class SimObject(PySource): 231 '''Add a SimObject python file as a python source object and add 232 it to a list of sim object modules''' 233 234 fixed = False 235 modnames = [] 236 237 def __init__(self, source, **guards): 238 '''Specify the source file and any guards (automatically in 239 the m5.objects package)''' 240 super(SimObject, self).__init__('m5.objects', source, **guards) 241 if self.fixed: 242 raise AttributeError, "Too late to call SimObject now." 243 244 bisect.insort_right(SimObject.modnames, self.modname) 245
| 184 185 Source.source_groups[Source.current_group].append(self) 186 187class PySource(SourceFile): 188 '''Add a python source file to the named package''' 189 invalid_sym_char = re.compile('[^A-z0-9_]') 190 modules = {} 191 tnodes = {} 192 symnames = {} 193 194 def __init__(self, package, source, **guards): 195 '''specify the python package, the source file, and any guards''' 196 super(PySource, self).__init__(source, **guards) 197 198 modname,ext = self.extname 199 assert ext == 'py' 200 201 if package: 202 path = package.split('.') 203 else: 204 path = [] 205 206 modpath = path[:] 207 if modname != '__init__': 208 modpath += [ modname ] 209 modpath = '.'.join(modpath) 210 211 arcpath = path + [ self.basename ] 212 abspath = self.snode.abspath 213 if not exists(abspath): 214 abspath = self.tnode.abspath 215 216 self.package = package 217 self.modname = modname 218 self.modpath = modpath 219 self.arcname = joinpath(*arcpath) 220 self.abspath = abspath 221 self.compiled = File(self.filename + 'c') 222 self.cpp = File(self.filename + '.cc') 223 self.symname = PySource.invalid_sym_char.sub('_', modpath) 224 225 PySource.modules[modpath] = self 226 PySource.tnodes[self.tnode] = self 227 PySource.symnames[self.symname] = self 228 229class SimObject(PySource): 230 '''Add a SimObject python file as a python source object and add 231 it to a list of sim object modules''' 232 233 fixed = False 234 modnames = [] 235 236 def __init__(self, source, **guards): 237 '''Specify the source file and any guards (automatically in 238 the m5.objects package)''' 239 super(SimObject, self).__init__('m5.objects', source, **guards) 240 if self.fixed: 241 raise AttributeError, "Too late to call SimObject now." 242 243 bisect.insort_right(SimObject.modnames, self.modname) 244
|
246class SwigSource(SourceFile): 247 '''Add a swig file to build''' 248 249 def __init__(self, package, source, **guards): 250 '''Specify the python package, the source file, and any guards''' 251 super(SwigSource, self).__init__(source, skip_no_python=True, **guards) 252 253 modname,ext = self.extname 254 assert ext == 'i' 255 256 self.package = package 257 self.module = modname 258 cc_file = joinpath(self.dirname, modname + '_wrap.cc') 259 py_file = joinpath(self.dirname, modname + '.py') 260 261 self.cc_source = Source(cc_file, swig=True, parent=self, **guards) 262 self.py_source = PySource(package, py_file, parent=self, **guards) 263
| |
264class ProtoBuf(SourceFile): 265 '''Add a Protocol Buffer to build''' 266 267 def __init__(self, source, **guards): 268 '''Specify the source file, and any guards''' 269 super(ProtoBuf, self).__init__(source, **guards) 270 271 # Get the file name and the extension 272 modname,ext = self.extname 273 assert ext == 'proto' 274 275 # Currently, we stick to generating the C++ headers, so we 276 # only need to track the source and header. 277 self.cc_file = File(modname + '.pb.cc') 278 self.hh_file = File(modname + '.pb.h') 279 280class UnitTest(object): 281 '''Create a UnitTest''' 282 283 all = [] 284 def __init__(self, target, *sources, **kwargs): 285 '''Specify the target name and any sources. Sources that are 286 not SourceFiles are evalued with Source(). All files are 287 guarded with a guard of the same name as the UnitTest 288 target.''' 289 290 srcs = [] 291 for src in sources: 292 if not isinstance(src, SourceFile): 293 src = Source(src, skip_lib=True) 294 src.guards[target] = True 295 srcs.append(src) 296 297 self.sources = srcs 298 self.target = target 299 self.main = kwargs.get('main', False) 300 UnitTest.all.append(self) 301 302# Children should have access 303Export('Source') 304Export('PySource') 305Export('SimObject')
| 245class ProtoBuf(SourceFile): 246 '''Add a Protocol Buffer to build''' 247 248 def __init__(self, source, **guards): 249 '''Specify the source file, and any guards''' 250 super(ProtoBuf, self).__init__(source, **guards) 251 252 # Get the file name and the extension 253 modname,ext = self.extname 254 assert ext == 'proto' 255 256 # Currently, we stick to generating the C++ headers, so we 257 # only need to track the source and header. 258 self.cc_file = File(modname + '.pb.cc') 259 self.hh_file = File(modname + '.pb.h') 260 261class UnitTest(object): 262 '''Create a UnitTest''' 263 264 all = [] 265 def __init__(self, target, *sources, **kwargs): 266 '''Specify the target name and any sources. Sources that are 267 not SourceFiles are evalued with Source(). All files are 268 guarded with a guard of the same name as the UnitTest 269 target.''' 270 271 srcs = [] 272 for src in sources: 273 if not isinstance(src, SourceFile): 274 src = Source(src, skip_lib=True) 275 src.guards[target] = True 276 srcs.append(src) 277 278 self.sources = srcs 279 self.target = target 280 self.main = kwargs.get('main', False) 281 UnitTest.all.append(self) 282 283# Children should have access 284Export('Source') 285Export('PySource') 286Export('SimObject')
|
306Export('SwigSource')
| |
307Export('ProtoBuf') 308Export('UnitTest') 309 310######################################################################## 311# 312# Debug Flags 313# 314debug_flags = {} 315def DebugFlag(name, desc=None): 316 if name in debug_flags: 317 raise AttributeError, "Flag %s already specified" % name 318 debug_flags[name] = (name, (), desc) 319 320def CompoundFlag(name, flags, desc=None): 321 if name in debug_flags: 322 raise AttributeError, "Flag %s already specified" % name 323 324 compound = tuple(flags) 325 debug_flags[name] = (name, compound, desc) 326 327Export('DebugFlag') 328Export('CompoundFlag') 329 330######################################################################## 331# 332# Set some compiler variables 333# 334 335# Include file paths are rooted in this directory. SCons will 336# automatically expand '.' to refer to both the source directory and 337# the corresponding build directory to pick up generated include 338# files. 339env.Append(CPPPATH=Dir('.')) 340 341for extra_dir in extras_dir_list: 342 env.Append(CPPPATH=Dir(extra_dir)) 343 344# Workaround for bug in SCons version > 0.97d20071212 345# Scons bug id: 2006 gem5 Bug id: 308 346for root, dirs, files in os.walk(base_dir, topdown=True): 347 Dir(root[len(base_dir) + 1:]) 348 349######################################################################## 350# 351# Walk the tree and execute all SConscripts in subdirectories 352# 353 354here = Dir('.').srcnode().abspath 355for root, dirs, files in os.walk(base_dir, topdown=True): 356 if root == here: 357 # we don't want to recurse back into this SConscript 358 continue 359 360 if 'SConscript' in files: 361 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 362 Source.set_group(build_dir) 363 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 364 365for extra_dir in extras_dir_list: 366 prefix_len = len(dirname(extra_dir)) + 1 367 368 # Also add the corresponding build directory to pick up generated 369 # include files. 370 env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 371 372 for root, dirs, files in os.walk(extra_dir, topdown=True): 373 # if build lives in the extras directory, don't walk down it 374 if 'build' in dirs: 375 dirs.remove('build') 376 377 if 'SConscript' in files: 378 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 379 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 380 381for opt in export_vars: 382 env.ConfigFile(opt) 383 384def makeTheISA(source, target, env): 385 isas = [ src.get_contents() for src in source ] 386 target_isa = env['TARGET_ISA'] 387 def define(isa): 388 return isa.upper() + '_ISA' 389 390 def namespace(isa): 391 return isa[0].upper() + isa[1:].lower() + 'ISA' 392 393 394 code = code_formatter() 395 code('''\ 396#ifndef __CONFIG_THE_ISA_HH__ 397#define __CONFIG_THE_ISA_HH__ 398 399''') 400 401 # create defines for the preprocessing and compile-time determination 402 for i,isa in enumerate(isas): 403 code('#define $0 $1', define(isa), i + 1) 404 code() 405 406 # create an enum for any run-time determination of the ISA, we 407 # reuse the same name as the namespaces 408 code('enum class Arch {') 409 for i,isa in enumerate(isas): 410 if i + 1 == len(isas): 411 code(' $0 = $1', namespace(isa), define(isa)) 412 else: 413 code(' $0 = $1,', namespace(isa), define(isa)) 414 code('};') 415 416 code(''' 417 418#define THE_ISA ${{define(target_isa)}} 419#define TheISA ${{namespace(target_isa)}} 420#define THE_ISA_STR "${{target_isa}}" 421 422#endif // __CONFIG_THE_ISA_HH__''') 423 424 code.write(str(target[0])) 425 426env.Command('config/the_isa.hh', map(Value, all_isa_list), 427 MakeAction(makeTheISA, Transform("CFG ISA", 0))) 428 429def makeTheGPUISA(source, target, env): 430 isas = [ src.get_contents() for src in source ] 431 target_gpu_isa = env['TARGET_GPU_ISA'] 432 def define(isa): 433 return isa.upper() + '_ISA' 434 435 def namespace(isa): 436 return isa[0].upper() + isa[1:].lower() + 'ISA' 437 438 439 code = code_formatter() 440 code('''\ 441#ifndef __CONFIG_THE_GPU_ISA_HH__ 442#define __CONFIG_THE_GPU_ISA_HH__ 443 444''') 445 446 # create defines for the preprocessing and compile-time determination 447 for i,isa in enumerate(isas): 448 code('#define $0 $1', define(isa), i + 1) 449 code() 450 451 # create an enum for any run-time determination of the ISA, we 452 # reuse the same name as the namespaces 453 code('enum class GPUArch {') 454 for i,isa in enumerate(isas): 455 if i + 1 == len(isas): 456 code(' $0 = $1', namespace(isa), define(isa)) 457 else: 458 code(' $0 = $1,', namespace(isa), define(isa)) 459 code('};') 460 461 code(''' 462 463#define THE_GPU_ISA ${{define(target_gpu_isa)}} 464#define TheGpuISA ${{namespace(target_gpu_isa)}} 465#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 466 467#endif // __CONFIG_THE_GPU_ISA_HH__''') 468 469 code.write(str(target[0])) 470 471env.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 472 MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 473 474######################################################################## 475# 476# Prevent any SimObjects from being added after this point, they 477# should all have been added in the SConscripts above 478# 479SimObject.fixed = True 480 481class DictImporter(object): 482 '''This importer takes a dictionary of arbitrary module names that 483 map to arbitrary filenames.''' 484 def __init__(self, modules): 485 self.modules = modules 486 self.installed = set() 487 488 def __del__(self): 489 self.unload() 490 491 def unload(self): 492 import sys 493 for module in self.installed: 494 del sys.modules[module] 495 self.installed = set() 496 497 def find_module(self, fullname, path): 498 if fullname == 'm5.defines': 499 return self 500 501 if fullname == 'm5.objects': 502 return self 503 504 if fullname.startswith('_m5'): 505 return None 506 507 source = self.modules.get(fullname, None) 508 if source is not None and fullname.startswith('m5.objects'): 509 return self 510 511 return None 512 513 def load_module(self, fullname): 514 mod = imp.new_module(fullname) 515 sys.modules[fullname] = mod 516 self.installed.add(fullname) 517 518 mod.__loader__ = self 519 if fullname == 'm5.objects': 520 mod.__path__ = fullname.split('.') 521 return mod 522 523 if fullname == 'm5.defines': 524 mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 525 return mod 526 527 source = self.modules[fullname] 528 if source.modname == '__init__': 529 mod.__path__ = source.modpath 530 mod.__file__ = source.abspath 531 532 exec file(source.abspath, 'r') in mod.__dict__ 533 534 return mod 535 536import m5.SimObject 537import m5.params 538from m5.util import code_formatter 539 540m5.SimObject.clear() 541m5.params.clear() 542 543# install the python importer so we can grab stuff from the source 544# tree itself. We can't have SimObjects added after this point or 545# else we won't know about them for the rest of the stuff. 546importer = DictImporter(PySource.modules) 547sys.meta_path[0:0] = [ importer ] 548 549# import all sim objects so we can populate the all_objects list 550# make sure that we're working with a list, then let's sort it 551for modname in SimObject.modnames: 552 exec('from m5.objects import %s' % modname) 553 554# we need to unload all of the currently imported modules so that they 555# will be re-imported the next time the sconscript is run 556importer.unload() 557sys.meta_path.remove(importer) 558 559sim_objects = m5.SimObject.allClasses 560all_enums = m5.params.allEnums 561
| 287Export('ProtoBuf') 288Export('UnitTest') 289 290######################################################################## 291# 292# Debug Flags 293# 294debug_flags = {} 295def DebugFlag(name, desc=None): 296 if name in debug_flags: 297 raise AttributeError, "Flag %s already specified" % name 298 debug_flags[name] = (name, (), desc) 299 300def CompoundFlag(name, flags, desc=None): 301 if name in debug_flags: 302 raise AttributeError, "Flag %s already specified" % name 303 304 compound = tuple(flags) 305 debug_flags[name] = (name, compound, desc) 306 307Export('DebugFlag') 308Export('CompoundFlag') 309 310######################################################################## 311# 312# Set some compiler variables 313# 314 315# Include file paths are rooted in this directory. SCons will 316# automatically expand '.' to refer to both the source directory and 317# the corresponding build directory to pick up generated include 318# files. 319env.Append(CPPPATH=Dir('.')) 320 321for extra_dir in extras_dir_list: 322 env.Append(CPPPATH=Dir(extra_dir)) 323 324# Workaround for bug in SCons version > 0.97d20071212 325# Scons bug id: 2006 gem5 Bug id: 308 326for root, dirs, files in os.walk(base_dir, topdown=True): 327 Dir(root[len(base_dir) + 1:]) 328 329######################################################################## 330# 331# Walk the tree and execute all SConscripts in subdirectories 332# 333 334here = Dir('.').srcnode().abspath 335for root, dirs, files in os.walk(base_dir, topdown=True): 336 if root == here: 337 # we don't want to recurse back into this SConscript 338 continue 339 340 if 'SConscript' in files: 341 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:]) 342 Source.set_group(build_dir) 343 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 344 345for extra_dir in extras_dir_list: 346 prefix_len = len(dirname(extra_dir)) + 1 347 348 # Also add the corresponding build directory to pick up generated 349 # include files. 350 env.Append(CPPPATH=Dir(joinpath(env['BUILDDIR'], extra_dir[prefix_len:]))) 351 352 for root, dirs, files in os.walk(extra_dir, topdown=True): 353 # if build lives in the extras directory, don't walk down it 354 if 'build' in dirs: 355 dirs.remove('build') 356 357 if 'SConscript' in files: 358 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:]) 359 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir) 360 361for opt in export_vars: 362 env.ConfigFile(opt) 363 364def makeTheISA(source, target, env): 365 isas = [ src.get_contents() for src in source ] 366 target_isa = env['TARGET_ISA'] 367 def define(isa): 368 return isa.upper() + '_ISA' 369 370 def namespace(isa): 371 return isa[0].upper() + isa[1:].lower() + 'ISA' 372 373 374 code = code_formatter() 375 code('''\ 376#ifndef __CONFIG_THE_ISA_HH__ 377#define __CONFIG_THE_ISA_HH__ 378 379''') 380 381 # create defines for the preprocessing and compile-time determination 382 for i,isa in enumerate(isas): 383 code('#define $0 $1', define(isa), i + 1) 384 code() 385 386 # create an enum for any run-time determination of the ISA, we 387 # reuse the same name as the namespaces 388 code('enum class Arch {') 389 for i,isa in enumerate(isas): 390 if i + 1 == len(isas): 391 code(' $0 = $1', namespace(isa), define(isa)) 392 else: 393 code(' $0 = $1,', namespace(isa), define(isa)) 394 code('};') 395 396 code(''' 397 398#define THE_ISA ${{define(target_isa)}} 399#define TheISA ${{namespace(target_isa)}} 400#define THE_ISA_STR "${{target_isa}}" 401 402#endif // __CONFIG_THE_ISA_HH__''') 403 404 code.write(str(target[0])) 405 406env.Command('config/the_isa.hh', map(Value, all_isa_list), 407 MakeAction(makeTheISA, Transform("CFG ISA", 0))) 408 409def makeTheGPUISA(source, target, env): 410 isas = [ src.get_contents() for src in source ] 411 target_gpu_isa = env['TARGET_GPU_ISA'] 412 def define(isa): 413 return isa.upper() + '_ISA' 414 415 def namespace(isa): 416 return isa[0].upper() + isa[1:].lower() + 'ISA' 417 418 419 code = code_formatter() 420 code('''\ 421#ifndef __CONFIG_THE_GPU_ISA_HH__ 422#define __CONFIG_THE_GPU_ISA_HH__ 423 424''') 425 426 # create defines for the preprocessing and compile-time determination 427 for i,isa in enumerate(isas): 428 code('#define $0 $1', define(isa), i + 1) 429 code() 430 431 # create an enum for any run-time determination of the ISA, we 432 # reuse the same name as the namespaces 433 code('enum class GPUArch {') 434 for i,isa in enumerate(isas): 435 if i + 1 == len(isas): 436 code(' $0 = $1', namespace(isa), define(isa)) 437 else: 438 code(' $0 = $1,', namespace(isa), define(isa)) 439 code('};') 440 441 code(''' 442 443#define THE_GPU_ISA ${{define(target_gpu_isa)}} 444#define TheGpuISA ${{namespace(target_gpu_isa)}} 445#define THE_GPU_ISA_STR "${{target_gpu_isa}}" 446 447#endif // __CONFIG_THE_GPU_ISA_HH__''') 448 449 code.write(str(target[0])) 450 451env.Command('config/the_gpu_isa.hh', map(Value, all_gpu_isa_list), 452 MakeAction(makeTheGPUISA, Transform("CFG ISA", 0))) 453 454######################################################################## 455# 456# Prevent any SimObjects from being added after this point, they 457# should all have been added in the SConscripts above 458# 459SimObject.fixed = True 460 461class DictImporter(object): 462 '''This importer takes a dictionary of arbitrary module names that 463 map to arbitrary filenames.''' 464 def __init__(self, modules): 465 self.modules = modules 466 self.installed = set() 467 468 def __del__(self): 469 self.unload() 470 471 def unload(self): 472 import sys 473 for module in self.installed: 474 del sys.modules[module] 475 self.installed = set() 476 477 def find_module(self, fullname, path): 478 if fullname == 'm5.defines': 479 return self 480 481 if fullname == 'm5.objects': 482 return self 483 484 if fullname.startswith('_m5'): 485 return None 486 487 source = self.modules.get(fullname, None) 488 if source is not None and fullname.startswith('m5.objects'): 489 return self 490 491 return None 492 493 def load_module(self, fullname): 494 mod = imp.new_module(fullname) 495 sys.modules[fullname] = mod 496 self.installed.add(fullname) 497 498 mod.__loader__ = self 499 if fullname == 'm5.objects': 500 mod.__path__ = fullname.split('.') 501 return mod 502 503 if fullname == 'm5.defines': 504 mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env) 505 return mod 506 507 source = self.modules[fullname] 508 if source.modname == '__init__': 509 mod.__path__ = source.modpath 510 mod.__file__ = source.abspath 511 512 exec file(source.abspath, 'r') in mod.__dict__ 513 514 return mod 515 516import m5.SimObject 517import m5.params 518from m5.util import code_formatter 519 520m5.SimObject.clear() 521m5.params.clear() 522 523# install the python importer so we can grab stuff from the source 524# tree itself. We can't have SimObjects added after this point or 525# else we won't know about them for the rest of the stuff. 526importer = DictImporter(PySource.modules) 527sys.meta_path[0:0] = [ importer ] 528 529# import all sim objects so we can populate the all_objects list 530# make sure that we're working with a list, then let's sort it 531for modname in SimObject.modnames: 532 exec('from m5.objects import %s' % modname) 533 534# we need to unload all of the currently imported modules so that they 535# will be re-imported the next time the sconscript is run 536importer.unload() 537sys.meta_path.remove(importer) 538 539sim_objects = m5.SimObject.allClasses 540all_enums = m5.params.allEnums 541
|
562if m5.SimObject.noCxxHeader: 563 print >> sys.stderr, \ 564 "warning: At least one SimObject lacks a header specification. " \ 565 "This can cause unexpected results in the generated SWIG " \ 566 "wrappers." 567 568# Find param types that need to be explicitly wrapped with swig. 569# These will be recognized because the ParamDesc will have a 570# swig_decl() method. Most param types are based on types that don't 571# need this, either because they're based on native types (like Int) 572# or because they're SimObjects (which get swigged independently). 573# For now the only things handled here are VectorParam types. 574params_to_swig = {}
| |
575for name,obj in sorted(sim_objects.iteritems()): 576 for param in obj._params.local.values(): 577 # load the ptype attribute now because it depends on the 578 # current version of SimObject.allClasses, but when scons 579 # actually uses the value, all versions of 580 # SimObject.allClasses will have been loaded 581 param.ptype 582
| 542for name,obj in sorted(sim_objects.iteritems()): 543 for param in obj._params.local.values(): 544 # load the ptype attribute now because it depends on the 545 # current version of SimObject.allClasses, but when scons 546 # actually uses the value, all versions of 547 # SimObject.allClasses will have been loaded 548 param.ptype 549
|
583 if not hasattr(param, 'swig_decl'): 584 continue 585 pname = param.ptype_str 586 if pname not in params_to_swig: 587 params_to_swig[pname] = param 588
| |
589######################################################################## 590# 591# calculate extra dependencies 592# 593module_depends = ["m5", "m5.SimObject", "m5.params"] 594depends = [ PySource.modules[dep].snode for dep in module_depends ] 595depends.sort(key = lambda x: x.name) 596 597######################################################################## 598# 599# Commands for the basic automatically generated python files 600# 601 602# Generate Python file containing a dict specifying the current 603# buildEnv flags. 604def makeDefinesPyFile(target, source, env): 605 build_env = source[0].get_contents() 606 607 code = code_formatter() 608 code(""" 609import _m5.core 610import m5.util 611 612buildEnv = m5.util.SmartDict($build_env) 613 614compileDate = _m5.core.compileDate 615_globals = globals() 616for key,val in _m5.core.__dict__.iteritems(): 617 if key.startswith('flag_'): 618 flag = key[5:] 619 _globals[flag] = val 620del _globals 621""") 622 code.write(target[0].abspath) 623 624defines_info = Value(build_env) 625# Generate a file with all of the compile options in it 626env.Command('python/m5/defines.py', defines_info, 627 MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 628PySource('m5', 'python/m5/defines.py') 629 630# Generate python file containing info about the M5 source code 631def makeInfoPyFile(target, source, env): 632 code = code_formatter() 633 for src in source: 634 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 635 code('$src = ${{repr(data)}}') 636 code.write(str(target[0])) 637 638# Generate a file that wraps the basic top level files 639env.Command('python/m5/info.py', 640 [ '#/COPYING', '#/LICENSE', '#/README', ], 641 MakeAction(makeInfoPyFile, Transform("INFO"))) 642PySource('m5', 'python/m5/info.py') 643 644######################################################################## 645# 646# Create all of the SimObject param headers and enum headers 647# 648 649def createSimObjectParamStruct(target, source, env): 650 assert len(target) == 1 and len(source) == 1 651 652 name = str(source[0].get_contents()) 653 obj = sim_objects[name] 654 655 code = code_formatter() 656 obj.cxx_param_decl(code) 657 code.write(target[0].abspath) 658 659def createSimObjectCxxConfig(is_header): 660 def body(target, source, env): 661 assert len(target) == 1 and len(source) == 1 662 663 name = str(source[0].get_contents()) 664 obj = sim_objects[name] 665 666 code = code_formatter() 667 obj.cxx_config_param_file(code, is_header) 668 code.write(target[0].abspath) 669 return body 670
| 550######################################################################## 551# 552# calculate extra dependencies 553# 554module_depends = ["m5", "m5.SimObject", "m5.params"] 555depends = [ PySource.modules[dep].snode for dep in module_depends ] 556depends.sort(key = lambda x: x.name) 557 558######################################################################## 559# 560# Commands for the basic automatically generated python files 561# 562 563# Generate Python file containing a dict specifying the current 564# buildEnv flags. 565def makeDefinesPyFile(target, source, env): 566 build_env = source[0].get_contents() 567 568 code = code_formatter() 569 code(""" 570import _m5.core 571import m5.util 572 573buildEnv = m5.util.SmartDict($build_env) 574 575compileDate = _m5.core.compileDate 576_globals = globals() 577for key,val in _m5.core.__dict__.iteritems(): 578 if key.startswith('flag_'): 579 flag = key[5:] 580 _globals[flag] = val 581del _globals 582""") 583 code.write(target[0].abspath) 584 585defines_info = Value(build_env) 586# Generate a file with all of the compile options in it 587env.Command('python/m5/defines.py', defines_info, 588 MakeAction(makeDefinesPyFile, Transform("DEFINES", 0))) 589PySource('m5', 'python/m5/defines.py') 590 591# Generate python file containing info about the M5 source code 592def makeInfoPyFile(target, source, env): 593 code = code_formatter() 594 for src in source: 595 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 596 code('$src = ${{repr(data)}}') 597 code.write(str(target[0])) 598 599# Generate a file that wraps the basic top level files 600env.Command('python/m5/info.py', 601 [ '#/COPYING', '#/LICENSE', '#/README', ], 602 MakeAction(makeInfoPyFile, Transform("INFO"))) 603PySource('m5', 'python/m5/info.py') 604 605######################################################################## 606# 607# Create all of the SimObject param headers and enum headers 608# 609 610def createSimObjectParamStruct(target, source, env): 611 assert len(target) == 1 and len(source) == 1 612 613 name = str(source[0].get_contents()) 614 obj = sim_objects[name] 615 616 code = code_formatter() 617 obj.cxx_param_decl(code) 618 code.write(target[0].abspath) 619 620def createSimObjectCxxConfig(is_header): 621 def body(target, source, env): 622 assert len(target) == 1 and len(source) == 1 623 624 name = str(source[0].get_contents()) 625 obj = sim_objects[name] 626 627 code = code_formatter() 628 obj.cxx_config_param_file(code, is_header) 629 code.write(target[0].abspath) 630 return body 631
|
671def createParamSwigWrapper(target, source, env): 672 assert len(target) == 1 and len(source) == 1 673 674 name = str(source[0].get_contents()) 675 param = params_to_swig[name] 676 677 code = code_formatter() 678 param.swig_decl(code) 679 code.write(target[0].abspath) 680
| |
681def createEnumStrings(target, source, env): 682 assert len(target) == 1 and len(source) == 1 683 684 name = str(source[0].get_contents()) 685 obj = all_enums[name] 686 687 code = code_formatter() 688 obj.cxx_def(code)
| 632def createEnumStrings(target, source, env): 633 assert len(target) == 1 and len(source) == 1 634 635 name = str(source[0].get_contents()) 636 obj = all_enums[name] 637 638 code = code_formatter() 639 obj.cxx_def(code)
|
| 640 if env['USE_PYTHON']: 641 obj.pybind_def(code)
|
689 code.write(target[0].abspath) 690 691def createEnumDecls(target, source, env): 692 assert len(target) == 1 and len(source) == 1 693 694 name = str(source[0].get_contents()) 695 obj = all_enums[name] 696 697 code = code_formatter() 698 obj.cxx_decl(code) 699 code.write(target[0].abspath) 700
| 642 code.write(target[0].abspath) 643 644def createEnumDecls(target, source, env): 645 assert len(target) == 1 and len(source) == 1 646 647 name = str(source[0].get_contents()) 648 obj = all_enums[name] 649 650 code = code_formatter() 651 obj.cxx_decl(code) 652 code.write(target[0].abspath) 653
|
701def createEnumSwigWrapper(target, source, env): 702 assert len(target) == 1 and len(source) == 1 703 704 name = str(source[0].get_contents()) 705 obj = all_enums[name] 706 707 code = code_formatter() 708 obj.swig_decl(code) 709 code.write(target[0].abspath) 710 711def createSimObjectSwigWrapper(target, source, env):
| 654def createSimObjectPyBindWrapper(target, source, env):
|
712 name = source[0].get_contents() 713 obj = sim_objects[name] 714 715 code = code_formatter()
| 655 name = source[0].get_contents() 656 obj = sim_objects[name] 657 658 code = code_formatter()
|
716 obj.swig_decl(code)
| 659 obj.pybind_decl(code)
|
717 code.write(target[0].abspath) 718
| 660 code.write(target[0].abspath) 661
|
719# dummy target for generated code 720# we start out with all the Source files so they get copied to build/*/ also. 721SWIG = env.Dummy('swig', [s.tnode for s in Source.get()]) 722
| |
723# Generate all of the SimObject param C++ struct header files 724params_hh_files = [] 725for name,simobj in sorted(sim_objects.iteritems()): 726 py_source = PySource.modules[simobj.__module__] 727 extra_deps = [ py_source.tnode ] 728 729 hh_file = File('params/%s.hh' % name) 730 params_hh_files.append(hh_file) 731 env.Command(hh_file, Value(name), 732 MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 733 env.Depends(hh_file, depends + extra_deps)
| 662# Generate all of the SimObject param C++ struct header files 663params_hh_files = [] 664for name,simobj in sorted(sim_objects.iteritems()): 665 py_source = PySource.modules[simobj.__module__] 666 extra_deps = [ py_source.tnode ] 667 668 hh_file = File('params/%s.hh' % name) 669 params_hh_files.append(hh_file) 670 env.Command(hh_file, Value(name), 671 MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) 672 env.Depends(hh_file, depends + extra_deps)
|
734 env.Depends(SWIG, hh_file)
| |
735 736# C++ parameter description files 737if GetOption('with_cxx_config'): 738 for name,simobj in sorted(sim_objects.iteritems()): 739 py_source = PySource.modules[simobj.__module__] 740 extra_deps = [ py_source.tnode ] 741 742 cxx_config_hh_file = File('cxx_config/%s.hh' % name) 743 cxx_config_cc_file = File('cxx_config/%s.cc' % name) 744 env.Command(cxx_config_hh_file, Value(name), 745 MakeAction(createSimObjectCxxConfig(True), 746 Transform("CXXCPRHH"))) 747 env.Command(cxx_config_cc_file, Value(name), 748 MakeAction(createSimObjectCxxConfig(False), 749 Transform("CXXCPRCC"))) 750 env.Depends(cxx_config_hh_file, depends + extra_deps + 751 [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 752 env.Depends(cxx_config_cc_file, depends + extra_deps + 753 [cxx_config_hh_file]) 754 Source(cxx_config_cc_file) 755 756 cxx_config_init_cc_file = File('cxx_config/init.cc') 757 758 def createCxxConfigInitCC(target, source, env): 759 assert len(target) == 1 and len(source) == 1 760 761 code = code_formatter() 762 763 for name,simobj in sorted(sim_objects.iteritems()): 764 if not hasattr(simobj, 'abstract') or not simobj.abstract: 765 code('#include "cxx_config/${name}.hh"') 766 code() 767 code('void cxxConfigInit()') 768 code('{') 769 code.indent() 770 for name,simobj in sorted(sim_objects.iteritems()): 771 not_abstract = not hasattr(simobj, 'abstract') or \ 772 not simobj.abstract 773 if not_abstract and 'type' in simobj.__dict__: 774 code('cxx_config_directory["${name}"] = ' 775 '${name}CxxConfigParams::makeDirectoryEntry();') 776 code.dedent() 777 code('}') 778 code.write(target[0].abspath) 779 780 py_source = PySource.modules[simobj.__module__] 781 extra_deps = [ py_source.tnode ] 782 env.Command(cxx_config_init_cc_file, Value(name), 783 MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 784 cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 785 for name,simobj in sorted(sim_objects.iteritems()) 786 if not hasattr(simobj, 'abstract') or not simobj.abstract] 787 Depends(cxx_config_init_cc_file, cxx_param_hh_files + 788 [File('sim/cxx_config.hh')]) 789 Source(cxx_config_init_cc_file) 790
| 673 674# C++ parameter description files 675if GetOption('with_cxx_config'): 676 for name,simobj in sorted(sim_objects.iteritems()): 677 py_source = PySource.modules[simobj.__module__] 678 extra_deps = [ py_source.tnode ] 679 680 cxx_config_hh_file = File('cxx_config/%s.hh' % name) 681 cxx_config_cc_file = File('cxx_config/%s.cc' % name) 682 env.Command(cxx_config_hh_file, Value(name), 683 MakeAction(createSimObjectCxxConfig(True), 684 Transform("CXXCPRHH"))) 685 env.Command(cxx_config_cc_file, Value(name), 686 MakeAction(createSimObjectCxxConfig(False), 687 Transform("CXXCPRCC"))) 688 env.Depends(cxx_config_hh_file, depends + extra_deps + 689 [File('params/%s.hh' % name), File('sim/cxx_config.hh')]) 690 env.Depends(cxx_config_cc_file, depends + extra_deps + 691 [cxx_config_hh_file]) 692 Source(cxx_config_cc_file) 693 694 cxx_config_init_cc_file = File('cxx_config/init.cc') 695 696 def createCxxConfigInitCC(target, source, env): 697 assert len(target) == 1 and len(source) == 1 698 699 code = code_formatter() 700 701 for name,simobj in sorted(sim_objects.iteritems()): 702 if not hasattr(simobj, 'abstract') or not simobj.abstract: 703 code('#include "cxx_config/${name}.hh"') 704 code() 705 code('void cxxConfigInit()') 706 code('{') 707 code.indent() 708 for name,simobj in sorted(sim_objects.iteritems()): 709 not_abstract = not hasattr(simobj, 'abstract') or \ 710 not simobj.abstract 711 if not_abstract and 'type' in simobj.__dict__: 712 code('cxx_config_directory["${name}"] = ' 713 '${name}CxxConfigParams::makeDirectoryEntry();') 714 code.dedent() 715 code('}') 716 code.write(target[0].abspath) 717 718 py_source = PySource.modules[simobj.__module__] 719 extra_deps = [ py_source.tnode ] 720 env.Command(cxx_config_init_cc_file, Value(name), 721 MakeAction(createCxxConfigInitCC, Transform("CXXCINIT"))) 722 cxx_param_hh_files = ["cxx_config/%s.hh" % simobj 723 for name,simobj in sorted(sim_objects.iteritems()) 724 if not hasattr(simobj, 'abstract') or not simobj.abstract] 725 Depends(cxx_config_init_cc_file, cxx_param_hh_files + 726 [File('sim/cxx_config.hh')]) 727 Source(cxx_config_init_cc_file) 728
|
791# Generate any needed param SWIG wrapper files 792params_i_files = [] 793for name,param in sorted(params_to_swig.iteritems()): 794 i_file = File('python/_m5/%s.i' % (param.swig_module_name())) 795 params_i_files.append(i_file) 796 env.Command(i_file, Value(name), 797 MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) 798 env.Depends(i_file, depends) 799 env.Depends(SWIG, i_file) 800 SwigSource('_m5', i_file) 801
| |
802# Generate all enum header files 803for name,enum in sorted(all_enums.iteritems()): 804 py_source = PySource.modules[enum.__module__] 805 extra_deps = [ py_source.tnode ] 806 807 cc_file = File('enums/%s.cc' % name) 808 env.Command(cc_file, Value(name), 809 MakeAction(createEnumStrings, Transform("ENUM STR"))) 810 env.Depends(cc_file, depends + extra_deps)
| 729# Generate all enum header files 730for name,enum in sorted(all_enums.iteritems()): 731 py_source = PySource.modules[enum.__module__] 732 extra_deps = [ py_source.tnode ] 733 734 cc_file = File('enums/%s.cc' % name) 735 env.Command(cc_file, Value(name), 736 MakeAction(createEnumStrings, Transform("ENUM STR"))) 737 env.Depends(cc_file, depends + extra_deps)
|
811 env.Depends(SWIG, cc_file)
| |
812 Source(cc_file) 813 814 hh_file = File('enums/%s.hh' % name) 815 env.Command(hh_file, Value(name), 816 MakeAction(createEnumDecls, Transform("ENUMDECL"))) 817 env.Depends(hh_file, depends + extra_deps)
| 738 Source(cc_file) 739 740 hh_file = File('enums/%s.hh' % name) 741 env.Command(hh_file, Value(name), 742 MakeAction(createEnumDecls, Transform("ENUMDECL"))) 743 env.Depends(hh_file, depends + extra_deps)
|
818 env.Depends(SWIG, hh_file)
| |
819
| 744
|
820 i_file = File('python/_m5/enum_%s.i' % name) 821 env.Command(i_file, Value(name), 822 MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) 823 env.Depends(i_file, depends + extra_deps) 824 env.Depends(SWIG, i_file) 825 SwigSource('_m5', i_file)
| 745# Generate SimObject Python bindings wrapper files 746if env['USE_PYTHON']: 747 for name,simobj in sorted(sim_objects.iteritems()): 748 py_source = PySource.modules[simobj.__module__] 749 extra_deps = [ py_source.tnode ] 750 cc_file = File('python/_m5/param_%s.cc' % name) 751 env.Command(cc_file, Value(name), 752 MakeAction(createSimObjectPyBindWrapper, 753 Transform("SO PyBind"))) 754 env.Depends(cc_file, depends + extra_deps) 755 Source(cc_file)
|
826
| 756
|
827# Generate SimObject SWIG wrapper files 828for name,simobj in sorted(sim_objects.iteritems()): 829 py_source = PySource.modules[simobj.__module__] 830 extra_deps = [ py_source.tnode ] 831 i_file = File('python/_m5/param_%s.i' % name) 832 env.Command(i_file, Value(name), 833 MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) 834 env.Depends(i_file, depends + extra_deps) 835 SwigSource('_m5', i_file) 836 837# Generate the main swig init file 838def makeEmbeddedSwigInit(package): 839 def body(target, source, env): 840 assert len(target) == 1 and len(source) == 1 841 842 code = code_formatter() 843 module = source[0].get_contents() 844 # Provide the full context so that the swig-generated call to 845 # Py_InitModule ends up placing the embedded module in the 846 # right package. 847 context = str(package) + "._" + str(module) 848 code('''\ 849 #include "sim/init.hh" 850 851 extern "C" { 852 void init_${module}(); 853 } 854 855 EmbeddedSwig embed_swig_${module}(init_${module}, "${context}"); 856 ''') 857 code.write(str(target[0])) 858 return body 859 860# Build all swig modules 861for swig in SwigSource.all: 862 env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode, 863 MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 864 '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) 865 cc_file = str(swig.tnode) 866 init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) 867 env.Command(init_file, Value(swig.module), 868 MakeAction(makeEmbeddedSwigInit(swig.package), 869 Transform("EMBED SW"))) 870 env.Depends(SWIG, init_file) 871 Source(init_file, **swig.guards) 872
| |
873# Build all protocol buffers if we have got protoc and protobuf available 874if env['HAVE_PROTOBUF']: 875 for proto in ProtoBuf.all: 876 # Use both the source and header as the target, and the .proto 877 # file as the source. When executing the protoc compiler, also 878 # specify the proto_path to avoid having the generated files 879 # include the path. 880 env.Command([proto.cc_file, proto.hh_file], proto.tnode, 881 MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 882 '--proto_path ${SOURCE.dir} $SOURCE', 883 Transform("PROTOC"))) 884
| 757# Build all protocol buffers if we have got protoc and protobuf available 758if env['HAVE_PROTOBUF']: 759 for proto in ProtoBuf.all: 760 # Use both the source and header as the target, and the .proto 761 # file as the source. When executing the protoc compiler, also 762 # specify the proto_path to avoid having the generated files 763 # include the path. 764 env.Command([proto.cc_file, proto.hh_file], proto.tnode, 765 MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 766 '--proto_path ${SOURCE.dir} $SOURCE', 767 Transform("PROTOC"))) 768
|
885 env.Depends(SWIG, [proto.cc_file, proto.hh_file])
| |
886 # Add the C++ source file 887 Source(proto.cc_file, **proto.guards) 888elif ProtoBuf.all: 889 print 'Got protobuf to build, but lacks support!' 890 Exit(1) 891 892# 893# Handle debug flags 894# 895def makeDebugFlagCC(target, source, env): 896 assert(len(target) == 1 and len(source) == 1) 897 898 code = code_formatter() 899 900 # delay definition of CompoundFlags until after all the definition 901 # of all constituent SimpleFlags 902 comp_code = code_formatter() 903 904 # file header 905 code(''' 906/* 907 * DO NOT EDIT THIS FILE! Automatically generated by SCons. 908 */ 909 910#include "base/debug.hh" 911 912namespace Debug { 913 914''') 915 916 for name, flag in sorted(source[0].read().iteritems()): 917 n, compound, desc = flag 918 assert n == name 919 920 if not compound: 921 code('SimpleFlag $name("$name", "$desc");') 922 else: 923 comp_code('CompoundFlag $name("$name", "$desc",') 924 comp_code.indent() 925 last = len(compound) - 1 926 for i,flag in enumerate(compound): 927 if i != last: 928 comp_code('&$flag,') 929 else: 930 comp_code('&$flag);') 931 comp_code.dedent() 932 933 code.append(comp_code) 934 code() 935 code('} // namespace Debug') 936 937 code.write(str(target[0])) 938 939def makeDebugFlagHH(target, source, env): 940 assert(len(target) == 1 and len(source) == 1) 941 942 val = eval(source[0].get_contents()) 943 name, compound, desc = val 944 945 code = code_formatter() 946 947 # file header boilerplate 948 code('''\ 949/* 950 * DO NOT EDIT THIS FILE! Automatically generated by SCons. 951 */ 952 953#ifndef __DEBUG_${name}_HH__ 954#define __DEBUG_${name}_HH__ 955 956namespace Debug { 957''') 958 959 if compound: 960 code('class CompoundFlag;') 961 code('class SimpleFlag;') 962 963 if compound: 964 code('extern CompoundFlag $name;') 965 for flag in compound: 966 code('extern SimpleFlag $flag;') 967 else: 968 code('extern SimpleFlag $name;') 969 970 code(''' 971} 972 973#endif // __DEBUG_${name}_HH__ 974''') 975 976 code.write(str(target[0])) 977 978for name,flag in sorted(debug_flags.iteritems()): 979 n, compound, desc = flag 980 assert n == name 981 982 hh_file = 'debug/%s.hh' % name 983 env.Command(hh_file, Value(flag), 984 MakeAction(makeDebugFlagHH, Transform("TRACING", 0)))
| 769 # Add the C++ source file 770 Source(proto.cc_file, **proto.guards) 771elif ProtoBuf.all: 772 print 'Got protobuf to build, but lacks support!' 773 Exit(1) 774 775# 776# Handle debug flags 777# 778def makeDebugFlagCC(target, source, env): 779 assert(len(target) == 1 and len(source) == 1) 780 781 code = code_formatter() 782 783 # delay definition of CompoundFlags until after all the definition 784 # of all constituent SimpleFlags 785 comp_code = code_formatter() 786 787 # file header 788 code(''' 789/* 790 * DO NOT EDIT THIS FILE! Automatically generated by SCons. 791 */ 792 793#include "base/debug.hh" 794 795namespace Debug { 796 797''') 798 799 for name, flag in sorted(source[0].read().iteritems()): 800 n, compound, desc = flag 801 assert n == name 802 803 if not compound: 804 code('SimpleFlag $name("$name", "$desc");') 805 else: 806 comp_code('CompoundFlag $name("$name", "$desc",') 807 comp_code.indent() 808 last = len(compound) - 1 809 for i,flag in enumerate(compound): 810 if i != last: 811 comp_code('&$flag,') 812 else: 813 comp_code('&$flag);') 814 comp_code.dedent() 815 816 code.append(comp_code) 817 code() 818 code('} // namespace Debug') 819 820 code.write(str(target[0])) 821 822def makeDebugFlagHH(target, source, env): 823 assert(len(target) == 1 and len(source) == 1) 824 825 val = eval(source[0].get_contents()) 826 name, compound, desc = val 827 828 code = code_formatter() 829 830 # file header boilerplate 831 code('''\ 832/* 833 * DO NOT EDIT THIS FILE! Automatically generated by SCons. 834 */ 835 836#ifndef __DEBUG_${name}_HH__ 837#define __DEBUG_${name}_HH__ 838 839namespace Debug { 840''') 841 842 if compound: 843 code('class CompoundFlag;') 844 code('class SimpleFlag;') 845 846 if compound: 847 code('extern CompoundFlag $name;') 848 for flag in compound: 849 code('extern SimpleFlag $flag;') 850 else: 851 code('extern SimpleFlag $name;') 852 853 code(''' 854} 855 856#endif // __DEBUG_${name}_HH__ 857''') 858 859 code.write(str(target[0])) 860 861for name,flag in sorted(debug_flags.iteritems()): 862 n, compound, desc = flag 863 assert n == name 864 865 hh_file = 'debug/%s.hh' % name 866 env.Command(hh_file, Value(flag), 867 MakeAction(makeDebugFlagHH, Transform("TRACING", 0)))
|
985 env.Depends(SWIG, hh_file)
| |
986 987env.Command('debug/flags.cc', Value(debug_flags), 988 MakeAction(makeDebugFlagCC, Transform("TRACING", 0)))
| 868 869env.Command('debug/flags.cc', Value(debug_flags), 870 MakeAction(makeDebugFlagCC, Transform("TRACING", 0)))
|
989env.Depends(SWIG, 'debug/flags.cc')
| |
990Source('debug/flags.cc') 991 992# version tags 993tags = \ 994env.Command('sim/tags.cc', None, 995 MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 996 Transform("VER TAGS"))) 997env.AlwaysBuild(tags) 998 999# Embed python files. All .py files that have been indicated by a 1000# PySource() call in a SConscript need to be embedded into the M5 1001# library. To do that, we compile the file to byte code, marshal the 1002# byte code, compress it, and then generate a c++ file that 1003# inserts the result into an array. 1004def embedPyFile(target, source, env): 1005 def c_str(string): 1006 if string is None: 1007 return "0" 1008 return '"%s"' % string 1009 1010 '''Action function to compile a .py into a code object, marshal 1011 it, compress it, and stick it into an asm file so the code appears 1012 as just bytes with a label in the data section''' 1013 1014 src = file(str(source[0]), 'r').read() 1015 1016 pysource = PySource.tnodes[source[0]] 1017 compiled = compile(src, pysource.abspath, 'exec') 1018 marshalled = marshal.dumps(compiled) 1019 compressed = zlib.compress(marshalled) 1020 data = compressed 1021 sym = pysource.symname 1022 1023 code = code_formatter() 1024 code('''\ 1025#include "sim/init.hh" 1026 1027namespace { 1028 1029const uint8_t data_${sym}[] = { 1030''') 1031 code.indent() 1032 step = 16 1033 for i in xrange(0, len(data), step): 1034 x = array.array('B', data[i:i+step]) 1035 code(''.join('%d,' % d for d in x)) 1036 code.dedent() 1037 1038 code('''}; 1039 1040EmbeddedPython embedded_${sym}( 1041 ${{c_str(pysource.arcname)}}, 1042 ${{c_str(pysource.abspath)}}, 1043 ${{c_str(pysource.modpath)}}, 1044 data_${sym}, 1045 ${{len(data)}}, 1046 ${{len(marshalled)}}); 1047 1048} // anonymous namespace 1049''') 1050 code.write(str(target[0])) 1051 1052for source in PySource.all: 1053 env.Command(source.cpp, source.tnode, 1054 MakeAction(embedPyFile, Transform("EMBED PY")))
| 871Source('debug/flags.cc') 872 873# version tags 874tags = \ 875env.Command('sim/tags.cc', None, 876 MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET', 877 Transform("VER TAGS"))) 878env.AlwaysBuild(tags) 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 a c++ file that 884# inserts the result into an array. 885def embedPyFile(target, source, env): 886 def c_str(string): 887 if string is None: 888 return "0" 889 return '"%s"' % string 890 891 '''Action function to compile a .py into a code object, marshal 892 it, compress it, and stick it into an asm file so the code appears 893 as just bytes with a label in the data section''' 894 895 src = file(str(source[0]), 'r').read() 896 897 pysource = PySource.tnodes[source[0]] 898 compiled = compile(src, pysource.abspath, 'exec') 899 marshalled = marshal.dumps(compiled) 900 compressed = zlib.compress(marshalled) 901 data = compressed 902 sym = pysource.symname 903 904 code = code_formatter() 905 code('''\ 906#include "sim/init.hh" 907 908namespace { 909 910const uint8_t data_${sym}[] = { 911''') 912 code.indent() 913 step = 16 914 for i in xrange(0, len(data), step): 915 x = array.array('B', data[i:i+step]) 916 code(''.join('%d,' % d for d in x)) 917 code.dedent() 918 919 code('''}; 920 921EmbeddedPython embedded_${sym}( 922 ${{c_str(pysource.arcname)}}, 923 ${{c_str(pysource.abspath)}}, 924 ${{c_str(pysource.modpath)}}, 925 data_${sym}, 926 ${{len(data)}}, 927 ${{len(marshalled)}}); 928 929} // anonymous namespace 930''') 931 code.write(str(target[0])) 932 933for source in PySource.all: 934 env.Command(source.cpp, source.tnode, 935 MakeAction(embedPyFile, Transform("EMBED PY")))
|
1055 env.Depends(SWIG, source.cpp)
| |
1056 Source(source.cpp, skip_no_python=True) 1057 1058######################################################################## 1059# 1060# Define binaries. Each different build type (debug, opt, etc.) gets 1061# a slightly different build environment. 1062# 1063 1064# List of constructed environments to pass back to SConstruct 1065date_source = Source('base/date.cc', skip_lib=True) 1066 1067# Capture this directory for the closure makeEnv, otherwise when it is 1068# called, it won't know what directory it should use. 1069variant_dir = Dir('.').path 1070def variant(*path): 1071 return os.path.join(variant_dir, *path) 1072def variantd(*path): 1073 return variant(*path)+'/' 1074 1075# Function to create a new build environment as clone of current 1076# environment 'env' with modified object suffix and optional stripped 1077# binary. Additional keyword arguments are appended to corresponding 1078# build environment vars. 1079def makeEnv(env, label, objsfx, strip = False, **kwargs): 1080 # SCons doesn't know to append a library suffix when there is a '.' in the 1081 # name. Use '_' instead. 1082 libname = variant('gem5_' + label) 1083 exename = variant('gem5.' + label) 1084 secondary_exename = variant('m5.' + label) 1085 1086 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 1087 new_env.Label = label 1088 new_env.Append(**kwargs) 1089
| 936 Source(source.cpp, skip_no_python=True) 937 938######################################################################## 939# 940# Define binaries. Each different build type (debug, opt, etc.) gets 941# a slightly different build environment. 942# 943 944# List of constructed environments to pass back to SConstruct 945date_source = Source('base/date.cc', skip_lib=True) 946 947# Capture this directory for the closure makeEnv, otherwise when it is 948# called, it won't know what directory it should use. 949variant_dir = Dir('.').path 950def variant(*path): 951 return os.path.join(variant_dir, *path) 952def variantd(*path): 953 return variant(*path)+'/' 954 955# Function to create a new build environment as clone of current 956# environment 'env' with modified object suffix and optional stripped 957# binary. Additional keyword arguments are appended to corresponding 958# build environment vars. 959def makeEnv(env, label, objsfx, strip = False, **kwargs): 960 # SCons doesn't know to append a library suffix when there is a '.' in the 961 # name. Use '_' instead. 962 libname = variant('gem5_' + label) 963 exename = variant('gem5.' + label) 964 secondary_exename = variant('m5.' + label) 965 966 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's') 967 new_env.Label = label 968 new_env.Append(**kwargs) 969
|
1090 swig_env = new_env.Clone() 1091 1092 # Both gcc and clang have issues with unused labels and values in 1093 # the SWIG generated code 1094 swig_env.Append(CCFLAGS=['-Wno-unused-label', '-Wno-unused-value']) 1095
| |
1096 if env['GCC']:
| 970 if env['GCC']:
|
1097 # Depending on the SWIG version, we also need to supress 1098 # warnings about uninitialized variables and missing field 1099 # initializers. 1100 swig_env.Append(CCFLAGS=['-Wno-uninitialized', 1101 '-Wno-missing-field-initializers', 1102 '-Wno-unused-but-set-variable', 1103 '-Wno-maybe-uninitialized', 1104 '-Wno-type-limits']) 1105 1106
| |
1107 # The address sanitizer is available for gcc >= 4.8 1108 if GetOption('with_asan'): 1109 if GetOption('with_ubsan') and \ 1110 compareVersions(env['GCC_VERSION'], '4.9') >= 0: 1111 new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 1112 '-fno-omit-frame-pointer']) 1113 new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 1114 else: 1115 new_env.Append(CCFLAGS=['-fsanitize=address', 1116 '-fno-omit-frame-pointer']) 1117 new_env.Append(LINKFLAGS='-fsanitize=address') 1118 # Only gcc >= 4.9 supports UBSan, so check both the version 1119 # and the command-line option before adding the compiler and 1120 # linker flags. 1121 elif GetOption('with_ubsan') and \ 1122 compareVersions(env['GCC_VERSION'], '4.9') >= 0: 1123 new_env.Append(CCFLAGS='-fsanitize=undefined') 1124 new_env.Append(LINKFLAGS='-fsanitize=undefined') 1125 1126 1127 if env['CLANG']:
| 971 # The address sanitizer is available for gcc >= 4.8 972 if GetOption('with_asan'): 973 if GetOption('with_ubsan') and \ 974 compareVersions(env['GCC_VERSION'], '4.9') >= 0: 975 new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 976 '-fno-omit-frame-pointer']) 977 new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 978 else: 979 new_env.Append(CCFLAGS=['-fsanitize=address', 980 '-fno-omit-frame-pointer']) 981 new_env.Append(LINKFLAGS='-fsanitize=address') 982 # Only gcc >= 4.9 supports UBSan, so check both the version 983 # and the command-line option before adding the compiler and 984 # linker flags. 985 elif GetOption('with_ubsan') and \ 986 compareVersions(env['GCC_VERSION'], '4.9') >= 0: 987 new_env.Append(CCFLAGS='-fsanitize=undefined') 988 new_env.Append(LINKFLAGS='-fsanitize=undefined') 989 990 991 if env['CLANG']:
|
1128 swig_env.Append(CCFLAGS=['-Wno-sometimes-uninitialized', 1129 '-Wno-deprecated-register', 1130 '-Wno-tautological-compare']) 1131
| |
1132 # We require clang >= 3.1, so there is no need to check any 1133 # versions here. 1134 if GetOption('with_ubsan'): 1135 if GetOption('with_asan'): 1136 new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 1137 '-fno-omit-frame-pointer']) 1138 new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 1139 else: 1140 new_env.Append(CCFLAGS='-fsanitize=undefined') 1141 new_env.Append(LINKFLAGS='-fsanitize=undefined') 1142 1143 elif GetOption('with_asan'): 1144 new_env.Append(CCFLAGS=['-fsanitize=address', 1145 '-fno-omit-frame-pointer']) 1146 new_env.Append(LINKFLAGS='-fsanitize=address') 1147 1148 werror_env = new_env.Clone() 1149 # Treat warnings as errors but white list some warnings that we 1150 # want to allow (e.g., deprecation warnings). 1151 werror_env.Append(CCFLAGS=['-Werror', 1152 '-Wno-error=deprecated-declarations', 1153 '-Wno-error=deprecated', 1154 ]) 1155 1156 def make_obj(source, static, extra_deps = None): 1157 '''This function adds the specified source to the correct 1158 build environment, and returns the corresponding SCons Object 1159 nodes''' 1160
| 992 # We require clang >= 3.1, so there is no need to check any 993 # versions here. 994 if GetOption('with_ubsan'): 995 if GetOption('with_asan'): 996 new_env.Append(CCFLAGS=['-fsanitize=address,undefined', 997 '-fno-omit-frame-pointer']) 998 new_env.Append(LINKFLAGS='-fsanitize=address,undefined') 999 else: 1000 new_env.Append(CCFLAGS='-fsanitize=undefined') 1001 new_env.Append(LINKFLAGS='-fsanitize=undefined') 1002 1003 elif GetOption('with_asan'): 1004 new_env.Append(CCFLAGS=['-fsanitize=address', 1005 '-fno-omit-frame-pointer']) 1006 new_env.Append(LINKFLAGS='-fsanitize=address') 1007 1008 werror_env = new_env.Clone() 1009 # Treat warnings as errors but white list some warnings that we 1010 # want to allow (e.g., deprecation warnings). 1011 werror_env.Append(CCFLAGS=['-Werror', 1012 '-Wno-error=deprecated-declarations', 1013 '-Wno-error=deprecated', 1014 ]) 1015 1016 def make_obj(source, static, extra_deps = None): 1017 '''This function adds the specified source to the correct 1018 build environment, and returns the corresponding SCons Object 1019 nodes''' 1020
|
1161 if source.swig: 1162 env = swig_env 1163 elif source.Werror:
| 1021 if source.Werror:
|
1164 env = werror_env 1165 else: 1166 env = new_env 1167 1168 if static: 1169 obj = env.StaticObject(source.tnode) 1170 else: 1171 obj = env.SharedObject(source.tnode) 1172 1173 if extra_deps: 1174 env.Depends(obj, extra_deps) 1175 1176 return obj 1177 1178 lib_guards = {'main': False, 'skip_lib': False} 1179
| 1022 env = werror_env 1023 else: 1024 env = new_env 1025 1026 if static: 1027 obj = env.StaticObject(source.tnode) 1028 else: 1029 obj = env.SharedObject(source.tnode) 1030 1031 if extra_deps: 1032 env.Depends(obj, extra_deps) 1033 1034 return obj 1035 1036 lib_guards = {'main': False, 'skip_lib': False} 1037
|
1180 # Without Python, leave out all SWIG and Python content from the 1181 # library builds. The option doesn't affect gem5 built as a program
| 1038 # Without Python, leave out all Python content from the library 1039 # builds. The option doesn't affect gem5 built as a program
|
1182 if GetOption('without_python'): 1183 lib_guards['skip_no_python'] = False 1184 1185 static_objs = [] 1186 shared_objs = [] 1187 for s in guarded_source_iterator(Source.source_groups[None], **lib_guards): 1188 static_objs.append(make_obj(s, True)) 1189 shared_objs.append(make_obj(s, False)) 1190 1191 partial_objs = [] 1192 for group, all_srcs in Source.source_groups.iteritems(): 1193 # If these are the ungrouped source files, skip them. 1194 if not group: 1195 continue 1196 1197 # Get a list of the source files compatible with the current guards. 1198 srcs = [ s for s in guarded_source_iterator(all_srcs, **lib_guards) ] 1199 # If there aren't any left, skip this group. 1200 if not srcs: 1201 continue 1202 1203 # Set up the static partially linked objects. 1204 source_objs = [ make_obj(s, True) for s in srcs ] 1205 file_name = new_env.subst("${OBJPREFIX}lib${OBJSUFFIX}.partial") 1206 target = File(joinpath(group, file_name)) 1207 partial = env.PartialStatic(target=target, source=source_objs) 1208 static_objs.append(partial) 1209 1210 # Set up the shared partially linked objects. 1211 source_objs = [ make_obj(s, False) for s in srcs ] 1212 file_name = new_env.subst("${SHOBJPREFIX}lib${SHOBJSUFFIX}.partial") 1213 target = File(joinpath(group, file_name)) 1214 partial = env.PartialShared(target=target, source=source_objs) 1215 shared_objs.append(partial) 1216 1217 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 1218 static_objs.append(static_date) 1219 1220 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 1221 shared_objs.append(shared_date) 1222 1223 # First make a library of everything but main() so other programs can 1224 # link against m5. 1225 static_lib = new_env.StaticLibrary(libname, static_objs) 1226 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1227 1228 # Now link a stub with main() and the static library. 1229 main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 1230 1231 for test in UnitTest.all: 1232 flags = { test.target : True } 1233 test_sources = Source.get(**flags) 1234 test_objs = [ make_obj(s, static=True) for s in test_sources ] 1235 if test.main: 1236 test_objs += main_objs 1237 path = variant('unittest/%s.%s' % (test.target, label)) 1238 new_env.Program(path, test_objs + static_objs) 1239 1240 progname = exename 1241 if strip: 1242 progname += '.unstripped' 1243 1244 targets = new_env.Program(progname, main_objs + static_objs) 1245 1246 if strip: 1247 if sys.platform == 'sunos5': 1248 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1249 else: 1250 cmd = 'strip $SOURCE -o $TARGET' 1251 targets = new_env.Command(exename, progname, 1252 MakeAction(cmd, Transform("STRIP"))) 1253 1254 new_env.Command(secondary_exename, exename, 1255 MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 1256 1257 new_env.M5Binary = targets[0] 1258 return new_env 1259 1260# Start out with the compiler flags common to all compilers, 1261# i.e. they all use -g for opt and -g -pg for prof 1262ccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 1263 'perf' : ['-g']} 1264 1265# Start out with the linker flags common to all linkers, i.e. -pg for 1266# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 1267# no-as-needed and as-needed as the binutils linker is too clever and 1268# simply doesn't link to the library otherwise. 1269ldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 1270 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 1271 1272# For Link Time Optimization, the optimisation flags used to compile 1273# individual files are decoupled from those used at link time 1274# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 1275# to also update the linker flags based on the target. 1276if env['GCC']: 1277 if sys.platform == 'sunos5': 1278 ccflags['debug'] += ['-gstabs+'] 1279 else: 1280 ccflags['debug'] += ['-ggdb3'] 1281 ldflags['debug'] += ['-O0'] 1282 # opt, fast, prof and perf all share the same cc flags, also add 1283 # the optimization to the ldflags as LTO defers the optimization 1284 # to link time 1285 for target in ['opt', 'fast', 'prof', 'perf']: 1286 ccflags[target] += ['-O3'] 1287 ldflags[target] += ['-O3'] 1288 1289 ccflags['fast'] += env['LTO_CCFLAGS'] 1290 ldflags['fast'] += env['LTO_LDFLAGS'] 1291elif env['CLANG']: 1292 ccflags['debug'] += ['-g', '-O0'] 1293 # opt, fast, prof and perf all share the same cc flags 1294 for target in ['opt', 'fast', 'prof', 'perf']: 1295 ccflags[target] += ['-O3'] 1296else: 1297 print 'Unknown compiler, please fix compiler options' 1298 Exit(1) 1299 1300 1301# To speed things up, we only instantiate the build environments we 1302# need. We try to identify the needed environment for each target; if 1303# we can't, we fall back on instantiating all the environments just to 1304# be safe. 1305target_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 1306obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 1307 'gpo' : 'perf'} 1308 1309def identifyTarget(t): 1310 ext = t.split('.')[-1] 1311 if ext in target_types: 1312 return ext 1313 if obj2target.has_key(ext): 1314 return obj2target[ext] 1315 match = re.search(r'/tests/([^/]+)/', t) 1316 if match and match.group(1) in target_types: 1317 return match.group(1) 1318 return 'all' 1319 1320needed_envs = [identifyTarget(target) for target in BUILD_TARGETS] 1321if 'all' in needed_envs: 1322 needed_envs += target_types 1323 1324def makeEnvirons(target, source, env): 1325 # cause any later Source() calls to be fatal, as a diagnostic. 1326 Source.done() 1327 1328 envList = [] 1329 1330 # Debug binary 1331 if 'debug' in needed_envs: 1332 envList.append( 1333 makeEnv(env, 'debug', '.do', 1334 CCFLAGS = Split(ccflags['debug']), 1335 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 1336 LINKFLAGS = Split(ldflags['debug']))) 1337 1338 # Optimized binary 1339 if 'opt' in needed_envs: 1340 envList.append( 1341 makeEnv(env, 'opt', '.o', 1342 CCFLAGS = Split(ccflags['opt']), 1343 CPPDEFINES = ['TRACING_ON=1'], 1344 LINKFLAGS = Split(ldflags['opt']))) 1345 1346 # "Fast" binary 1347 if 'fast' in needed_envs: 1348 envList.append( 1349 makeEnv(env, 'fast', '.fo', strip = True, 1350 CCFLAGS = Split(ccflags['fast']), 1351 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1352 LINKFLAGS = Split(ldflags['fast']))) 1353 1354 # Profiled binary using gprof 1355 if 'prof' in needed_envs: 1356 envList.append( 1357 makeEnv(env, 'prof', '.po', 1358 CCFLAGS = Split(ccflags['prof']), 1359 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1360 LINKFLAGS = Split(ldflags['prof']))) 1361 1362 # Profiled binary using google-pprof 1363 if 'perf' in needed_envs: 1364 envList.append( 1365 makeEnv(env, 'perf', '.gpo', 1366 CCFLAGS = Split(ccflags['perf']), 1367 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1368 LINKFLAGS = Split(ldflags['perf']))) 1369 1370 # Set up the regression tests for each build. 1371 for e in envList: 1372 SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 1373 variant_dir = variantd('tests', e.Label), 1374 exports = { 'env' : e }, duplicate = False) 1375 1376# The MakeEnvirons Builder defers the full dependency collection until 1377# after processing the ISA definition (due to dynamically generated 1378# source files). Add this dependency to all targets so they will wait 1379# until the environments are completely set up. Otherwise, a second 1380# process (e.g. -j2 or higher) will try to compile the requested target, 1381# not know how, and fail. 1382env.Append(BUILDERS = {'MakeEnvirons' : 1383 Builder(action=MakeAction(makeEnvirons, 1384 Transform("ENVIRONS", 1)))}) 1385 1386isa_target = env['PHONY_BASE'] + '-deps' 1387environs = env['PHONY_BASE'] + '-environs' 1388env.Depends('#all-deps', isa_target) 1389env.Depends('#all-environs', environs) 1390env.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 1391envSetup = env.MakeEnvirons(environs, isa_target) 1392 1393# make sure no -deps targets occur before all ISAs are complete 1394env.Depends(isa_target, '#all-isas') 1395# likewise for -environs targets and all the -deps targets 1396env.Depends(environs, '#all-deps')
| 1040 if GetOption('without_python'): 1041 lib_guards['skip_no_python'] = False 1042 1043 static_objs = [] 1044 shared_objs = [] 1045 for s in guarded_source_iterator(Source.source_groups[None], **lib_guards): 1046 static_objs.append(make_obj(s, True)) 1047 shared_objs.append(make_obj(s, False)) 1048 1049 partial_objs = [] 1050 for group, all_srcs in Source.source_groups.iteritems(): 1051 # If these are the ungrouped source files, skip them. 1052 if not group: 1053 continue 1054 1055 # Get a list of the source files compatible with the current guards. 1056 srcs = [ s for s in guarded_source_iterator(all_srcs, **lib_guards) ] 1057 # If there aren't any left, skip this group. 1058 if not srcs: 1059 continue 1060 1061 # Set up the static partially linked objects. 1062 source_objs = [ make_obj(s, True) for s in srcs ] 1063 file_name = new_env.subst("${OBJPREFIX}lib${OBJSUFFIX}.partial") 1064 target = File(joinpath(group, file_name)) 1065 partial = env.PartialStatic(target=target, source=source_objs) 1066 static_objs.append(partial) 1067 1068 # Set up the shared partially linked objects. 1069 source_objs = [ make_obj(s, False) for s in srcs ] 1070 file_name = new_env.subst("${SHOBJPREFIX}lib${SHOBJSUFFIX}.partial") 1071 target = File(joinpath(group, file_name)) 1072 partial = env.PartialShared(target=target, source=source_objs) 1073 shared_objs.append(partial) 1074 1075 static_date = make_obj(date_source, static=True, extra_deps=static_objs) 1076 static_objs.append(static_date) 1077 1078 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs) 1079 shared_objs.append(shared_date) 1080 1081 # First make a library of everything but main() so other programs can 1082 # link against m5. 1083 static_lib = new_env.StaticLibrary(libname, static_objs) 1084 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1085 1086 # Now link a stub with main() and the static library. 1087 main_objs = [ make_obj(s, True) for s in Source.get(main=True) ] 1088 1089 for test in UnitTest.all: 1090 flags = { test.target : True } 1091 test_sources = Source.get(**flags) 1092 test_objs = [ make_obj(s, static=True) for s in test_sources ] 1093 if test.main: 1094 test_objs += main_objs 1095 path = variant('unittest/%s.%s' % (test.target, label)) 1096 new_env.Program(path, test_objs + static_objs) 1097 1098 progname = exename 1099 if strip: 1100 progname += '.unstripped' 1101 1102 targets = new_env.Program(progname, main_objs + static_objs) 1103 1104 if strip: 1105 if sys.platform == 'sunos5': 1106 cmd = 'cp $SOURCE $TARGET; strip $TARGET' 1107 else: 1108 cmd = 'strip $SOURCE -o $TARGET' 1109 targets = new_env.Command(exename, progname, 1110 MakeAction(cmd, Transform("STRIP"))) 1111 1112 new_env.Command(secondary_exename, exename, 1113 MakeAction('ln $SOURCE $TARGET', Transform("HARDLINK"))) 1114 1115 new_env.M5Binary = targets[0] 1116 return new_env 1117 1118# Start out with the compiler flags common to all compilers, 1119# i.e. they all use -g for opt and -g -pg for prof 1120ccflags = {'debug' : [], 'opt' : ['-g'], 'fast' : [], 'prof' : ['-g', '-pg'], 1121 'perf' : ['-g']} 1122 1123# Start out with the linker flags common to all linkers, i.e. -pg for 1124# prof, and -lprofiler for perf. The -lprofile flag is surrounded by 1125# no-as-needed and as-needed as the binutils linker is too clever and 1126# simply doesn't link to the library otherwise. 1127ldflags = {'debug' : [], 'opt' : [], 'fast' : [], 'prof' : ['-pg'], 1128 'perf' : ['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed']} 1129 1130# For Link Time Optimization, the optimisation flags used to compile 1131# individual files are decoupled from those used at link time 1132# (i.e. you can compile with -O3 and perform LTO with -O0), so we need 1133# to also update the linker flags based on the target. 1134if env['GCC']: 1135 if sys.platform == 'sunos5': 1136 ccflags['debug'] += ['-gstabs+'] 1137 else: 1138 ccflags['debug'] += ['-ggdb3'] 1139 ldflags['debug'] += ['-O0'] 1140 # opt, fast, prof and perf all share the same cc flags, also add 1141 # the optimization to the ldflags as LTO defers the optimization 1142 # to link time 1143 for target in ['opt', 'fast', 'prof', 'perf']: 1144 ccflags[target] += ['-O3'] 1145 ldflags[target] += ['-O3'] 1146 1147 ccflags['fast'] += env['LTO_CCFLAGS'] 1148 ldflags['fast'] += env['LTO_LDFLAGS'] 1149elif env['CLANG']: 1150 ccflags['debug'] += ['-g', '-O0'] 1151 # opt, fast, prof and perf all share the same cc flags 1152 for target in ['opt', 'fast', 'prof', 'perf']: 1153 ccflags[target] += ['-O3'] 1154else: 1155 print 'Unknown compiler, please fix compiler options' 1156 Exit(1) 1157 1158 1159# To speed things up, we only instantiate the build environments we 1160# need. We try to identify the needed environment for each target; if 1161# we can't, we fall back on instantiating all the environments just to 1162# be safe. 1163target_types = ['debug', 'opt', 'fast', 'prof', 'perf'] 1164obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof', 1165 'gpo' : 'perf'} 1166 1167def identifyTarget(t): 1168 ext = t.split('.')[-1] 1169 if ext in target_types: 1170 return ext 1171 if obj2target.has_key(ext): 1172 return obj2target[ext] 1173 match = re.search(r'/tests/([^/]+)/', t) 1174 if match and match.group(1) in target_types: 1175 return match.group(1) 1176 return 'all' 1177 1178needed_envs = [identifyTarget(target) for target in BUILD_TARGETS] 1179if 'all' in needed_envs: 1180 needed_envs += target_types 1181 1182def makeEnvirons(target, source, env): 1183 # cause any later Source() calls to be fatal, as a diagnostic. 1184 Source.done() 1185 1186 envList = [] 1187 1188 # Debug binary 1189 if 'debug' in needed_envs: 1190 envList.append( 1191 makeEnv(env, 'debug', '.do', 1192 CCFLAGS = Split(ccflags['debug']), 1193 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], 1194 LINKFLAGS = Split(ldflags['debug']))) 1195 1196 # Optimized binary 1197 if 'opt' in needed_envs: 1198 envList.append( 1199 makeEnv(env, 'opt', '.o', 1200 CCFLAGS = Split(ccflags['opt']), 1201 CPPDEFINES = ['TRACING_ON=1'], 1202 LINKFLAGS = Split(ldflags['opt']))) 1203 1204 # "Fast" binary 1205 if 'fast' in needed_envs: 1206 envList.append( 1207 makeEnv(env, 'fast', '.fo', strip = True, 1208 CCFLAGS = Split(ccflags['fast']), 1209 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1210 LINKFLAGS = Split(ldflags['fast']))) 1211 1212 # Profiled binary using gprof 1213 if 'prof' in needed_envs: 1214 envList.append( 1215 makeEnv(env, 'prof', '.po', 1216 CCFLAGS = Split(ccflags['prof']), 1217 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1218 LINKFLAGS = Split(ldflags['prof']))) 1219 1220 # Profiled binary using google-pprof 1221 if 'perf' in needed_envs: 1222 envList.append( 1223 makeEnv(env, 'perf', '.gpo', 1224 CCFLAGS = Split(ccflags['perf']), 1225 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 1226 LINKFLAGS = Split(ldflags['perf']))) 1227 1228 # Set up the regression tests for each build. 1229 for e in envList: 1230 SConscript(os.path.join(env.root.abspath, 'tests', 'SConscript'), 1231 variant_dir = variantd('tests', e.Label), 1232 exports = { 'env' : e }, duplicate = False) 1233 1234# The MakeEnvirons Builder defers the full dependency collection until 1235# after processing the ISA definition (due to dynamically generated 1236# source files). Add this dependency to all targets so they will wait 1237# until the environments are completely set up. Otherwise, a second 1238# process (e.g. -j2 or higher) will try to compile the requested target, 1239# not know how, and fail. 1240env.Append(BUILDERS = {'MakeEnvirons' : 1241 Builder(action=MakeAction(makeEnvirons, 1242 Transform("ENVIRONS", 1)))}) 1243 1244isa_target = env['PHONY_BASE'] + '-deps' 1245environs = env['PHONY_BASE'] + '-environs' 1246env.Depends('#all-deps', isa_target) 1247env.Depends('#all-environs', environs) 1248env.ScanISA(isa_target, File('arch/%s/generated/inc.d' % env['TARGET_ISA'])) 1249envSetup = env.MakeEnvirons(environs, isa_target) 1250 1251# make sure no -deps targets occur before all ISAs are complete 1252env.Depends(isa_target, '#all-isas') 1253# likewise for -environs targets and all the -deps targets 1254env.Depends(environs, '#all-deps')
|