# -*- mode:python -*- # Copyright (c) 2004-2005 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer; # redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution; # neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os, os.path, re, sys Import('env') import scons_helper def WriteEmbeddedPyFile(target, source, path, name, ext, filename): if isinstance(source, str): source = file(source, 'r') if isinstance(target, str): target = file(target, 'w') print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \ (`path`, `name`, `ext`, `filename`) for line in source: line = line # escape existing backslashes line = line.replace('\\', '\\\\') # escape existing triple quotes line = line.replace("'''", r"\'\'\'") print >>target, line, print >>target, "''')" print >>target def WriteCFile(target, source, name): if isinstance(source, str): source = file(source, 'r') if isinstance(target, str): target = file(target, 'w') print >>target, 'const char %s_string[] = {' % name count = 0 from array import array try: while True: foo = array('B') foo.fromfile(source, 10000) l = [ str(i) for i in foo.tolist() ] count += len(l) for i in xrange(0,9999,20): print >>target, ','.join(l[i:i+20]) + ',' except EOFError: l = [ str(i) for i in foo.tolist() ] count += len(l) for i in xrange(0,len(l),20): print >>target, ','.join(l[i:i+20]) + ',' print >>target, ','.join(l[i:]) + ',' print >>target, '};' print >>target, 'const int %s_length = %d;' % (name, count) print >>target def splitpath(path): dir,file = os.path.split(path) path = [] assert(file) while dir: dir,base = os.path.split(dir) path.insert(0, base) return path, file def MakeEmbeddedPyFile(target, source, env): target = file(str(target[0]), 'w') tree = {} for src in source: src = str(src) path,pyfile = splitpath(src) node = tree for dir in path: if not node.has_key(dir): node[dir] = { } node = node[dir] name,ext = pyfile.split('.') if name == '__init__': node['.hasinit'] = True node[pyfile] = (src,name,ext,src) done = False while not done: done = True for name,entry in tree.items(): if not isinstance(entry, dict): continue if entry.has_key('.hasinit'): continue done = False del tree[name] for key,val in entry.iteritems(): if tree.has_key(key): raise NameError, \ "dir already has %s can't add it again" % key tree[key] = val files = [] def populate(node, path = []): names = node.keys() names.sort() for name in names: if name == '.hasinit': continue entry = node[name] if isinstance(entry, dict): if not entry.has_key('.hasinit'): raise NameError, 'package directory missing __init__.py' populate(entry, path + [ name ]) else: pyfile,name,ext,filename = entry files.append((pyfile, path, name, ext, filename)) populate(tree) for pyfile, path, name, ext, filename in files: WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename) def MakeDefinesPyFile(target, source, env): f = file(str(target[0]), 'w') print >>f, "import __main__" print >>f, "__main__.m5_build_env = ", print >>f, source[0] f.close() CFileCounter = 0 def MakePythonCFile(target, source, env): global CFileCounter target = file(str(target[0]), 'w') print >>target, '''\ #include "base/embedfile.hh" namespace { ''' for src in source: src = str(src) fname = os.path.basename(src) name = 'embedded_file%d' % CFileCounter CFileCounter += 1 WriteCFile(target, src, name) print >>target, '''\ EmbedMap %(name)s("%(fname)s", %(name)s_string, %(name)s_length); ''' % locals() print >>target, '''\ /* namespace */ } ''' # base list of .py files to embed embedded_py_files = [ '../util/pbs/jobfile.py' ] # add all .py files in python/m5 objpath = os.path.join(env['SRCDIR'], 'python', 'm5') for root, dirs, files in os.walk(objpath, topdown=True): for i,dir in enumerate(dirs): if dir == 'SCCS': del dirs[i] break assert(root.startswith(objpath)) for f in files: if f.endswith('.py'): embedded_py_files.append(os.path.join(root, f)) embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh') optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions]) env.Command('defines.py', Value(optionDict), MakeDefinesPyFile) env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile) env.Depends('embedded_py.cc', embedfile_hh) env.Command('embedded_py.cc', ['string_importer.py', 'defines.py', 'embedded_py.py'], MakePythonCFile)