3 # Copyright (c) 2004-2005 The Regents of The University of Michigan
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.
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.
29 # Authors: Nathan Binkert
40 from os.path import basename, dirname, exists, isdir, isfile, join as joinpath
44 # This file defines how to build a particular configuration of M5
45 # based on variable settings in the 'env' build environment.
49 # Children need to see the environment
52 build_env = [(opt, env[opt]) for opt in export_vars]
54 from m5.util import code_formatter
56 ########################################################################
57 # Code for adding source files of various types
59 class SourceMeta(type):
60 def __init__(cls, name, bases, dict):
61 super(SourceMeta, cls).__init__(name, bases, dict)
64 def get(cls, **kwargs):
66 for attr,value in kwargs.iteritems():
67 if getattr(src, attr) != value:
72 class SourceFile(object):
73 __metaclass__ = SourceMeta
74 def __init__(self, source):
76 if not isinstance(source, SCons.Node.FS.File):
80 self.snode = tnode.srcnode()
81 self.filename = str(tnode)
82 self.dirname = dirname(self.filename)
83 self.basename = basename(self.filename)
84 index = self.basename.rfind('.')
86 # dot files aren't extensions
87 self.extname = self.basename, None
89 self.extname = self.basename[:index], self.basename[index+1:]
91 for base in type(self).__mro__:
92 if issubclass(base, SourceFile):
95 def __lt__(self, other): return self.filename < other.filename
96 def __le__(self, other): return self.filename <= other.filename
97 def __gt__(self, other): return self.filename > other.filename
98 def __ge__(self, other): return self.filename >= other.filename
99 def __eq__(self, other): return self.filename == other.filename
100 def __ne__(self, other): return self.filename != other.filename
102 class Source(SourceFile):
103 '''Add a c/c++ source file to the build'''
104 def __init__(self, source, Werror=True, swig=False, bin_only=False,
106 super(Source, self).__init__(source)
110 self.bin_only = bin_only
111 self.skip_lib = bin_only or skip_lib
113 class PySource(SourceFile):
114 '''Add a python source file to the named package'''
115 invalid_sym_char = re.compile('[^A-z0-9_]')
120 def __init__(self, package, source):
121 super(PySource, self).__init__(source)
123 modname,ext = self.extname
127 path = package.split('.')
132 if modname != '__init__':
133 modpath += [ modname ]
134 modpath = '.'.join(modpath)
136 arcpath = path + [ self.basename ]
137 abspath = self.snode.abspath
138 if not exists(abspath):
139 abspath = self.tnode.abspath
141 self.package = package
142 self.modname = modname
143 self.modpath = modpath
144 self.arcname = joinpath(*arcpath)
145 self.abspath = abspath
146 self.compiled = File(self.filename + 'c')
147 self.cpp = File(self.filename + '.cc')
148 self.symname = PySource.invalid_sym_char.sub('_', modpath)
150 PySource.modules[modpath] = self
151 PySource.tnodes[self.tnode] = self
152 PySource.symnames[self.symname] = self
154 class SimObject(PySource):
155 '''Add a SimObject python file as a python source object and add
156 it to a list of sim object modules'''
161 def __init__(self, source):
162 super(SimObject, self).__init__('m5.objects', source)
164 raise AttributeError, "Too late to call SimObject now."
166 bisect.insort_right(SimObject.modnames, self.modname)
168 class SwigSource(SourceFile):
169 '''Add a swig file to build'''
171 def __init__(self, package, source):
172 super(SwigSource, self).__init__(source)
174 modname,ext = self.extname
177 self.module = modname
178 cc_file = joinpath(self.dirname, modname + '_wrap.cc')
179 py_file = joinpath(self.dirname, modname + '.py')
181 self.cc_source = Source(cc_file, swig=True)
182 self.py_source = PySource(package, py_file)
185 def UnitTest(target, sources):
186 if not isinstance(sources, (list, tuple)):
187 sources = [ sources ]
189 sources = [ Source(src, skip_lib=True) for src in sources ]
190 unit_tests.append((target, sources))
192 # Children should have access
199 ########################################################################
204 def TraceFlag(name, desc=None):
205 if name in trace_flags:
206 raise AttributeError, "Flag %s already specified" % name
207 trace_flags[name] = (name, (), desc)
209 def CompoundFlag(name, flags, desc=None):
210 if name in trace_flags:
211 raise AttributeError, "Flag %s already specified" % name
213 compound = tuple(flags)
214 trace_flags[name] = (name, compound, desc)
217 Export('CompoundFlag')
219 ########################################################################
221 # Set some compiler variables
224 # Include file paths are rooted in this directory. SCons will
225 # automatically expand '.' to refer to both the source directory and
226 # the corresponding build directory to pick up generated include
228 env.Append(CPPPATH=Dir('.'))
230 for extra_dir in extras_dir_list:
231 env.Append(CPPPATH=Dir(extra_dir))
233 # Workaround for bug in SCons version > 0.97d20071212
234 # Scons bug id: 2006 M5 Bug id: 308
235 for root, dirs, files in os.walk(base_dir, topdown=True):
236 Dir(root[len(base_dir) + 1:])
238 ########################################################################
240 # Walk the tree and execute all SConscripts in subdirectories
243 here = Dir('.').srcnode().abspath
244 for root, dirs, files in os.walk(base_dir, topdown=True):
246 # we don't want to recurse back into this SConscript
249 if 'SConscript' in files:
250 build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:])
251 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir)
253 for extra_dir in extras_dir_list:
254 prefix_len = len(dirname(extra_dir)) + 1
255 for root, dirs, files in os.walk(extra_dir, topdown=True):
256 if 'SConscript' in files:
257 build_dir = joinpath(env['BUILDDIR'], root[prefix_len:])
258 SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir)
260 for opt in export_vars:
263 def makeTheISA(source, target, env):
264 isas = [ src.get_contents() for src in source ]
265 target_isa = env['TARGET_ISA']
267 return isa.upper() + '_ISA'
270 return isa[0].upper() + isa[1:].lower() + 'ISA'
273 code = code_formatter()
275 #ifndef __CONFIG_THE_ISA_HH__
276 #define __CONFIG_THE_ISA_HH__
280 for i,isa in enumerate(isas):
281 code('#define $0 $1', define(isa), i + 1)
285 #define THE_ISA ${{define(target_isa)}}
286 #define TheISA ${{namespace(target_isa)}}
288 #endif // __CONFIG_THE_ISA_HH__''')
290 code.write(str(target[0]))
292 env.Command('config/the_isa.hh', map(Value, all_isa_list),
293 MakeAction(makeTheISA, " [ CFG ISA] $STRIP_TARGET"))
295 ########################################################################
297 # Prevent any SimObjects from being added after this point, they
298 # should all have been added in the SConscripts above
300 SimObject.fixed = True
302 class DictImporter(object):
303 '''This importer takes a dictionary of arbitrary module names that
304 map to arbitrary filenames.'''
305 def __init__(self, modules):
306 self.modules = modules
307 self.installed = set()
314 for module in self.installed:
315 del sys.modules[module]
316 self.installed = set()
318 def find_module(self, fullname, path):
319 if fullname == 'm5.defines':
322 if fullname == 'm5.objects':
325 if fullname.startswith('m5.internal'):
328 source = self.modules.get(fullname, None)
329 if source is not None and fullname.startswith('m5.objects'):
334 def load_module(self, fullname):
335 mod = imp.new_module(fullname)
336 sys.modules[fullname] = mod
337 self.installed.add(fullname)
339 mod.__loader__ = self
340 if fullname == 'm5.objects':
341 mod.__path__ = fullname.split('.')
344 if fullname == 'm5.defines':
345 mod.__dict__['buildEnv'] = m5.util.SmartDict(build_env)
348 source = self.modules[fullname]
349 if source.modname == '__init__':
350 mod.__path__ = source.modpath
351 mod.__file__ = source.abspath
353 exec file(source.abspath, 'r') in mod.__dict__
359 from m5.util import code_formatter
364 # install the python importer so we can grab stuff from the source
365 # tree itself. We can't have SimObjects added after this point or
366 # else we won't know about them for the rest of the stuff.
367 importer = DictImporter(PySource.modules)
368 sys.meta_path[0:0] = [ importer ]
370 # import all sim objects so we can populate the all_objects list
371 # make sure that we're working with a list, then let's sort it
372 for modname in SimObject.modnames:
373 exec('from m5.objects import %s' % modname)
375 # we need to unload all of the currently imported modules so that they
376 # will be re-imported the next time the sconscript is run
378 sys.meta_path.remove(importer)
380 sim_objects = m5.SimObject.allClasses
381 all_enums = m5.params.allEnums
384 for name,obj in sorted(sim_objects.iteritems()):
385 for param in obj._params.local.values():
386 # load the ptype attribute now because it depends on the
387 # current version of SimObject.allClasses, but when scons
388 # actually uses the value, all versions of
389 # SimObject.allClasses will have been loaded
392 if not hasattr(param, 'swig_decl'):
394 pname = param.ptype_str
395 if pname not in all_params:
396 all_params[pname] = param
398 ########################################################################
400 # calculate extra dependencies
402 module_depends = ["m5", "m5.SimObject", "m5.params"]
403 depends = [ PySource.modules[dep].snode for dep in module_depends ]
405 ########################################################################
407 # Commands for the basic automatically generated python files
410 # Generate Python file containing a dict specifying the current
412 def makeDefinesPyFile(target, source, env):
413 build_env, hg_info = [ x.get_contents() for x in source ]
415 code = code_formatter()
420 buildEnv = m5.util.SmartDict($build_env)
423 compileDate = m5.internal.core.compileDate
425 for key,val in m5.internal.core.__dict__.iteritems():
426 if key.startswith('flag_'):
431 code.write(target[0].abspath)
433 defines_info = [ Value(build_env), Value(env['HG_INFO']) ]
434 # Generate a file with all of the compile options in it
435 env.Command('python/m5/defines.py', defines_info,
436 MakeAction(makeDefinesPyFile, " [ DEFINES] $STRIP_TARGET"))
437 PySource('m5', 'python/m5/defines.py')
439 # Generate python file containing info about the M5 source code
440 def makeInfoPyFile(target, source, env):
441 code = code_formatter()
443 data = ''.join(file(src.srcnode().abspath, 'r').xreadlines())
444 code('$src = ${{repr(data)}}')
445 code.write(str(target[0]))
447 # Generate a file that wraps the basic top level files
448 env.Command('python/m5/info.py',
449 [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
450 MakeAction(makeInfoPyFile, " [ INFO] $STRIP_TARGET"))
451 PySource('m5', 'python/m5/info.py')
453 ########################################################################
455 # Create all of the SimObject param headers and enum headers
458 def createSimObjectParam(target, source, env):
459 assert len(target) == 1 and len(source) == 1
461 name = str(source[0].get_contents())
462 obj = sim_objects[name]
464 code = code_formatter()
466 code.write(target[0].abspath)
468 def createSwigParam(target, source, env):
469 assert len(target) == 1 and len(source) == 1
471 name = str(source[0].get_contents())
472 param = all_params[name]
474 code = code_formatter()
475 code('%module(package="m5.internal") $0_${name}', param.file_ext)
476 param.swig_decl(code)
477 code.write(target[0].abspath)
479 def createEnumStrings(target, source, env):
480 assert len(target) == 1 and len(source) == 1
482 name = str(source[0].get_contents())
483 obj = all_enums[name]
485 code = code_formatter()
487 code.write(target[0].abspath)
489 def createEnumParam(target, source, env):
490 assert len(target) == 1 and len(source) == 1
492 name = str(source[0].get_contents())
493 obj = all_enums[name]
495 code = code_formatter()
497 code.write(target[0].abspath)
499 def createEnumSwig(target, source, env):
500 assert len(target) == 1 and len(source) == 1
502 name = str(source[0].get_contents())
503 obj = all_enums[name]
505 code = code_formatter()
507 %module(package="m5.internal") enum_$name
510 #include "enums/$name.hh"
513 %include "enums/$name.hh"
515 code.write(target[0].abspath)
517 # Generate all of the SimObject param struct header files
519 for name,simobj in sorted(sim_objects.iteritems()):
520 py_source = PySource.modules[simobj.__module__]
521 extra_deps = [ py_source.tnode ]
523 hh_file = File('params/%s.hh' % name)
524 params_hh_files.append(hh_file)
525 env.Command(hh_file, Value(name),
526 MakeAction(createSimObjectParam, " [SO PARAM] $STRIP_TARGET"))
527 env.Depends(hh_file, depends + extra_deps)
529 # Generate any parameter header files needed
531 for name,param in all_params.iteritems():
532 i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name))
533 params_i_files.append(i_file)
534 env.Command(i_file, Value(name),
535 MakeAction(createSwigParam, " [SW PARAM] $STRIP_TARGET"))
536 env.Depends(i_file, depends)
537 SwigSource('m5.internal', i_file)
539 # Generate all enum header files
540 for name,enum in sorted(all_enums.iteritems()):
541 py_source = PySource.modules[enum.__module__]
542 extra_deps = [ py_source.tnode ]
544 cc_file = File('enums/%s.cc' % name)
545 env.Command(cc_file, Value(name),
546 MakeAction(createEnumStrings, " [ENUM STR] $STRIP_TARGET"))
547 env.Depends(cc_file, depends + extra_deps)
550 hh_file = File('enums/%s.hh' % name)
551 env.Command(hh_file, Value(name),
552 MakeAction(createEnumParam, " [EN PARAM] $STRIP_TARGET"))
553 env.Depends(hh_file, depends + extra_deps)
555 i_file = File('python/m5/internal/enum_%s.i' % name)
556 env.Command(i_file, Value(name),
557 MakeAction(createEnumSwig, " [ENUMSWIG] $STRIP_TARGET"))
558 env.Depends(i_file, depends + extra_deps)
559 SwigSource('m5.internal', i_file)
561 def buildParam(target, source, env):
562 name = source[0].get_contents()
563 obj = sim_objects[name]
564 class_path = obj.cxx_class.split('::')
565 classname = class_path[-1]
566 namespaces = class_path[:-1]
567 params = obj._params.local.values()
569 code = code_formatter()
571 code('%module(package="m5.internal") param_$name')
574 code('#include "params/$obj.hh"')
576 param.cxx_predecls(code)
581 param.swig_predecls(code)
585 code('%import "python/m5/internal/param_${{obj._base}}.i"')
587 obj.swig_objdecls(code)
590 code('%include "params/$obj.hh"')
592 code.write(target[0].abspath)
594 for name in sim_objects.iterkeys():
595 params_file = File('python/m5/internal/param_%s.i' % name)
596 env.Command(params_file, Value(name),
597 MakeAction(buildParam, " [BLDPARAM] $STRIP_TARGET"))
598 env.Depends(params_file, depends)
599 SwigSource('m5.internal', params_file)
601 # Generate the main swig init file
602 def makeEmbeddedSwigInit(target, source, env):
603 code = code_formatter()
604 module = source[0].get_contents()
606 #include "sim/init.hh"
609 void init_${module}();
612 EmbeddedSwig embed_swig_${module}(init_${module});
614 code.write(str(target[0]))
616 # Build all swig modules
617 for swig in SwigSource.all:
618 env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode,
619 MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
620 '-o ${TARGETS[0]} $SOURCES', " [ SWIG] $STRIP_TARGET"))
621 init_file = 'python/swig/init_%s.cc' % swig.module
622 env.Command(init_file, Value(swig.module),
623 MakeAction(makeEmbeddedSwigInit, " [EMBED SW] $STRIP_TARGET"))
626 def getFlags(source_flags):
629 for s in source_flags:
630 val = eval(s.get_contents())
631 name, compound, desc = val
632 flagsList.append(val)
633 flagsMap[name] = bool(compound)
635 for name, compound, desc in flagsList:
636 for flag in compound:
637 if flag not in flagsMap:
638 raise AttributeError, "Trace flag %s not found" % flag
640 raise AttributeError, \
641 "Compound flag can't point to another compound flag"
647 # Generate traceflags.py
648 def traceFlagsPy(target, source, env):
649 assert(len(target) == 1)
650 code = code_formatter()
652 allFlags = getFlags(source)
656 for flag, compound, desc in allFlags:
666 for flag, compound, desc in allFlags:
673 code("all = frozenset(basic + compound)")
676 code('compoundMap = {')
678 all = tuple([flag for flag,compound,desc in allFlags if not compound])
679 code("'All' : $all,")
680 for flag, compound, desc in allFlags:
682 code("'$flag' : $compound,")
687 code('descriptions = {')
689 code("'All' : 'All flags',")
690 for flag, compound, desc in allFlags:
691 code("'$flag' : '$desc',")
695 code.write(str(target[0]))
697 def traceFlagsCC(target, source, env):
698 assert(len(target) == 1)
700 allFlags = getFlags(source)
701 code = code_formatter()
706 * DO NOT EDIT THIS FILE! Automatically generated
709 #include "base/traceflags.hh"
711 using namespace Trace;
713 const char *Trace::flagStrings[] =
717 # The string array is used by SimpleEnumParam to map the strings
718 # provided by the user to enum values.
719 for flag, compound, desc in allFlags:
724 for flag, compound, desc in allFlags:
732 const int Trace::numFlagStrings = ${{len(allFlags) + 1}};
736 # Now define the individual compound flag arrays. There is an array
737 # for each compound flag listing the component base flags.
738 all = tuple([flag for flag,compound,desc in allFlags if not compound])
739 code('static const Flags AllMap[] = {')
741 for flag, compound, desc in allFlags:
748 for flag, compound, desc in allFlags:
751 code('static const Flags ${flag}Map[] = {')
753 for flag in compound:
760 # Finally the compoundFlags[] array maps the compound flags
761 # to their individual arrays/
762 code('const Flags *Trace::compoundFlags[] = {')
765 for flag, compound, desc in allFlags:
772 code.write(str(target[0]))
774 def traceFlagsHH(target, source, env):
775 assert(len(target) == 1)
777 allFlags = getFlags(source)
778 code = code_formatter()
780 # file header boilerplate
783 * DO NOT EDIT THIS FILE!
785 * Automatically generated from traceflags.py
788 #ifndef __BASE_TRACE_FLAGS_HH__
789 #define __BASE_TRACE_FLAGS_HH__
795 # Generate the enum. Base flags come first, then compound flags.
798 for flag, compound, desc in allFlags:
800 code('$flag = $idx,')
804 code('NumFlags = $idx,')
808 # put a comment in here to separate base from compound flags
810 // The remaining enum values are *not* valid indices for Trace::flags.
811 // They are "compound" flags, which correspond to sets of base
812 // flags, and are used by changeFlag.''')
817 for flag, compound, desc in allFlags:
819 code('$flag = $idx,')
822 numCompoundFlags = idx - numBaseFlags
823 code('NumCompoundFlags = $numCompoundFlags')
826 # trailer boilerplate
830 // Array of strings for SimpleEnumParam
831 extern const char *flagStrings[];
832 extern const int numFlagStrings;
834 // Array of arraay pointers: for each compound flag, gives the list of
835 // base flags to set. Inidividual flag arrays are terminated by -1.
836 extern const Flags *compoundFlags[];
840 #endif // __BASE_TRACE_FLAGS_HH__
843 code.write(str(target[0]))
845 flags = map(Value, trace_flags.values())
846 env.Command('base/traceflags.py', flags,
847 MakeAction(traceFlagsPy, " [ TRACING] $STRIP_TARGET"))
848 PySource('m5', 'base/traceflags.py')
850 env.Command('base/traceflags.hh', flags,
851 MakeAction(traceFlagsHH, " [ TRACING] $STRIP_TARGET"))
852 env.Command('base/traceflags.cc', flags,
853 MakeAction(traceFlagsCC, " [ TRACING] $STRIP_TARGET"))
854 Source('base/traceflags.cc')
856 # Embed python files. All .py files that have been indicated by a
857 # PySource() call in a SConscript need to be embedded into the M5
858 # library. To do that, we compile the file to byte code, marshal the
859 # byte code, compress it, and then generate a c++ file that
860 # inserts the result into an array.
861 def embedPyFile(target, source, env):
865 return '"%s"' % string
867 '''Action function to compile a .py into a code object, marshal
868 it, compress it, and stick it into an asm file so the code appears
869 as just bytes with a label in the data section'''
871 src = file(str(source[0]), 'r').read()
873 pysource = PySource.tnodes[source[0]]
874 compiled = compile(src, pysource.abspath, 'exec')
875 marshalled = marshal.dumps(compiled)
876 compressed = zlib.compress(marshalled)
878 sym = pysource.symname
880 code = code_formatter()
882 #include "sim/init.hh"
886 const char data_${sym}[] = {
890 for i in xrange(0, len(data), step):
891 x = array.array('B', data[i:i+step])
892 code(''.join('%d,' % d for d in x))
897 EmbeddedPython embedded_${sym}(
898 ${{c_str(pysource.arcname)}},
899 ${{c_str(pysource.abspath)}},
900 ${{c_str(pysource.modpath)}},
903 ${{len(marshalled)}});
905 } // anonymous namespace
907 code.write(str(target[0]))
909 for source in PySource.all:
910 env.Command(source.cpp, source.tnode,
911 MakeAction(embedPyFile, " [EMBED PY] $STRIP_TARGET"))
914 ########################################################################
916 # Define binaries. Each different build type (debug, opt, etc.) gets
917 # a slightly different build environment.
920 # List of constructed environments to pass back to SConstruct
923 date_source = Source('base/date.cc', skip_lib=True)
925 # Function to create a new build environment as clone of current
926 # environment 'env' with modified object suffix and optional stripped
927 # binary. Additional keyword arguments are appended to corresponding
928 # build environment vars.
929 def makeEnv(label, objsfx, strip = False, **kwargs):
930 # SCons doesn't know to append a library suffix when there is a '.' in the
931 # name. Use '_' instead.
932 libname = 'm5_' + label
933 exename = 'm5.' + label
935 new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's')
936 new_env.Label = label
937 new_env.Append(**kwargs)
939 swig_env = new_env.Clone()
940 swig_env.Append(CCFLAGS='-Werror')
942 swig_env.Append(CCFLAGS='-Wno-uninitialized')
943 swig_env.Append(CCFLAGS='-Wno-sign-compare')
944 swig_env.Append(CCFLAGS='-Wno-parentheses')
946 werror_env = new_env.Clone()
947 werror_env.Append(CCFLAGS='-Werror')
949 def make_obj(source, static, extra_deps = None):
950 '''This function adds the specified source to the correct
951 build environment, and returns the corresponding SCons Object
962 obj = env.StaticObject(source.tnode)
964 obj = env.SharedObject(source.tnode)
967 env.Depends(obj, extra_deps)
971 static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)]
972 shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)]
974 static_date = make_obj(date_source, static=True, extra_deps=static_objs)
975 static_objs.append(static_date)
977 shared_date = make_obj(date_source, static=False, extra_deps=shared_objs)
978 shared_objs.append(shared_date)
980 # First make a library of everything but main() so other programs can
982 static_lib = new_env.StaticLibrary(libname, static_objs)
983 shared_lib = new_env.SharedLibrary(libname, shared_objs)
985 for target, sources in unit_tests:
986 objs = [ make_obj(s, static=True) for s in sources ]
987 new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs)
989 # Now link a stub with main() and the static library.
990 bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ]
993 progname += '.unstripped'
995 targets = new_env.Program(progname, bin_objs + static_objs)
998 if sys.platform == 'sunos5':
999 cmd = 'cp $SOURCE $TARGET; strip $TARGET'
1001 cmd = 'strip $SOURCE -o $TARGET'
1002 targets = new_env.Command(exename, progname,
1003 MakeAction(cmd, " [ STRIP] $STRIP_TARGET"))
1005 new_env.M5Binary = targets[0]
1006 envList.append(new_env)
1011 if sys.platform == 'sunos5':
1012 ccflags['debug'] = '-gstabs+'
1014 ccflags['debug'] = '-ggdb3'
1015 ccflags['opt'] = '-g -O3'
1016 ccflags['fast'] = '-O3'
1017 ccflags['prof'] = '-O3 -g -pg'
1019 ccflags['debug'] = '-g0'
1020 ccflags['opt'] = '-g -O'
1021 ccflags['fast'] = '-fast'
1022 ccflags['prof'] = '-fast -g -pg'
1024 ccflags['debug'] = '-g -O0'
1025 ccflags['opt'] = '-g -O'
1026 ccflags['fast'] = '-fast'
1027 ccflags['prof'] = '-fast -g -pg'
1029 print 'Unknown compiler, please fix compiler options'
1032 makeEnv('debug', '.do',
1033 CCFLAGS = Split(ccflags['debug']),
1034 CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])
1037 makeEnv('opt', '.o',
1038 CCFLAGS = Split(ccflags['opt']),
1039 CPPDEFINES = ['TRACING_ON=1'])
1042 makeEnv('fast', '.fo', strip = True,
1043 CCFLAGS = Split(ccflags['fast']),
1044 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])
1047 makeEnv('prof', '.po',
1048 CCFLAGS = Split(ccflags['prof']),
1049 CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],