SConscript (5341:4efeab4cc2a5) SConscript (5342:c19e3a1a607c)
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 imp
32import os
33import sys
34
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 imp
32import os
33import sys
34
35from os.path import basename
36from os.path import isdir, join as joinpath
37from os.path import exists
38from os.path import isdir
39from os.path import isfile
35from os.path import basename, exists, isdir, isfile, join as joinpath
40
41import SCons
42
43# This file defines how to build a particular configuration of M5
44# based on variable settings in the 'env' build environment.
45
46Import('*')
47
48# Children need to see the environment
49Export('env')
50
51def sort_list(_list):
52 """return a sorted copy of '_list'"""
53 if isinstance(_list, list):
54 _list = _list[:]
55 else:
56 _list = list(_list)
57 _list.sort()
58 return _list
59
60class PySourceFile(object):
61 def __init__(self, package, source):
62 filename = str(source)
63 pyname = basename(filename)
64 assert pyname.endswith('.py')
65 name = pyname[:-3]
66 path = package.split('.')
67 modpath = path
68 if name != '__init__':
69 modpath += [name]
70 modpath = '.'.join(modpath)
71
72 arcpath = package.split('.') + [ pyname + 'c' ]
73 arcname = joinpath(*arcpath)
74
75 self.source = source
76 self.pyname = pyname
77 self.srcpath = source.srcnode().abspath
78 self.package = package
79 self.modpath = modpath
80 self.arcname = arcname
81 self.filename = filename
82 self.compiled = File(filename + 'c')
83
84########################################################################
85# Code for adding source files of various types
86#
87cc_sources = []
88def Source(source):
89 '''Add a C/C++ source file to the build'''
90 if not isinstance(source, SCons.Node.FS.File):
91 source = File(source)
92
93 cc_sources.append(source)
94
95py_sources = []
96def PySource(package, source):
97 '''Add a python source file to the named package'''
98 if not isinstance(source, SCons.Node.FS.File):
99 source = File(source)
100
101 source = PySourceFile(package, source)
102 py_sources.append(source)
103
104sim_objects_fixed = False
105sim_object_modfiles = set()
106def SimObject(source):
107 '''Add a SimObject python file as a python source object and add
108 it to a list of sim object modules'''
109
110 if sim_objects_fixed:
111 raise AttributeError, "Too late to call SimObject now."
112
113 if not isinstance(source, SCons.Node.FS.File):
114 source = File(source)
115
116 PySource('m5.objects', source)
117 modfile = basename(str(source))
118 assert modfile.endswith('.py')
119 modname = modfile[:-3]
120 sim_object_modfiles.add(modname)
121
122swig_sources = []
123def SwigSource(package, source):
124 '''Add a swig file to build'''
125 if not isinstance(source, SCons.Node.FS.File):
126 source = File(source)
127 val = source,package
128 swig_sources.append(val)
129
130# Children should have access
131Export('Source')
132Export('PySource')
133Export('SimObject')
134Export('SwigSource')
135
136########################################################################
137#
138# Trace Flags
139#
140all_flags = {}
141trace_flags = []
142def TraceFlag(name, desc=''):
143 if name in all_flags:
144 raise AttributeError, "Flag %s already specified" % name
145 flag = (name, (), desc)
146 trace_flags.append(flag)
147 all_flags[name] = ()
148
149def CompoundFlag(name, flags, desc=''):
150 if name in all_flags:
151 raise AttributeError, "Flag %s already specified" % name
152
153 compound = tuple(flags)
154 for flag in compound:
155 if flag not in all_flags:
156 raise AttributeError, "Trace flag %s not found" % flag
157 if all_flags[flag]:
158 raise AttributeError, \
159 "Compound flag can't point to another compound flag"
160
161 flag = (name, compound, desc)
162 trace_flags.append(flag)
163 all_flags[name] = compound
164
165Export('TraceFlag')
166Export('CompoundFlag')
167
168########################################################################
169#
170# Set some compiler variables
171#
172
173# Include file paths are rooted in this directory. SCons will
174# automatically expand '.' to refer to both the source directory and
175# the corresponding build directory to pick up generated include
176# files.
177env.Append(CPPPATH=Dir('.'))
178
179# Add a flag defining what THE_ISA should be for all compilation
180env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
181
182########################################################################
183#
184# Walk the tree and execute all SConscripts in 'src' subdirectories
185#
186
187for base_dir in base_dir_list:
188 src_dir = joinpath(base_dir, 'src')
189 if not isdir(src_dir):
190 continue
191 here = Dir('.').srcnode().abspath
192 for root, dirs, files in os.walk(src_dir, topdown=True):
193 if root == here:
194 # we don't want to recurse back into this SConscript
195 continue
196
197 if 'SConscript' in files:
198 build_dir = joinpath(env['BUILDDIR'], root[len(src_dir) + 1:])
199 SConscript(joinpath(root, 'SConscript'), build_dir=build_dir)
200
201for opt in env.ExportOptions:
202 env.ConfigFile(opt)
203
204########################################################################
205#
206# Prevent any SimObjects from being added after this point, they
207# should all have been added in the SConscripts above
208#
209sim_objects_fixed = True
210
211########################################################################
212#
213# Manually turn python/generate.py into a python module and import it
214#
215generate_file = File('python/generate.py')
216generate_module = imp.new_module('generate')
217sys.modules['generate'] = generate_module
218exec file(generate_file.srcnode().abspath, 'r') in generate_module.__dict__
219
220########################################################################
221#
222# build a generate
223#
224from generate import Generate
225optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions])
226generate = Generate(py_sources, sim_object_modfiles, optionDict)
227m5 = generate.m5
228
229########################################################################
230#
231# calculate extra dependencies
232#
233module_depends = ["m5", "m5.SimObject", "m5.params"]
234module_depends = [ File(generate.py_modules[dep]) for dep in module_depends ]
235file_depends = [ generate_file ]
236depends = module_depends + file_depends
237
238########################################################################
239#
240# Commands for the basic automatically generated python files
241#
242
243# Generate a file with all of the compile options in it
244env.Command('python/m5/defines.py', Value(optionDict),
245 generate.makeDefinesPyFile)
246PySource('m5', 'python/m5/defines.py')
247
248# Generate a file that wraps the basic top level files
249env.Command('python/m5/info.py',
250 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
251 generate.makeInfoPyFile)
252PySource('m5', 'python/m5/info.py')
253
254# Generate an __init__.py file for the objects package
255env.Command('python/m5/objects/__init__.py',
256 [ Value(o) for o in sort_list(sim_object_modfiles) ],
257 generate.makeObjectsInitFile)
258PySource('m5.objects', 'python/m5/objects/__init__.py')
259
260########################################################################
261#
262# Create all of the SimObject param headers and enum headers
263#
264
265# Generate all of the SimObject param struct header files
266params_hh_files = []
267for name,simobj in generate.sim_objects.iteritems():
268 extra_deps = [ File(generate.py_modules[simobj.__module__]) ]
269
270 hh_file = File('params/%s.hh' % name)
271 params_hh_files.append(hh_file)
272 env.Command(hh_file, Value(name), generate.createSimObjectParam)
273 env.Depends(hh_file, depends + extra_deps)
274
275# Generate any parameter header files needed
276for name,param in generate.params.iteritems():
277 if isinstance(param, m5.params.VectorParamDesc):
278 ext = 'vptype'
279 else:
280 ext = 'ptype'
281
282 i_file = File('params/%s_%s.i' % (name, ext))
283 env.Command(i_file, Value(name), generate.createSwigParam)
284 env.Depends(i_file, depends)
285
286# Generate all enum header files
287for name,enum in generate.enums.iteritems():
288 extra_deps = [ File(generate.py_modules[enum.__module__]) ]
289
290 cc_file = File('enums/%s.cc' % name)
291 env.Command(cc_file, Value(name), generate.createEnumStrings)
292 env.Depends(cc_file, depends + extra_deps)
293 Source(cc_file)
294
295 hh_file = File('enums/%s.hh' % name)
296 env.Command(hh_file, Value(name), generate.createEnumParam)
297 env.Depends(hh_file, depends + extra_deps)
298
299# Build the big monolithic swigged params module (wraps all SimObject
300# param structs and enum structs)
301params_file = File('params/params.i')
302names = sort_list(generate.sim_objects.keys())
303env.Command(params_file, [ Value(v) for v in names ],
304 generate.buildParams)
305env.Depends(params_file, params_hh_files + depends)
306SwigSource('m5.objects', params_file)
307
308# Build all swig modules
309swig_modules = []
310for source,package in swig_sources:
311 filename = str(source)
312 assert filename.endswith('.i')
313
314 base = '.'.join(filename.split('.')[:-1])
315 module = basename(base)
316 cc_file = base + '_wrap.cc'
317 py_file = base + '.py'
318
319 env.Command([cc_file, py_file], source,
320 '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
321 '-o ${TARGETS[0]} $SOURCES')
322 env.Depends(py_file, source)
323 env.Depends(cc_file, source)
324
325 swig_modules.append(Value(module))
326 Source(cc_file)
327 PySource(package, py_file)
328
329# Generate the main swig init file
330env.Command('swig/init.cc', swig_modules, generate.makeSwigInit)
331Source('swig/init.cc')
332
333# Generate traceflags.py
334flags = [ Value(f) for f in trace_flags ]
335env.Command('base/traceflags.py', flags, generate.traceFlagsPy)
336PySource('m5', 'base/traceflags.py')
337
338env.Command('base/traceflags.hh', flags, generate.traceFlagsHH)
339env.Command('base/traceflags.cc', flags, generate.traceFlagsCC)
340Source('base/traceflags.cc')
341
342# Build the zip file
343py_compiled = []
344py_zip_depends = []
345for source in py_sources:
346 env.Command(source.compiled, source.source, generate.compilePyFile)
347 py_compiled.append(source.compiled)
348
349 # make the zipfile depend on the archive name so that the archive
350 # is rebuilt if the name changes
351 py_zip_depends.append(Value(source.arcname))
352
353# Add the zip file target to the environment.
354m5zip = File('m5py.zip')
355env.Command(m5zip, py_compiled, generate.buildPyZip)
356env.Depends(m5zip, py_zip_depends)
357
358########################################################################
359#
360# Define binaries. Each different build type (debug, opt, etc.) gets
361# a slightly different build environment.
362#
363
364# List of constructed environments to pass back to SConstruct
365envList = []
366
367# This function adds the specified sources to the given build
368# environment, and returns a list of all the corresponding SCons
369# Object nodes (including an extra one for date.cc). We explicitly
370# add the Object nodes so we can set up special dependencies for
371# date.cc.
372def make_objs(sources, env):
373 objs = [env.Object(s) for s in sources]
374 # make date.cc depend on all other objects so it always gets
375 # recompiled whenever anything else does
376 date_obj = env.Object('base/date.cc')
377 env.Depends(date_obj, objs)
378 objs.append(date_obj)
379 return objs
380
381# Function to create a new build environment as clone of current
382# environment 'env' with modified object suffix and optional stripped
383# binary. Additional keyword arguments are appended to corresponding
384# build environment vars.
385def makeEnv(label, objsfx, strip = False, **kwargs):
386 newEnv = env.Copy(OBJSUFFIX=objsfx)
387 newEnv.Label = label
388 newEnv.Append(**kwargs)
389 exe = 'm5.' + label # final executable
390 bin = exe + '.bin' # executable w/o appended Python zip archive
391 newEnv.Program(bin, make_objs(cc_sources, newEnv))
392 if strip:
393 stripped_bin = bin + '.stripped'
394 if sys.platform == 'sunos5':
395 cmd = 'cp $SOURCE $TARGET; strip $TARGET'
396 else:
397 cmd = 'strip $SOURCE -o $TARGET'
398 newEnv.Command(stripped_bin, bin, cmd)
399 bin = stripped_bin
400 targets = newEnv.Concat(exe, [bin, 'm5py.zip'])
401 newEnv.M5Binary = targets[0]
402 envList.append(newEnv)
403
404# Debug binary
405ccflags = {}
406if env['GCC']:
407 if sys.platform == 'sunos5':
408 ccflags['debug'] = '-gstabs+'
409 else:
410 ccflags['debug'] = '-ggdb3'
411 ccflags['opt'] = '-g -O3'
412 ccflags['fast'] = '-O3'
413 ccflags['prof'] = '-O3 -g -pg'
414elif env['SUNCC']:
415 ccflags['debug'] = '-g0'
416 ccflags['opt'] = '-g -O'
417 ccflags['fast'] = '-fast'
418 ccflags['prof'] = '-fast -g -pg'
419elif env['ICC']:
420 ccflags['debug'] = '-g -O0'
421 ccflags['opt'] = '-g -O'
422 ccflags['fast'] = '-fast'
423 ccflags['prof'] = '-fast -g -pg'
424else:
425 print 'Unknown compiler, please fix compiler options'
426 Exit(1)
427
428makeEnv('debug', '.do',
429 CCFLAGS = Split(ccflags['debug']),
430 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])
431
432# Optimized binary
433makeEnv('opt', '.o',
434 CCFLAGS = Split(ccflags['opt']),
435 CPPDEFINES = ['TRACING_ON=1'])
436
437# "Fast" binary
438makeEnv('fast', '.fo', strip = True,
439 CCFLAGS = Split(ccflags['fast']),
440 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])
441
442# Profiled binary
443makeEnv('prof', '.po',
444 CCFLAGS = Split(ccflags['prof']),
445 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
446 LINKFLAGS = '-pg')
447
448Return('envList')
36
37import SCons
38
39# This file defines how to build a particular configuration of M5
40# based on variable settings in the 'env' build environment.
41
42Import('*')
43
44# Children need to see the environment
45Export('env')
46
47def sort_list(_list):
48 """return a sorted copy of '_list'"""
49 if isinstance(_list, list):
50 _list = _list[:]
51 else:
52 _list = list(_list)
53 _list.sort()
54 return _list
55
56class PySourceFile(object):
57 def __init__(self, package, source):
58 filename = str(source)
59 pyname = basename(filename)
60 assert pyname.endswith('.py')
61 name = pyname[:-3]
62 path = package.split('.')
63 modpath = path
64 if name != '__init__':
65 modpath += [name]
66 modpath = '.'.join(modpath)
67
68 arcpath = package.split('.') + [ pyname + 'c' ]
69 arcname = joinpath(*arcpath)
70
71 self.source = source
72 self.pyname = pyname
73 self.srcpath = source.srcnode().abspath
74 self.package = package
75 self.modpath = modpath
76 self.arcname = arcname
77 self.filename = filename
78 self.compiled = File(filename + 'c')
79
80########################################################################
81# Code for adding source files of various types
82#
83cc_sources = []
84def Source(source):
85 '''Add a C/C++ source file to the build'''
86 if not isinstance(source, SCons.Node.FS.File):
87 source = File(source)
88
89 cc_sources.append(source)
90
91py_sources = []
92def PySource(package, source):
93 '''Add a python source file to the named package'''
94 if not isinstance(source, SCons.Node.FS.File):
95 source = File(source)
96
97 source = PySourceFile(package, source)
98 py_sources.append(source)
99
100sim_objects_fixed = False
101sim_object_modfiles = set()
102def SimObject(source):
103 '''Add a SimObject python file as a python source object and add
104 it to a list of sim object modules'''
105
106 if sim_objects_fixed:
107 raise AttributeError, "Too late to call SimObject now."
108
109 if not isinstance(source, SCons.Node.FS.File):
110 source = File(source)
111
112 PySource('m5.objects', source)
113 modfile = basename(str(source))
114 assert modfile.endswith('.py')
115 modname = modfile[:-3]
116 sim_object_modfiles.add(modname)
117
118swig_sources = []
119def SwigSource(package, source):
120 '''Add a swig file to build'''
121 if not isinstance(source, SCons.Node.FS.File):
122 source = File(source)
123 val = source,package
124 swig_sources.append(val)
125
126# Children should have access
127Export('Source')
128Export('PySource')
129Export('SimObject')
130Export('SwigSource')
131
132########################################################################
133#
134# Trace Flags
135#
136all_flags = {}
137trace_flags = []
138def TraceFlag(name, desc=''):
139 if name in all_flags:
140 raise AttributeError, "Flag %s already specified" % name
141 flag = (name, (), desc)
142 trace_flags.append(flag)
143 all_flags[name] = ()
144
145def CompoundFlag(name, flags, desc=''):
146 if name in all_flags:
147 raise AttributeError, "Flag %s already specified" % name
148
149 compound = tuple(flags)
150 for flag in compound:
151 if flag not in all_flags:
152 raise AttributeError, "Trace flag %s not found" % flag
153 if all_flags[flag]:
154 raise AttributeError, \
155 "Compound flag can't point to another compound flag"
156
157 flag = (name, compound, desc)
158 trace_flags.append(flag)
159 all_flags[name] = compound
160
161Export('TraceFlag')
162Export('CompoundFlag')
163
164########################################################################
165#
166# Set some compiler variables
167#
168
169# Include file paths are rooted in this directory. SCons will
170# automatically expand '.' to refer to both the source directory and
171# the corresponding build directory to pick up generated include
172# files.
173env.Append(CPPPATH=Dir('.'))
174
175# Add a flag defining what THE_ISA should be for all compilation
176env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
177
178########################################################################
179#
180# Walk the tree and execute all SConscripts in 'src' subdirectories
181#
182
183for base_dir in base_dir_list:
184 src_dir = joinpath(base_dir, 'src')
185 if not isdir(src_dir):
186 continue
187 here = Dir('.').srcnode().abspath
188 for root, dirs, files in os.walk(src_dir, topdown=True):
189 if root == here:
190 # we don't want to recurse back into this SConscript
191 continue
192
193 if 'SConscript' in files:
194 build_dir = joinpath(env['BUILDDIR'], root[len(src_dir) + 1:])
195 SConscript(joinpath(root, 'SConscript'), build_dir=build_dir)
196
197for opt in env.ExportOptions:
198 env.ConfigFile(opt)
199
200########################################################################
201#
202# Prevent any SimObjects from being added after this point, they
203# should all have been added in the SConscripts above
204#
205sim_objects_fixed = True
206
207########################################################################
208#
209# Manually turn python/generate.py into a python module and import it
210#
211generate_file = File('python/generate.py')
212generate_module = imp.new_module('generate')
213sys.modules['generate'] = generate_module
214exec file(generate_file.srcnode().abspath, 'r') in generate_module.__dict__
215
216########################################################################
217#
218# build a generate
219#
220from generate import Generate
221optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions])
222generate = Generate(py_sources, sim_object_modfiles, optionDict)
223m5 = generate.m5
224
225########################################################################
226#
227# calculate extra dependencies
228#
229module_depends = ["m5", "m5.SimObject", "m5.params"]
230module_depends = [ File(generate.py_modules[dep]) for dep in module_depends ]
231file_depends = [ generate_file ]
232depends = module_depends + file_depends
233
234########################################################################
235#
236# Commands for the basic automatically generated python files
237#
238
239# Generate a file with all of the compile options in it
240env.Command('python/m5/defines.py', Value(optionDict),
241 generate.makeDefinesPyFile)
242PySource('m5', 'python/m5/defines.py')
243
244# Generate a file that wraps the basic top level files
245env.Command('python/m5/info.py',
246 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
247 generate.makeInfoPyFile)
248PySource('m5', 'python/m5/info.py')
249
250# Generate an __init__.py file for the objects package
251env.Command('python/m5/objects/__init__.py',
252 [ Value(o) for o in sort_list(sim_object_modfiles) ],
253 generate.makeObjectsInitFile)
254PySource('m5.objects', 'python/m5/objects/__init__.py')
255
256########################################################################
257#
258# Create all of the SimObject param headers and enum headers
259#
260
261# Generate all of the SimObject param struct header files
262params_hh_files = []
263for name,simobj in generate.sim_objects.iteritems():
264 extra_deps = [ File(generate.py_modules[simobj.__module__]) ]
265
266 hh_file = File('params/%s.hh' % name)
267 params_hh_files.append(hh_file)
268 env.Command(hh_file, Value(name), generate.createSimObjectParam)
269 env.Depends(hh_file, depends + extra_deps)
270
271# Generate any parameter header files needed
272for name,param in generate.params.iteritems():
273 if isinstance(param, m5.params.VectorParamDesc):
274 ext = 'vptype'
275 else:
276 ext = 'ptype'
277
278 i_file = File('params/%s_%s.i' % (name, ext))
279 env.Command(i_file, Value(name), generate.createSwigParam)
280 env.Depends(i_file, depends)
281
282# Generate all enum header files
283for name,enum in generate.enums.iteritems():
284 extra_deps = [ File(generate.py_modules[enum.__module__]) ]
285
286 cc_file = File('enums/%s.cc' % name)
287 env.Command(cc_file, Value(name), generate.createEnumStrings)
288 env.Depends(cc_file, depends + extra_deps)
289 Source(cc_file)
290
291 hh_file = File('enums/%s.hh' % name)
292 env.Command(hh_file, Value(name), generate.createEnumParam)
293 env.Depends(hh_file, depends + extra_deps)
294
295# Build the big monolithic swigged params module (wraps all SimObject
296# param structs and enum structs)
297params_file = File('params/params.i')
298names = sort_list(generate.sim_objects.keys())
299env.Command(params_file, [ Value(v) for v in names ],
300 generate.buildParams)
301env.Depends(params_file, params_hh_files + depends)
302SwigSource('m5.objects', params_file)
303
304# Build all swig modules
305swig_modules = []
306for source,package in swig_sources:
307 filename = str(source)
308 assert filename.endswith('.i')
309
310 base = '.'.join(filename.split('.')[:-1])
311 module = basename(base)
312 cc_file = base + '_wrap.cc'
313 py_file = base + '.py'
314
315 env.Command([cc_file, py_file], source,
316 '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
317 '-o ${TARGETS[0]} $SOURCES')
318 env.Depends(py_file, source)
319 env.Depends(cc_file, source)
320
321 swig_modules.append(Value(module))
322 Source(cc_file)
323 PySource(package, py_file)
324
325# Generate the main swig init file
326env.Command('swig/init.cc', swig_modules, generate.makeSwigInit)
327Source('swig/init.cc')
328
329# Generate traceflags.py
330flags = [ Value(f) for f in trace_flags ]
331env.Command('base/traceflags.py', flags, generate.traceFlagsPy)
332PySource('m5', 'base/traceflags.py')
333
334env.Command('base/traceflags.hh', flags, generate.traceFlagsHH)
335env.Command('base/traceflags.cc', flags, generate.traceFlagsCC)
336Source('base/traceflags.cc')
337
338# Build the zip file
339py_compiled = []
340py_zip_depends = []
341for source in py_sources:
342 env.Command(source.compiled, source.source, generate.compilePyFile)
343 py_compiled.append(source.compiled)
344
345 # make the zipfile depend on the archive name so that the archive
346 # is rebuilt if the name changes
347 py_zip_depends.append(Value(source.arcname))
348
349# Add the zip file target to the environment.
350m5zip = File('m5py.zip')
351env.Command(m5zip, py_compiled, generate.buildPyZip)
352env.Depends(m5zip, py_zip_depends)
353
354########################################################################
355#
356# Define binaries. Each different build type (debug, opt, etc.) gets
357# a slightly different build environment.
358#
359
360# List of constructed environments to pass back to SConstruct
361envList = []
362
363# This function adds the specified sources to the given build
364# environment, and returns a list of all the corresponding SCons
365# Object nodes (including an extra one for date.cc). We explicitly
366# add the Object nodes so we can set up special dependencies for
367# date.cc.
368def make_objs(sources, env):
369 objs = [env.Object(s) for s in sources]
370 # make date.cc depend on all other objects so it always gets
371 # recompiled whenever anything else does
372 date_obj = env.Object('base/date.cc')
373 env.Depends(date_obj, objs)
374 objs.append(date_obj)
375 return objs
376
377# Function to create a new build environment as clone of current
378# environment 'env' with modified object suffix and optional stripped
379# binary. Additional keyword arguments are appended to corresponding
380# build environment vars.
381def makeEnv(label, objsfx, strip = False, **kwargs):
382 newEnv = env.Copy(OBJSUFFIX=objsfx)
383 newEnv.Label = label
384 newEnv.Append(**kwargs)
385 exe = 'm5.' + label # final executable
386 bin = exe + '.bin' # executable w/o appended Python zip archive
387 newEnv.Program(bin, make_objs(cc_sources, newEnv))
388 if strip:
389 stripped_bin = bin + '.stripped'
390 if sys.platform == 'sunos5':
391 cmd = 'cp $SOURCE $TARGET; strip $TARGET'
392 else:
393 cmd = 'strip $SOURCE -o $TARGET'
394 newEnv.Command(stripped_bin, bin, cmd)
395 bin = stripped_bin
396 targets = newEnv.Concat(exe, [bin, 'm5py.zip'])
397 newEnv.M5Binary = targets[0]
398 envList.append(newEnv)
399
400# Debug binary
401ccflags = {}
402if env['GCC']:
403 if sys.platform == 'sunos5':
404 ccflags['debug'] = '-gstabs+'
405 else:
406 ccflags['debug'] = '-ggdb3'
407 ccflags['opt'] = '-g -O3'
408 ccflags['fast'] = '-O3'
409 ccflags['prof'] = '-O3 -g -pg'
410elif env['SUNCC']:
411 ccflags['debug'] = '-g0'
412 ccflags['opt'] = '-g -O'
413 ccflags['fast'] = '-fast'
414 ccflags['prof'] = '-fast -g -pg'
415elif env['ICC']:
416 ccflags['debug'] = '-g -O0'
417 ccflags['opt'] = '-g -O'
418 ccflags['fast'] = '-fast'
419 ccflags['prof'] = '-fast -g -pg'
420else:
421 print 'Unknown compiler, please fix compiler options'
422 Exit(1)
423
424makeEnv('debug', '.do',
425 CCFLAGS = Split(ccflags['debug']),
426 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])
427
428# Optimized binary
429makeEnv('opt', '.o',
430 CCFLAGS = Split(ccflags['opt']),
431 CPPDEFINES = ['TRACING_ON=1'])
432
433# "Fast" binary
434makeEnv('fast', '.fo', strip = True,
435 CCFLAGS = Split(ccflags['fast']),
436 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])
437
438# Profiled binary
439makeEnv('prof', '.po',
440 CCFLAGS = Split(ccflags['prof']),
441 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
442 LINKFLAGS = '-pg')
443
444Return('envList')