Clean up import situation... key things are:
[gem5.git] / python / SConscript
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
29 import os, os.path, re
30
31 def 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
53 def 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
83 def 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
92 Import('env')
93 def 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
147 def MakeDefinesPyFile(target, source, env):
148 target = file(str(target[0]), 'w')
149
150 print >>target, "import os"
151 defines = env['CPPDEFINES']
152 if isinstance(defines, list):
153 for var in defines:
154 if isinstance(var, tuple):
155 key,val = var
156 else:
157 key,val = var,'True'
158
159 if not isinstance(key, basestring):
160 panic("invalid type for define: %s" % type(key))
161
162 print >>target, "os.environ['%s'] = '%s'" % (key, val)
163
164 elif isinstance(defines, dict):
165 for key,val in defines.iteritems():
166 print >>target, "os.environ['%s'] = '%s'" % (key, val)
167 else:
168 panic("invalid type for defines: %s" % type(defines))
169
170 CFileCounter = 0
171 def MakePythonCFile(target, source, env):
172 global CFileCounter
173 target = file(str(target[0]), 'w')
174
175 print >>target, '''\
176 #include "base/embedfile.hh"
177
178 namespace {
179 '''
180 for src in source:
181 src = str(src)
182 fname = os.path.basename(src)
183 name = 'embedded_file%d' % CFileCounter
184 CFileCounter += 1
185 WriteCFile(target, src, name)
186 print >>target, '''\
187 EmbedMap %(name)s("%(fname)s",
188 %(name)s_string, %(name)s_length);
189
190 ''' % locals()
191 print >>target, '''\
192
193 /* namespace */ }
194 '''
195
196 embedded_py_files = [ 'mpy_importer.py', '../util/pbs/jobfile.py' ]
197 objpath = os.path.join(env['SRCDIR'], 'python/m5')
198 for root, dirs, files in os.walk(objpath, topdown=True):
199 for i,dir in enumerate(dirs):
200 if dir == 'SCCS':
201 del dirs[i]
202 break
203
204 assert(root.startswith(objpath))
205 for f in files:
206 if f.endswith('.mpy') or f.endswith('.py'):
207 embedded_py_files.append(os.path.join(root, f))
208
209 embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh')
210 env.Command('defines.py', None, MakeDefinesPyFile)
211 env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile)
212 env.Depends('embedded_py.cc', embedfile_hh)
213 env.Command('embedded_py.cc',
214 ['string_importer.py', 'defines.py', 'embedded_py.py'],
215 MakePythonCFile)