SConscript revision 1858
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 9# notice, this list of conditions and the following disclaimer; 10# redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution; 13# neither the name of the copyright holders nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29import os, os.path, re, sys 30 31Import('env') 32 33import scons_helper 34 35def WriteEmbeddedPyFile(target, source, path, name, ext, filename): 36 if isinstance(source, str): 37 source = file(source, 'r') 38 39 if isinstance(target, str): 40 target = file(target, 'w') 41 42 print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \ 43 (`path`, `name`, `ext`, `filename`) 44 45 for line in source: 46 line = line 47 # escape existing backslashes 48 line = line.replace('\\', '\\\\') 49 # escape existing triple quotes 50 line = line.replace("'''", r"\'\'\'") 51 52 print >>target, line, 53 54 print >>target, "''')" 55 print >>target 56 57def WriteCFile(target, source, name): 58 if isinstance(source, str): 59 source = file(source, 'r') 60 61 if isinstance(target, str): 62 target = file(target, 'w') 63 64 print >>target, 'const char %s_string[] = {' % name 65 66 count = 0 67 from array import array 68 try: 69 while True: 70 foo = array('B') 71 foo.fromfile(source, 10000) 72 l = [ str(i) for i in foo.tolist() ] 73 count += len(l) 74 for i in xrange(0,9999,20): 75 print >>target, ','.join(l[i:i+20]) + ',' 76 except EOFError: 77 l = [ str(i) for i in foo.tolist() ] 78 count += len(l) 79 for i in xrange(0,len(l),20): 80 print >>target, ','.join(l[i:i+20]) + ',' 81 print >>target, ','.join(l[i:]) + ',' 82 83 print >>target, '};' 84 print >>target, 'const int %s_length = %d;' % (name, count) 85 print >>target 86 87def splitpath(path): 88 dir,file = os.path.split(path) 89 path = [] 90 assert(file) 91 while dir: 92 dir,base = os.path.split(dir) 93 path.insert(0, base) 94 return path, file 95 96def MakeEmbeddedPyFile(target, source, env): 97 target = file(str(target[0]), 'w') 98 99 tree = {} 100 for src in source: 101 src = str(src) 102 path,pyfile = splitpath(src) 103 node = tree 104 for dir in path: 105 if not node.has_key(dir): 106 node[dir] = { } 107 node = node[dir] 108 109 name,ext = pyfile.split('.') 110 if name == '__init__': 111 node['.hasinit'] = True 112 node[pyfile] = (src,name,ext,src) 113 114 done = False 115 while not done: 116 done = True 117 for name,entry in tree.items(): 118 if not isinstance(entry, dict): continue 119 if entry.has_key('.hasinit'): continue 120 121 done = False 122 del tree[name] 123 for key,val in entry.iteritems(): 124 if tree.has_key(key): 125 raise NameError, \ 126 "dir already has %s can't add it again" % key 127 tree[key] = val 128 129 files = [] 130 def populate(node, path = []): 131 names = node.keys() 132 names.sort() 133 for name in names: 134 if name == '.hasinit': 135 continue 136 137 entry = node[name] 138 if isinstance(entry, dict): 139 if not entry.has_key('.hasinit'): 140 raise NameError, 'package directory missing __init__.py' 141 populate(entry, path + [ name ]) 142 else: 143 pyfile,name,ext,filename = entry 144 files.append((pyfile, path, name, ext, filename)) 145 populate(tree) 146 147 for pyfile, path, name, ext, filename in files: 148 WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename) 149 150def MakeDefinesPyFile(target, source, env): 151 f = file(str(target[0]), 'w') 152 print >>f, "import __main__" 153 print >>f, "__main__.m5_build_env = ", 154 print >>f, source[0] 155 f.close() 156 157CFileCounter = 0 158def MakePythonCFile(target, source, env): 159 global CFileCounter 160 target = file(str(target[0]), 'w') 161 162 print >>target, '''\ 163#include "base/embedfile.hh" 164 165namespace { 166''' 167 for src in source: 168 src = str(src) 169 fname = os.path.basename(src) 170 name = 'embedded_file%d' % CFileCounter 171 CFileCounter += 1 172 WriteCFile(target, src, name) 173 print >>target, '''\ 174EmbedMap %(name)s("%(fname)s", 175 %(name)s_string, %(name)s_length); 176 177''' % locals() 178 print >>target, '''\ 179 180/* namespace */ } 181''' 182 183# base list of .py files to embed 184embedded_py_files = [ '../util/pbs/jobfile.py' ] 185# add all .py files in python/m5 186objpath = os.path.join(env['SRCDIR'], 'python', 'm5') 187for root, dirs, files in os.walk(objpath, topdown=True): 188 for i,dir in enumerate(dirs): 189 if dir == 'SCCS': 190 del dirs[i] 191 break 192 193 assert(root.startswith(objpath)) 194 for f in files: 195 if f.endswith('.py'): 196 embedded_py_files.append(os.path.join(root, f)) 197 198embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh') 199 200optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions]) 201env.Command('defines.py', Value(optionDict), MakeDefinesPyFile) 202 203env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile) 204env.Depends('embedded_py.cc', embedfile_hh) 205env.Command('embedded_py.cc', 206 ['string_importer.py', 'defines.py', 'embedded_py.py'], 207 MakePythonCFile) 208