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 tags can be 63# specified for that file. |
64 |
65class SourceList(list): 66 def with_tags_that(self, predicate): 67 '''Return a list of sources with tags that satisfy a predicate.''' 68 def match(source): 69 return predicate(source.tags) 70 return SourceList(filter(match, self)) 71 72 def with_any_tags(self, *tags): 73 '''Return a list of sources with any of the supplied tags.''' 74 return self.with_tags_that(lambda stags: len(tags & stags) > 0) 75 76 def with_all_tags(self, *tags): 77 '''Return a list of sources with all of the supplied tags.''' 78 return self.with_tags_that(lambda stags: tags <= stags) 79 80 def with_tag(self, tag): 81 '''Return a list of sources with the supplied tag.''' 82 return self.with_tags_that(lambda stags: tag in stags) 83 84 def without_tags(self, *tags): 85 '''Return a list of sources without any of the supplied tags.''' 86 return self.with_tags_that(lambda stags: len(tags & stags) == 0) 87 88 def without_tag(self, tag): 89 '''Return a list of sources with the supplied tag.''' 90 return self.with_tags_that(lambda stags: tag not in stags) 91 |
92class SourceMeta(type): 93 '''Meta class for source files that keeps track of all files of a |
94 particular type.''' |
95 def __init__(cls, name, bases, dict): 96 super(SourceMeta, cls).__init__(name, bases, dict) |
97 cls.all = SourceList() |
98 |
99class SourceFile(object): 100 '''Base object that encapsulates the notion of a source file. 101 This includes, the source node, target node, various manipulations |
102 of those. A source file also specifies a set of tags which 103 describing arbitrary properties of the source file.''' |
104 __metaclass__ = SourceMeta |
105 def __init__(self, source, tags=None, add_tags=None): 106 if tags is None: 107 tags='gem5 lib' 108 if isinstance(tags, basestring): 109 tags = set([tags]) 110 if isinstance(add_tags, basestring): 111 add_tags = set([add_tags]) 112 if add_tags: 113 tags = tags | add_tags 114 self.tags = set(tags) |
115 116 tnode = source 117 if not isinstance(source, SCons.Node.FS.File): 118 tnode = File(source) 119 120 self.tnode = tnode 121 self.snode = tnode.srcnode() 122 --- 17 unchanged lines hidden (view full) --- 140 def extname(self): 141 index = self.basename.rfind('.') 142 if index <= 0: 143 # dot files aren't extensions 144 return self.basename, None 145 146 return self.basename[:index], self.basename[index+1:] 147 |
148 def __lt__(self, other): return self.filename < other.filename 149 def __le__(self, other): return self.filename <= other.filename 150 def __gt__(self, other): return self.filename > other.filename 151 def __ge__(self, other): return self.filename >= other.filename 152 def __eq__(self, other): return self.filename == other.filename 153 def __ne__(self, other): return self.filename != other.filename 154 155 @staticmethod 156 def done(): 157 def disabled(cls, name, *ignored): 158 raise RuntimeError("Additional SourceFile '%s'" % name,\ 159 "declared, but targets deps are already fixed.") 160 SourceFile.__init__ = disabled 161 162 163class Source(SourceFile): |
164 ungrouped_tag = 'No link group' 165 source_groups = set() |
166 |
167 _current_group_tag = ungrouped_tag 168 169 @staticmethod 170 def link_group_tag(group): 171 return 'link group: %s' % group 172 |
173 @classmethod 174 def set_group(cls, group): |
175 new_tag = Source.link_group_tag(group) 176 Source._current_group_tag = new_tag 177 Source.source_groups.add(group) |
178 |
179 def _add_link_group_tag(self): 180 self.tags.add(Source._current_group_tag) |
181 |
182 '''Add a c/c++ source file to the build''' 183 def __init__(self, source, tags=None, add_tags=None, Werror=True): 184 '''specify the source file, and any tags''' 185 super(Source, self).__init__(source, tags, add_tags) 186 self._add_link_group_tag() |
187 self.Werror = Werror 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, tags=None, add_tags=None): 197 '''specify the python package, the source file, and any tags''' 198 super(PySource, self).__init__(source, tags, add_tags) |
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, tags=None, add_tags=None): 239 '''Specify the source file and any tags (automatically in |
240 the m5.objects package)''' |
241 super(SimObject, self).__init__('m5.objects', source, tags, add_tags) |
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, tags=None, add_tags=None): 251 '''Specify the source file, and any tags''' 252 super(ProtoBuf, self).__init__(source, tags, add_tags) |
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 tagged with the name of the UnitTest target.''' |
271 |
272 srcs = SourceList() |
273 for src in sources: 274 if not isinstance(src, SourceFile): |
275 src = Source(src, tags=str(target)) |
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 --- 479 unchanged lines hidden (view full) --- 763 # specify the proto_path to avoid having the generated files 764 # include the path. 765 env.Command([proto.cc_file, proto.hh_file], proto.tnode, 766 MakeAction('$PROTOC --cpp_out ${TARGET.dir} ' 767 '--proto_path ${SOURCE.dir} $SOURCE', 768 Transform("PROTOC"))) 769 770 # Add the C++ source file |
771 Source(proto.cc_file, tags=proto.tags) |
772elif ProtoBuf.all: 773 print 'Got protobuf to build, but lacks support!' 774 Exit(1) 775 776# 777# Handle debug flags 778# 779def makeDebugFlagCC(target, source, env): --- 149 unchanged lines hidden (view full) --- 929 930} // anonymous namespace 931''') 932 code.write(str(target[0])) 933 934for source in PySource.all: 935 env.Command(source.cpp, source.tnode, 936 MakeAction(embedPyFile, Transform("EMBED PY"))) |
937 Source(source.cpp, tags=source.tags, add_tags='python') |
938 939######################################################################## 940# 941# Define binaries. Each different build type (debug, opt, etc.) gets 942# a slightly different build environment. 943# 944 945# List of constructed environments to pass back to SConstruct |
946date_source = Source('base/date.cc', tags=[]) |
947 948# Function to create a new build environment as clone of current 949# environment 'env' with modified object suffix and optional stripped 950# binary. Additional keyword arguments are appended to corresponding 951# build environment vars. 952def makeEnv(env, label, objsfx, strip=False, disable_partial=False, **kwargs): 953 # SCons doesn't know to append a library suffix when there is a '.' in the 954 # name. Use '_' instead. --- 66 unchanged lines hidden (view full) --- 1021 else: 1022 obj = env.SharedObject(source.tnode) 1023 1024 if extra_deps: 1025 env.Depends(obj, extra_deps) 1026 1027 return obj 1028 |
1029 lib_sources = Source.all.with_tag('gem5 lib') |
1030 1031 # Without Python, leave out all Python content from the library 1032 # builds. The option doesn't affect gem5 built as a program 1033 if GetOption('without_python'): |
1034 lib_sources = lib_sources.without_tag('python') |
1035 1036 static_objs = [] 1037 shared_objs = [] |
1038 1039 for s in lib_sources.with_tag(Source.ungrouped_tag): |
1040 static_objs.append(make_obj(s, True)) 1041 shared_objs.append(make_obj(s, False)) 1042 1043 partial_objs = [] |
1044 |
1045 for group in Source.source_groups: 1046 srcs = lib_sources.with_tag(Source.link_group_tag(group)) |
1047 if not srcs: 1048 continue 1049 1050 # If partial linking is disabled, add these sources to the build 1051 # directly, and short circuit this loop. 1052 if disable_partial: 1053 for s in srcs: 1054 static_objs.append(make_obj(s, True)) --- 21 unchanged lines hidden (view full) --- 1076 shared_objs.append(shared_date) 1077 1078 # First make a library of everything but main() so other programs can 1079 # link against m5. 1080 static_lib = new_env.StaticLibrary(libname, static_objs) 1081 shared_lib = new_env.SharedLibrary(libname, shared_objs) 1082 1083 # Now link a stub with main() and the static library. |
1084 main_objs = [ make_obj(s, True) for s in Source.all.with_tag('main') ] |
1085 1086 for test in UnitTest.all: |
1087 test_sources = Source.all.with_tag(str(test.target)) |
1088 test_objs = [ make_obj(s, static=True) for s in test_sources ] 1089 if test.main: 1090 test_objs += main_objs 1091 path = 'unittest/%s.%s' % (test.target, label) 1092 new_env.Program(path, test_objs + static_objs) 1093 1094 progname = exename 1095 if strip: --- 124 unchanged lines hidden --- |