6b167552e5dc0e9f5f9c7e09b63f6ad39ea570da
1 # Copyright (c) 2004-2006 The Regents of The University of Michigan
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met: redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer;
8 # redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution;
11 # neither the name of the copyright holders nor the names of its
12 # contributors may be used to endorse or promote products derived from
13 # this software without specific prior written permission.
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 # Authors: Nathan Binkert
34 from os
.path
import basename
35 from os
.path
import exists
37 class DictImporter(object):
38 '''This importer takes a dictionary of arbitrary module names that
39 map to arbitrary filenames.'''
40 def __init__(self
, modules
, build_env
):
41 self
.modules
= modules
42 self
.installed
= set()
43 self
.build_env
= build_env
49 for module
in self
.installed
:
50 del sys
.modules
[module
]
52 def find_module(self
, fullname
, path
):
53 if fullname
== '__scons':
56 if fullname
== 'm5.objects':
59 if fullname
.startswith('m5.internal'):
62 if fullname
in self
.modules
and exists(self
.modules
[fullname
]):
67 def load_module(self
, fullname
):
68 mod
= imp
.new_module(fullname
)
69 sys
.modules
[fullname
] = mod
70 self
.installed
.add(fullname
)
73 if fullname
== 'm5.objects':
74 mod
.__path
__ = fullname
.split('.')
77 if fullname
== '__scons':
78 mod
.__dict
__['m5_build_env'] = self
.build_env
81 srcfile
= self
.modules
[fullname
]
82 if basename(srcfile
) == '__init__.py':
83 mod
.__path
__ = fullname
.split('.')
84 mod
.__file
__ = srcfile
86 exec file(srcfile
, 'r') in mod
.__dict
__
90 class ordered_dict(dict):
92 keys
= super(ordered_dict
, self
).keys()
97 return [ self
[key
] for key
in self
.keys() ]
100 return [ (key
,self
[key
]) for key
in self
.keys() ]
103 for key
in self
.keys():
106 def itervalues(self
):
107 for value
in self
.values():
111 for key
,value
in self
.items():
114 class Generate(object):
115 def __init__(self
, py_sources
, sim_objects
, build_env
):
116 self
.py_sources
= py_sources
118 for source
in py_sources
:
119 self
.py_modules
[source
.modpath
] = source
.srcpath
121 importer
= DictImporter(self
.py_modules
, build_env
)
123 # install the python importer so we can grab stuff from the source
125 sys
.meta_path
[0:0] = [ importer
]
130 # import all sim objects so we can populate the all_objects list
131 # make sure that we're working with a list, then let's sort it
132 sim_objects
= list(sim_objects
)
134 for simobj
in sim_objects
:
135 exec('from m5.objects import %s' % simobj
)
137 # we need to unload all of the currently imported modules so that they
138 # will be re-imported the next time the sconscript is run
140 sys
.meta_path
.remove(importer
)
142 self
.sim_objects
= m5
.SimObject
.allClasses
143 self
.enums
= m5
.params
.allEnums
146 for name
,obj
in self
.sim_objects
.iteritems():
147 for param
in obj
._params
.local
.values():
148 if not hasattr(param
, 'swig_decl'):
150 pname
= param
.ptype_str
151 if pname
not in self
.params
:
152 self
.params
[pname
] = param
154 def createSimObjectParam(self
, target
, source
, env
):
155 assert len(target
) == 1 and len(source
) == 1
157 hh_file
= file(target
[0].abspath
, 'w')
158 name
= str(source
[0].get_contents())
159 obj
= self
.sim_objects
[name
]
161 print >>hh_file
, obj
.cxx_decl()
163 # Generate Python file containing a dict specifying the current
165 def makeDefinesPyFile(self
, target
, source
, env
):
166 f
= file(str(target
[0]), 'w')
167 print >>f
, "m5_build_env = ", source
[0]
170 # Generate python file containing info about the M5 source code
171 def makeInfoPyFile(self
, target
, source
, env
):
172 f
= file(str(target
[0]), 'w')
174 data
= ''.join(file(src
.srcnode().abspath
, 'r').xreadlines())
175 print >>f
, "%s = %s" % (src
, repr(data
))
178 # Generate the __init__.py file for m5.objects
179 def makeObjectsInitFile(self
, target
, source
, env
):
180 f
= file(str(target
[0]), 'w')
181 print >>f
, 'from params import *'
182 print >>f
, 'from m5.SimObject import *'
183 for module
in source
:
184 print >>f
, 'from %s import *' % module
.get_contents()
187 def createSwigParam(self
, target
, source
, env
):
188 assert len(target
) == 1 and len(source
) == 1
190 i_file
= file(target
[0].abspath
, 'w')
191 name
= str(source
[0].get_contents())
192 param
= self
.params
[name
]
194 for line
in param
.swig_decl():
197 def createEnumStrings(self
, target
, source
, env
):
198 assert len(target
) == 1 and len(source
) == 1
200 cc_file
= file(target
[0].abspath
, 'w')
201 name
= str(source
[0].get_contents())
202 obj
= self
.enums
[name
]
204 print >>cc_file
, obj
.cxx_def()
207 def createEnumParam(self
, target
, source
, env
):
208 assert len(target
) == 1 and len(source
) == 1
210 hh_file
= file(target
[0].abspath
, 'w')
211 name
= str(source
[0].get_contents())
212 obj
= self
.enums
[name
]
214 print >>hh_file
, obj
.cxx_decl()
216 def buildParams(self
, target
, source
, env
):
217 names
= [ s
.get_contents() for s
in source
]
218 objs
= [ self
.sim_objects
[name
] for name
in names
]
219 out
= file(target
[0].abspath
, 'w')
229 if str(obj
) != 'SimObject':
230 order_obj(obj
.__bases
__[0])
232 ordered_objs
.append(obj
)
243 if pd
not in pd_seen
:
247 for obj
in ordered_objs
:
248 params
= obj
._params
.local
.values()
251 if issubclass(ptype
, self
.m5
.params
.Enum
):
252 if ptype
not in enums
:
254 pds
= param
.swig_predecls()
255 if isinstance(pds
, (list, tuple)):
260 print >>out
, '%module params'
263 for obj
in ordered_objs
:
264 print >>out
, '#include "params/%s.hh"' % obj
273 print >>out
, '%%include "enums/%s.hh"' % enum
.__name
__
276 for obj
in ordered_objs
:
277 if obj
.swig_objdecls
:
278 for decl
in obj
.swig_objdecls
:
283 base
= obj
.get_base()
285 code
+= '// stop swig from creating/wrapping default ctor/dtor\n'
286 code
+= '%%nodefault %s;\n' % obj
.cxx_class
287 code
+= 'class %s ' % obj
.cxx_class
289 code
+= ': public %s' % base
292 klass
= obj
.cxx_class
;
293 if hasattr(obj
, 'cxx_namespace'):
294 new_code
= 'namespace %s {\n' % obj
.cxx_namespace
298 klass
= '%s::%s' % (obj
.cxx_namespace
, klass
)
302 for obj
in ordered_objs
:
303 print >>out
, '%%include "params/%s.hh"' % obj
305 def makeSwigInit(self
, target
, source
, env
):
306 f
= file(str(target
[0]), 'w')
307 print >>f
, 'extern "C" {'
308 for module
in source
:
309 print >>f
, ' void init_%s();' % module
.get_contents()
311 print >>f
, 'void init_swig() {'
312 for module
in source
:
313 print >>f
, ' init_%s();' % module
.get_contents()
317 def compilePyFile(self
, target
, source
, env
):
318 '''Action function to compile a .py into a .pyc'''
319 py_compile
.compile(str(source
[0]), str(target
[0]))
321 def buildPyZip(self
, target
, source
, env
):
322 '''Action function to build the zip archive. Uses the
323 PyZipFile module included in the standard Python library.'''
326 for s
in self
.py_sources
:
327 compname
= str(s
.compiled
)
328 assert compname
not in py_compiled
329 py_compiled
[compname
] = s
331 zf
= zipfile
.ZipFile(str(target
[0]), 'w')
334 arcname
= py_compiled
[zipname
].arcname
335 zf
.write(zipname
, arcname
)