Use the multidict in the python config stuff. Makes code a bit
[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, sys
30
31 Import('env')
32
33 import m5scons
34
35 def 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
57 def 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
87 def 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
96 def 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
150 def 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, m5scons.flatten_defines(env['CPPDEFINES'])
155 f.close()
156
157 CFileCounter = 0
158 def MakePythonCFile(target, source, env):
159 global CFileCounter
160 target = file(str(target[0]), 'w')
161
162 print >>target, '''\
163 #include "base/embedfile.hh"
164
165 namespace {
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, '''\
174 EmbedMap %(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
184 embedded_py_files = [ '../util/pbs/jobfile.py' ]
185 # add all .py and .mpy files in python/m5
186 objpath = os.path.join(env['SRCDIR'], 'python', 'm5')
187 for 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('.mpy') or f.endswith('.py'):
196 embedded_py_files.append(os.path.join(root, f))
197
198 embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh')
199 env.Command('defines.py', None, MakeDefinesPyFile)
200 env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile)
201 env.Depends('embedded_py.cc', embedfile_hh)
202 env.Command('embedded_py.cc',
203 ['string_importer.py', 'defines.py', 'embedded_py.py'],
204 MakePythonCFile)