| # -*- 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) |