Deleted Added
sdiff udiff text old ( 5518:70caf53d9d7c ) new ( 5522:e56c3d89be79 )
full compact
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

--- 14 unchanged lines hidden (view full) ---

23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29# Authors: Nathan Binkert
30
31import array
32import imp
33import marshal
34import os
35import re
36import sys
37import zlib
38
39from os.path import basename, 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

--- 9 unchanged lines hidden (view full) ---

55 if isinstance(_list, list):
56 _list = _list[:]
57 else:
58 _list = list(_list)
59 _list.sort()
60 return _list
61
62class PySourceFile(object):
63 invalid_sym_char = re.compile('[^A-z0-9_]')
64 def __init__(self, package, source):
65 filename = str(source)
66 pyname = basename(filename)
67 assert pyname.endswith('.py')
68 name = pyname[:-3]
69 if package:
70 path = package.split('.')
71 else:
72 path = []
73 modpath = path
74 if name != '__init__':
75 modpath += [name]
76 modpath = '.'.join(modpath)
77
78 arcpath = path + [ pyname ]
79 arcname = joinpath(*arcpath)
80
81 self.tnode = source
82 self.snode = source.srcnode()
83 self.pyname = pyname
84 self.package = package
85 self.modpath = modpath
86 self.arcname = arcname
87 self.filename = filename
88 self.compiled = File(filename + 'c')
89 self.assembly = File(filename + '.s')
90 self.symname = "PyEMB_" + self.invalid_sym_char.sub('_', modpath)
91
92
93########################################################################
94# Code for adding source files of various types
95#
96cc_lib_sources = []
97def Source(source):
98 '''Add a source file to the libm5 build'''
99 if not isinstance(source, SCons.Node.FS.File):
100 source = File(source)
101
102 cc_lib_sources.append(source)
103
104cc_bin_sources = []
105def BinSource(source):
106 '''Add a source file to the m5 binary build'''
107 if not isinstance(source, SCons.Node.FS.File):
108 source = File(source)
109
110 cc_bin_sources.append(source)
111
112py_sources = []
113def PySource(package, source):
114 '''Add a python source file to the named package'''
115 if not isinstance(source, SCons.Node.FS.File):
116 source = File(source)
117
118 source = PySourceFile(package, source)
119 py_sources.append(source)

--- 21 unchanged lines hidden (view full) ---

141 '''Add a swig file to build'''
142 if not isinstance(source, SCons.Node.FS.File):
143 source = File(source)
144 val = source,package
145 swig_sources.append(val)
146
147# Children should have access
148Export('Source')
149Export('BinSource')
150Export('PySource')
151Export('SimObject')
152Export('SwigSource')
153
154########################################################################
155#
156# Trace Flags
157#

--- 114 unchanged lines hidden (view full) ---

272 mod.__file__ = srcfile
273
274 exec file(srcfile, 'r') in mod.__dict__
275
276 return mod
277
278py_modules = {}
279for source in py_sources:
280 py_modules[source.modpath] = source.snode.abspath
281
282# install the python importer so we can grab stuff from the source
283# tree itself. We can't have SimObjects added after this point or
284# else we won't know about them for the rest of the stuff.
285sim_objects_fixed = True
286importer = DictImporter(py_modules)
287sys.meta_path[0:0] = [ importer ]
288

--- 275 unchanged lines hidden (view full) ---

564
565# Generate the main swig init file
566def makeSwigInit(target, source, env):
567 f = file(str(target[0]), 'w')
568 print >>f, 'extern "C" {'
569 for module in source:
570 print >>f, ' void init_%s();' % module.get_contents()
571 print >>f, '}'
572 print >>f, 'void initSwig() {'
573 for module in source:
574 print >>f, ' init_%s();' % module.get_contents()
575 print >>f, '}'
576 f.close()
577
578env.Command('python/swig/init.cc', swig_modules, makeSwigInit)
579Source('python/swig/init.cc')
580
581# Generate traceflags.py
582def traceFlagsPy(target, source, env):
583 assert(len(target) == 1)
584
585 f = file(str(target[0]), 'w')
586
587 allFlags = []

--- 222 unchanged lines hidden (view full) ---

810 print "in except"
811 gen_file(target, "Unknown", "Unknown", "Unknown")
812 mercurial.demandimport.disable()
813
814env.Command('base/program_info.cc',
815 Value(str(SCons.Node.FS.default_fs.SConstruct_dir)),
816 programInfo)
817
818# embed python files. All .py files that have been indicated by a
819# PySource() call in a SConscript need to be embedded into the M5
820# library. To do that, we compile the file to byte code, marshal the
821# byte code, compress it, and then generate an assembly file that
822# inserts the result into the data section with symbols indicating the
823# beginning, and end (and with the size at the end)
824py_sources_tnodes = {}
825for pysource in py_sources:
826 py_sources_tnodes[pysource.tnode] = pysource
827
828def objectifyPyFile(target, source, env):
829 '''Action function to compile a .py into a code object, marshal
830 it, compress it, and stick it into an asm file so the code appears
831 as just bytes with a label in the data section'''
832
833 src = file(str(source[0]), 'r').read()
834 dst = file(str(target[0]), 'w')
835
836 pysource = py_sources_tnodes[source[0]]
837 compiled = compile(src, pysource.snode.path, 'exec')
838 marshalled = marshal.dumps(compiled)
839 compressed = zlib.compress(marshalled)
840 data = compressed
841
842 # Some C/C++ compilers prepend an underscore to global symbol
843 # names, so if they're going to do that, we need to prepend that
844 # leading underscore to globals in the assembly file.
845 if env['LEADING_UNDERSCORE']:
846 sym = '_' + pysource.symname
847 else:
848 sym = pysource.symname
849
850 step = 16
851 print >>dst, ".data"
852 print >>dst, ".globl %s_beg" % sym
853 print >>dst, ".globl %s_end" % sym
854 print >>dst, "%s_beg:" % sym
855 for i in xrange(0, len(data), step):
856 x = array.array('B', data[i:i+step])
857 print >>dst, ".byte", ','.join([str(d) for d in x])
858 print >>dst, "%s_end:" % sym
859 print >>dst, ".long %d" % len(marshalled)
860
861for source in py_sources:
862 env.Command(source.assembly, source.tnode, objectifyPyFile)
863 Source(source.assembly)
864
865# Generate init_python.cc which creates a bunch of EmbeddedPyModule
866# structs that describe the embedded python code. One such struct
867# contains information about the importer that python uses to get at
868# the embedded files, and then there's a list of all of the rest that
869# the importer uses to load the rest on demand.
870py_sources_symbols = {}
871for pysource in py_sources:
872 py_sources_symbols[pysource.symname] = pysource
873def pythonInit(target, source, env):
874 dst = file(str(target[0]), 'w')
875
876 def dump_mod(sym, endchar=','):
877 pysource = py_sources_symbols[sym]
878 print >>dst, ' { "%s",' % pysource.arcname
879 print >>dst, ' "%s",' % pysource.modpath
880 print >>dst, ' %s_beg, %s_end,' % (sym, sym)
881 print >>dst, ' %s_end - %s_beg,' % (sym, sym)
882 print >>dst, ' *(int *)%s_end }%s' % (sym, endchar)
883
884 print >>dst, '#include "sim/init.hh"'
885
886 for sym in source:
887 sym = sym.get_contents()
888 print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym)
889
890 print >>dst, "const EmbeddedPyModule embeddedPyImporter = "
891 dump_mod("PyEMB_importer", endchar=';');
892 print >>dst
893
894 print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {"
895 for i,sym in enumerate(source):
896 sym = sym.get_contents()
897 if sym == "PyEMB_importer":
898 # Skip the importer since we've already exported it
899 continue
900 dump_mod(sym)
901 print >>dst, " { 0, 0, 0, 0, 0, 0 }"
902 print >>dst, "};"
903
904symbols = [Value(s.symname) for s in py_sources]
905env.Command('sim/init_python.cc', symbols, pythonInit)
906Source('sim/init_python.cc')
907
908########################################################################
909#
910# Define binaries. Each different build type (debug, opt, etc.) gets
911# a slightly different build environment.
912#
913
914# List of constructed environments to pass back to SConstruct
915envList = []

--- 23 unchanged lines hidden (view full) ---

939# Function to create a new build environment as clone of current
940# environment 'env' with modified object suffix and optional stripped
941# binary. Additional keyword arguments are appended to corresponding
942# build environment vars.
943def makeEnv(label, objsfx, strip = False, **kwargs):
944 newEnv = env.Copy(OBJSUFFIX=objsfx)
945 newEnv.Label = label
946 newEnv.Append(**kwargs)
947
948 # First make a library of everything but main() so other programs can
949 # link against m5.
950 #
951 # SCons doesn't know to append a library suffix when there is a '.' in the
952 # name. Use '_' instead.
953 m5lib = newEnv.Library('m5_' + label, make_objs(cc_lib_sources, newEnv))
954
955 # Now link a stub with main() and the library.
956 exe = 'm5.' + label # final executable
957 objects = [newEnv.Object(s) for s in cc_bin_sources] + m5lib
958 if strip:
959 unstripped_exe = exe + '.unstripped'
960 newEnv.Program(unstripped_exe, objects)
961 if sys.platform == 'sunos5':
962 cmd = 'cp $SOURCE $TARGET; strip $TARGET'
963 else:
964 cmd = 'strip $SOURCE -o $TARGET'
965 targets = newEnv.Command(exe, unstripped_exe, cmd)
966 else:
967 targets = newEnv.Program(exe, objects)
968
969 newEnv.M5Binary = targets[0]
970 envList.append(newEnv)
971
972# Debug binary
973ccflags = {}
974if env['GCC']:
975 if sys.platform == 'sunos5':
976 ccflags['debug'] = '-gstabs+'

--- 40 unchanged lines hidden ---