SConscript (2632:1bb2f91485ea) SConscript (2655:da93a2088efa)
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

--- 13 unchanged lines hidden (view full) ---

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
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

--- 13 unchanged lines hidden (view full) ---

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
30from zipfile import PyZipFile
30
31
32# handy function for path joins
33def join(*args):
34 return os.path.normpath(os.path.join(*args))
35
31Import('env')
32
36Import('env')
37
33import scons_helper
38# This SConscript is in charge of collecting .py files and generating a zip archive that is appended to the m5 binary.
34
39
35def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
36 if isinstance(source, str):
37 source = file(source, 'r')
40# Copy .py source files here (relative to src/python in the build
41# directory).
42pyzip_root = 'zip'
38
43
39 if isinstance(target, str):
40 target = file(target, 'w')
44# List of files & directories to include in the zip file. To include
45# a package, list only the root directory of the package, not any
46# internal .py files (else they will get the path stripped off when
47# they are imported into the zip file).
48pyzip_files = []
41
49
42 print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \
43 (`path`, `name`, `ext`, `filename`)
50# List of additional files on which the zip archive depends, but which
51# are not included in pyzip_files... i.e. individual .py files within
52# a package.
53pyzip_dep_files = []
44
54
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"\'\'\'")
55# Add the specified package to the zip archive. Adds the directory to
56# pyzip_files and all included .py files to pyzip_dep_files.
57def addPkg(pkgdir):
58 pyzip_files.append(join(pyzip_root, pkgdir))
59 origdir = os.getcwd()
60 srcdir = join(Dir('.').srcnode().abspath, pkgdir)
61 os.chdir(srcdir)
62 for path, dirs, files in os.walk('.'):
63 for i,dir in enumerate(dirs):
64 if dir == 'SCCS':
65 del dirs[i]
66 break
51
67
52 print >>target, line,
68 for f in files:
69 if f.endswith('.py'):
70 source = join(pkgdir, path, f)
71 target = join(pyzip_root, source)
72 pyzip_dep_files.append(target)
73 env.CopyFile(target, source)
53
74
54 print >>target, "''')"
55 print >>target
75 os.chdir(origdir)
56
76
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
77# Generate Python file that contains a dict specifying the current
78# build_env flags.
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
79def MakeDefinesPyFile(target, source, env):
80 f = file(str(target[0]), 'w')
81 print >>f, "import __main__"
82 print >>f, "__main__.m5_build_env = ",
83 print >>f, source[0]
84 f.close()
85
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 = [ os.path.join(env['ROOT'], '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
86optionDict = dict([(opt, env[opt]) for opt in env.ExportOptions])
87env.Command('defines.py', Value(optionDict), MakeDefinesPyFile)
88
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)
89# Now specify the packages & files for the zip archive.
90addPkg('m5')
91pyzip_files.append('defines.py')
92pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py'))
93
94# Action function to build the zip archive. Uses the PyZipFile module
95# included in the standard Python library.
96def buildPyZip(target, source, env):
97 pzf = PyZipFile(str(target[0]), 'w')
98 for s in source:
99 pzf.writepy(str(s))
100
101# Add the zip file target to the environment.
102env.Command('m5py.zip', pyzip_files, buildPyZip)
103env.Depends('m5py.zip', pyzip_dep_files)