Deleted Added
sdiff udiff text old ( 12246:9ffa51416f39 ) new ( 12302:5771c4c65b23 )
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

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

54
55build_env = [(opt, env[opt]) for opt in export_vars]
56
57from m5.util import code_formatter, compareVersions
58
59########################################################################
60# Code for adding source files of various types
61#
62# When specifying a source file of some type, a set of guards can be
63# specified for that file. When get() is used to find the files, if
64# get specifies a set of filters, only files that match those filters
65# will be accepted (unspecified filters on files are assumed to be
66# false). Current filters are:
67# main -- specifies the gem5 main() function
68# skip_lib -- do not put this file into the gem5 library
69# skip_no_python -- do not put this file into a no_python library
70# as it embeds compiled Python
71# <unittest> -- unit tests use filters based on the unit test name
72#
73# A parent can now be specified for a source file and default filter
74# values will be retrieved recursively from parents (children override
75# parents).
76#
77def guarded_source_iterator(sources, **guards):
78 '''Iterate over a set of sources, gated by a set of guards.'''
79 for src in sources:
80 for flag,value in guards.iteritems():
81 # if the flag is found and has a different value, skip
82 # this file
83 if src.all_guards.get(flag, False) != value:
84 break
85 else:
86 yield src
87
88class SourceMeta(type):
89 '''Meta class for source files that keeps track of all files of a
90 particular type and has a get function for finding all functions
91 of a certain type that match a set of guards'''
92 def __init__(cls, name, bases, dict):
93 super(SourceMeta, cls).__init__(name, bases, dict)
94 cls.all = []
95
96 def get(cls, **guards):
97 '''Find all files that match the specified guards. If a source
98 file does not specify a flag, the default is False'''
99 for s in guarded_source_iterator(cls.all, **guards):
100 yield s
101
102class SourceFile(object):
103 '''Base object that encapsulates the notion of a source file.
104 This includes, the source node, target node, various manipulations
105 of those. A source file also specifies a set of guards which
106 describing which builds the source file applies to. A parent can
107 also be specified to get default guards from'''
108 __metaclass__ = SourceMeta
109 def __init__(self, source, parent=None, **guards):
110 self.guards = guards
111 self.parent = parent
112
113 tnode = source
114 if not isinstance(source, SCons.Node.FS.File):
115 tnode = File(source)
116
117 self.tnode = tnode
118 self.snode = tnode.srcnode()
119

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

137 def extname(self):
138 index = self.basename.rfind('.')
139 if index <= 0:
140 # dot files aren't extensions
141 return self.basename, None
142
143 return self.basename[:index], self.basename[index+1:]
144
145 @property
146 def all_guards(self):
147 '''find all guards for this object getting default values
148 recursively from its parents'''
149 guards = {}
150 if self.parent:
151 guards.update(self.parent.guards)
152 guards.update(self.guards)
153 return guards
154
155 def __lt__(self, other): return self.filename < other.filename
156 def __le__(self, other): return self.filename <= other.filename
157 def __gt__(self, other): return self.filename > other.filename
158 def __ge__(self, other): return self.filename >= other.filename
159 def __eq__(self, other): return self.filename == other.filename
160 def __ne__(self, other): return self.filename != other.filename
161
162 @staticmethod
163 def done():
164 def disabled(cls, name, *ignored):
165 raise RuntimeError("Additional SourceFile '%s'" % name,\
166 "declared, but targets deps are already fixed.")
167 SourceFile.__init__ = disabled
168
169
170class Source(SourceFile):
171 current_group = None
172 source_groups = { None : [] }
173
174 @classmethod
175 def set_group(cls, group):
176 if not group in Source.source_groups:
177 Source.source_groups[group] = []
178 Source.current_group = group
179
180 '''Add a c/c++ source file to the build'''
181 def __init__(self, source, Werror=True, **guards):
182 '''specify the source file, and any guards'''
183 super(Source, self).__init__(source, **guards)
184
185 self.Werror = Werror
186
187 Source.source_groups[Source.current_group].append(self)
188
189class PySource(SourceFile):
190 '''Add a python source file to the named package'''
191 invalid_sym_char = re.compile('[^A-z0-9_]')
192 modules = {}
193 tnodes = {}
194 symnames = {}
195
196 def __init__(self, package, source, **guards):
197 '''specify the python package, the source file, and any guards'''
198 super(PySource, self).__init__(source, **guards)
199
200 modname,ext = self.extname
201 assert ext == 'py'
202
203 if package:
204 path = package.split('.')
205 else:
206 path = []

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

230
231class SimObject(PySource):
232 '''Add a SimObject python file as a python source object and add
233 it to a list of sim object modules'''
234
235 fixed = False
236 modnames = []
237
238 def __init__(self, source, **guards):
239 '''Specify the source file and any guards (automatically in
240 the m5.objects package)'''
241 super(SimObject, self).__init__('m5.objects', source, **guards)
242 if self.fixed:
243 raise AttributeError, "Too late to call SimObject now."
244
245 bisect.insort_right(SimObject.modnames, self.modname)
246
247class ProtoBuf(SourceFile):
248 '''Add a Protocol Buffer to build'''
249
250 def __init__(self, source, **guards):
251 '''Specify the source file, and any guards'''
252 super(ProtoBuf, self).__init__(source, **guards)
253
254 # Get the file name and the extension
255 modname,ext = self.extname
256 assert ext == 'proto'
257
258 # Currently, we stick to generating the C++ headers, so we
259 # only need to track the source and header.
260 self.cc_file = File(modname + '.pb.cc')
261 self.hh_file = File(modname + '.pb.h')
262
263class UnitTest(object):
264 '''Create a UnitTest'''
265
266 all = []
267 def __init__(self, target, *sources, **kwargs):
268 '''Specify the target name and any sources. Sources that are
269 not SourceFiles are evalued with Source(). All files are
270 guarded with a guard of the same name as the UnitTest
271 target.'''
272
273 srcs = []
274 for src in sources:
275 if not isinstance(src, SourceFile):
276 src = Source(src, skip_lib=True)
277 src.guards[target] = True
278 srcs.append(src)
279
280 self.sources = srcs
281 self.target = target
282 self.main = kwargs.get('main', False)
283 UnitTest.all.append(self)
284
285# Children should have access

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

765 # specify the proto_path to avoid having the generated files
766 # include the path.
767 env.Command([proto.cc_file, proto.hh_file], proto.tnode,
768 MakeAction('$PROTOC --cpp_out ${TARGET.dir} '
769 '--proto_path ${SOURCE.dir} $SOURCE',
770 Transform("PROTOC")))
771
772 # Add the C++ source file
773 Source(proto.cc_file, **proto.guards)
774elif ProtoBuf.all:
775 print 'Got protobuf to build, but lacks support!'
776 Exit(1)
777
778#
779# Handle debug flags
780#
781def makeDebugFlagCC(target, source, env):

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

931
932} // anonymous namespace
933''')
934 code.write(str(target[0]))
935
936for source in PySource.all:
937 env.Command(source.cpp, source.tnode,
938 MakeAction(embedPyFile, Transform("EMBED PY")))
939 Source(source.cpp, skip_no_python=True)
940
941########################################################################
942#
943# Define binaries. Each different build type (debug, opt, etc.) gets
944# a slightly different build environment.
945#
946
947# List of constructed environments to pass back to SConstruct
948date_source = Source('base/date.cc', skip_lib=True)
949
950# Function to create a new build environment as clone of current
951# environment 'env' with modified object suffix and optional stripped
952# binary. Additional keyword arguments are appended to corresponding
953# build environment vars.
954def makeEnv(env, label, objsfx, strip=False, disable_partial=False, **kwargs):
955 # SCons doesn't know to append a library suffix when there is a '.' in the
956 # name. Use '_' instead.

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

1023 else:
1024 obj = env.SharedObject(source.tnode)
1025
1026 if extra_deps:
1027 env.Depends(obj, extra_deps)
1028
1029 return obj
1030
1031 lib_guards = {'main': False, 'skip_lib': False}
1032
1033 # Without Python, leave out all Python content from the library
1034 # builds. The option doesn't affect gem5 built as a program
1035 if GetOption('without_python'):
1036 lib_guards['skip_no_python'] = False
1037
1038 static_objs = []
1039 shared_objs = []
1040 for s in guarded_source_iterator(Source.source_groups[None], **lib_guards):
1041 static_objs.append(make_obj(s, True))
1042 shared_objs.append(make_obj(s, False))
1043
1044 partial_objs = []
1045 for group, all_srcs in Source.source_groups.iteritems():
1046 # If these are the ungrouped source files, skip them.
1047 if not group:
1048 continue
1049
1050 # Get a list of the source files compatible with the current guards.
1051 srcs = [ s for s in guarded_source_iterator(all_srcs, **lib_guards) ]
1052 # If there aren't any left, skip this group.
1053 if not srcs:
1054 continue
1055
1056 # If partial linking is disabled, add these sources to the build
1057 # directly, and short circuit this loop.
1058 if disable_partial:
1059 for s in srcs:
1060 static_objs.append(make_obj(s, True))

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

1082 shared_objs.append(shared_date)
1083
1084 # First make a library of everything but main() so other programs can
1085 # link against m5.
1086 static_lib = new_env.StaticLibrary(libname, static_objs)
1087 shared_lib = new_env.SharedLibrary(libname, shared_objs)
1088
1089 # Now link a stub with main() and the static library.
1090 main_objs = [ make_obj(s, True) for s in Source.get(main=True) ]
1091
1092 for test in UnitTest.all:
1093 flags = { test.target : True }
1094 test_sources = Source.get(**flags)
1095 test_objs = [ make_obj(s, static=True) for s in test_sources ]
1096 if test.main:
1097 test_objs += main_objs
1098 path = 'unittest/%s.%s' % (test.target, label)
1099 new_env.Program(path, test_objs + static_objs)
1100
1101 progname = exename
1102 if strip:

--- 124 unchanged lines hidden ---