SConscript revision 1439
1# -*- mode:python -*- 2 3# Copyright (c) 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 30 31def WriteEmbeddedPyFile(target, source, path, name, ext, filename): 32 if isinstance(source, str): 33 source = file(source, 'r') 34 35 if isinstance(target, str): 36 target = file(target, 'w') 37 38 print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \ 39 (`path`, `name`, `ext`, `filename`) 40 41 for line in source: 42 line = line 43 # escape existing backslashes 44 line = line.replace('\\', '\\\\') 45 # escape existing triple quotes 46 line = line.replace("'''", r"\'\'\'") 47 48 print >>target, line, 49 50 print >>target, "''')" 51 print >>target 52 53def WriteCFile(target, source, name): 54 if isinstance(source, str): 55 source = file(source, 'r') 56 57 if isinstance(target, str): 58 target = file(target, 'w') 59 60 print >>target, 'const char %s_string[] = {' % name 61 62 count = 0 63 from array import array 64 try: 65 while True: 66 foo = array('B') 67 foo.fromfile(source, 10000) 68 l = [ str(i) for i in foo.tolist() ] 69 count += len(l) 70 for i in xrange(0,9999,20): 71 print >>target, ','.join(l[i:i+20]) + ',' 72 except EOFError: 73 l = [ str(i) for i in foo.tolist() ] 74 count += len(l) 75 for i in xrange(0,len(l),20): 76 print >>target, ','.join(l[i:i+20]) + ',' 77 print >>target, ','.join(l[i:]) + ',' 78 79 print >>target, '};' 80 print >>target, 'const int %s_length = %d;' % (name, count) 81 print >>target 82 83def splitpath(path): 84 dir,file = os.path.split(path) 85 path = [] 86 assert(file) 87 while dir: 88 dir,base = os.path.split(dir) 89 path.insert(0, base) 90 return path, file 91 92Import('env') 93def MakeEmbeddedPyFile(target, source, env): 94 target = file(str(target[0]), 'w') 95 96 tree = {} 97 for src in source: 98 src = str(src) 99 path,pyfile = splitpath(src) 100 node = tree 101 for dir in path: 102 if not node.has_key(dir): 103 node[dir] = { } 104 node = node[dir] 105 106 name,ext = pyfile.split('.') 107 if name == '__init__': 108 node['.hasinit'] = True 109 node[pyfile] = (src,name,ext,src) 110 111 done = False 112 while not done: 113 done = True 114 for name,entry in tree.items(): 115 if not isinstance(entry, dict): continue 116 if entry.has_key('.hasinit'): continue 117 118 done = False 119 del tree[name] 120 for key,val in entry.iteritems(): 121 if tree.has_key(key): 122 raise NameError, \ 123 "dir already has %s can't add it again" % key 124 tree[key] = val 125 126 files = [] 127 def populate(node, path = []): 128 names = node.keys() 129 names.sort() 130 for name in names: 131 if name == '.hasinit': 132 continue 133 134 entry = node[name] 135 if isinstance(entry, dict): 136 if not entry.has_key('.hasinit'): 137 raise NameError, 'package directory missing __init__.py' 138 populate(entry, path + [ name ]) 139 else: 140 pyfile,name,ext,filename = entry 141 files.append((pyfile, path, name, ext, filename)) 142 populate(tree) 143 144 for pyfile, path, name, ext, filename in files: 145 WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename) 146 147def MakeDefinesPyFile(target, source, env): 148 target = file(str(target[0]), 'w') 149 150 defines = env['CPPDEFINES'] 151 if isinstance(defines, list): 152 for var in defines: 153 if isinstance(var, tuple): 154 key,val = var 155 else: 156 key,val = var,'True' 157 158 if not isinstance(key, basestring): 159 panic("invalid type for define: %s" % type(key)) 160 161 print >>target, "env['%s'] = '%s'" % (key, val) 162 163 elif isinstance(defines, dict): 164 for key,val in defines.iteritems(): 165 print >>target, "env['%s'] = '%s'" % (key, val) 166 else: 167 panic("invalid type for defines: %s" % type(defines)) 168 169CFileCounter = 0 170def MakePythonCFile(target, source, env): 171 global CFileCounter 172 target = file(str(target[0]), 'w') 173 174 print >>target, '''\ 175#include "base/embedfile.hh" 176 177namespace { 178''' 179 for src in source: 180 src = str(src) 181 fname = os.path.basename(src) 182 name = 'embedded_file%d' % CFileCounter 183 CFileCounter += 1 184 WriteCFile(target, src, name) 185 print >>target, '''\ 186EmbedMap %(name)s("%(fname)s", 187 %(name)s_string, %(name)s_length); 188 189''' % locals() 190 print >>target, '''\ 191 192/* namespace */ } 193''' 194 195embedded_py_files = ['m5config.py', 'importer.py', '../../util/pbs/jobfile.py'] 196objpath = os.path.join(env['SRCDIR'], 'objects') 197for root, dirs, files in os.walk(objpath, topdown=True): 198 for i,dir in enumerate(dirs): 199 if dir == 'SCCS': 200 del dirs[i] 201 break 202 203 assert(root.startswith(objpath)) 204 for f in files: 205 if f.endswith('.mpy') or f.endswith('.py'): 206 embedded_py_files.append(os.path.join(root, f)) 207 208embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh') 209env.Command('defines.py', None, MakeDefinesPyFile) 210env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile) 211env.Depends('embedded_py.cc', embedfile_hh) 212env.Command('embedded_py.cc', 213 ['string_importer.py', 'defines.py', 'embedded_py.py'], 214 MakePythonCFile) 215