SConscript revision 1530
112239Sandreas.sandberg@arm.com# -*- mode:python -*-
212239Sandreas.sandberg@arm.com
312239Sandreas.sandberg@arm.com# Copyright (c) 2005 The Regents of The University of Michigan
412239Sandreas.sandberg@arm.com# All rights reserved.
512239Sandreas.sandberg@arm.com#
612239Sandreas.sandberg@arm.com# Redistribution and use in source and binary forms, with or without
712239Sandreas.sandberg@arm.com# modification, are permitted provided that the following conditions are
812239Sandreas.sandberg@arm.com# met: redistributions of source code must retain the above copyright
912239Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer;
1012239Sandreas.sandberg@arm.com# redistributions in binary form must reproduce the above copyright
1112239Sandreas.sandberg@arm.com# notice, this list of conditions and the following disclaimer in the
1212239Sandreas.sandberg@arm.com# documentation and/or other materials provided with the distribution;
1312239Sandreas.sandberg@arm.com# neither the name of the copyright holders nor the names of its
1412239Sandreas.sandberg@arm.com# contributors may be used to endorse or promote products derived from
1512239Sandreas.sandberg@arm.com# this software without specific prior written permission.
1612239Sandreas.sandberg@arm.com#
1712239Sandreas.sandberg@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1812239Sandreas.sandberg@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1912239Sandreas.sandberg@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012239Sandreas.sandberg@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2112239Sandreas.sandberg@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2212239Sandreas.sandberg@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2312239Sandreas.sandberg@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2412239Sandreas.sandberg@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2512239Sandreas.sandberg@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2612239Sandreas.sandberg@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2712239Sandreas.sandberg@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2812239Sandreas.sandberg@arm.com
2912239Sandreas.sandberg@arm.comimport os, os.path, re, sys
3012239Sandreas.sandberg@arm.com
3112239Sandreas.sandberg@arm.comImport('env')
3212239Sandreas.sandberg@arm.com
3312239Sandreas.sandberg@arm.com# tell python where to find m5 python code
3412239Sandreas.sandberg@arm.comsys.path.append(os.path.join(env['SRCDIR'], 'python'))
3512239Sandreas.sandberg@arm.com
3612239Sandreas.sandberg@arm.comimport m5scons
3712239Sandreas.sandberg@arm.com
3812239Sandreas.sandberg@arm.comdef WriteEmbeddedPyFile(target, source, path, name, ext, filename):
3912239Sandreas.sandberg@arm.com    if isinstance(source, str):
4012239Sandreas.sandberg@arm.com        source = file(source, 'r')
4112239Sandreas.sandberg@arm.com
4212334Sgabeblack@google.com    if isinstance(target, str):
4312239Sandreas.sandberg@arm.com        target = file(target, 'w')
4412239Sandreas.sandberg@arm.com
4512239Sandreas.sandberg@arm.com    print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \
4612239Sandreas.sandberg@arm.com          (`path`, `name`, `ext`, `filename`)
4712239Sandreas.sandberg@arm.com
4812239Sandreas.sandberg@arm.com    for line in source:
4912239Sandreas.sandberg@arm.com        line = line
5012239Sandreas.sandberg@arm.com        # escape existing backslashes
5112239Sandreas.sandberg@arm.com        line = line.replace('\\', '\\\\')
5212239Sandreas.sandberg@arm.com        # escape existing triple quotes
5312239Sandreas.sandberg@arm.com        line = line.replace("'''", r"\'\'\'")
5412239Sandreas.sandberg@arm.com
5512239Sandreas.sandberg@arm.com        print >>target, line,
5612239Sandreas.sandberg@arm.com
5712239Sandreas.sandberg@arm.com    print >>target, "''')"
5812239Sandreas.sandberg@arm.com    print >>target
5912239Sandreas.sandberg@arm.com
6012239Sandreas.sandberg@arm.comdef WriteCFile(target, source, name):
6112239Sandreas.sandberg@arm.com    if isinstance(source, str):
6212239Sandreas.sandberg@arm.com        source = file(source, 'r')
6312239Sandreas.sandberg@arm.com
6412239Sandreas.sandberg@arm.com    if isinstance(target, str):
6512239Sandreas.sandberg@arm.com        target = file(target, 'w')
6612239Sandreas.sandberg@arm.com
6712239Sandreas.sandberg@arm.com    print >>target, 'const char %s_string[] = {' % name
6812239Sandreas.sandberg@arm.com
6912239Sandreas.sandberg@arm.com    count = 0
7012239Sandreas.sandberg@arm.com    from array import array
7112239Sandreas.sandberg@arm.com    try:
7212239Sandreas.sandberg@arm.com        while True:
7312239Sandreas.sandberg@arm.com            foo = array('B')
7412239Sandreas.sandberg@arm.com            foo.fromfile(source, 10000)
7512239Sandreas.sandberg@arm.com            l = [ str(i) for i in foo.tolist() ]
7612239Sandreas.sandberg@arm.com            count += len(l)
7712239Sandreas.sandberg@arm.com            for i in xrange(0,9999,20):
7812239Sandreas.sandberg@arm.com                print >>target, ','.join(l[i:i+20]) + ','
7912239Sandreas.sandberg@arm.com    except EOFError:
8012239Sandreas.sandberg@arm.com        l = [ str(i) for i in foo.tolist() ]
8112239Sandreas.sandberg@arm.com        count += len(l)
8212239Sandreas.sandberg@arm.com        for i in xrange(0,len(l),20):
8312239Sandreas.sandberg@arm.com            print >>target, ','.join(l[i:i+20]) + ','
8412239Sandreas.sandberg@arm.com        print >>target, ','.join(l[i:]) + ','
8512239Sandreas.sandberg@arm.com
8612239Sandreas.sandberg@arm.com    print >>target, '};'
8712239Sandreas.sandberg@arm.com    print >>target, 'const int %s_length = %d;' % (name, count)
8812239Sandreas.sandberg@arm.com    print >>target
8912239Sandreas.sandberg@arm.com
9012239Sandreas.sandberg@arm.comdef splitpath(path):
9112239Sandreas.sandberg@arm.com    dir,file = os.path.split(path)
9212239Sandreas.sandberg@arm.com    path = []
9312239Sandreas.sandberg@arm.com    assert(file)
9412239Sandreas.sandberg@arm.com    while dir:
9512239Sandreas.sandberg@arm.com        dir,base = os.path.split(dir)
96        path.insert(0, base)
97    return path, file
98
99def MakeEmbeddedPyFile(target, source, env):
100    target = file(str(target[0]), 'w')
101   
102    tree = {}
103    for src in source:
104        src = str(src)
105        path,pyfile = splitpath(src)
106        node = tree
107        for dir in path:
108            if not node.has_key(dir):
109                node[dir] = { }
110            node = node[dir]
111
112        name,ext = pyfile.split('.')
113        if name == '__init__':
114            node['.hasinit'] = True
115        node[pyfile] = (src,name,ext,src)
116
117    done = False
118    while not done:
119        done = True
120        for name,entry in tree.items():
121            if not isinstance(entry, dict): continue
122            if entry.has_key('.hasinit'): continue
123
124            done = False
125            del tree[name]
126            for key,val in entry.iteritems():
127                if tree.has_key(key):
128                    raise NameError, \
129                          "dir already has %s can't add it again" % key
130                tree[key] = val
131
132    files = []
133    def populate(node, path = []):
134        names = node.keys()
135        names.sort()
136        for name in names:
137            if name == '.hasinit':
138                continue
139            
140            entry = node[name]
141            if isinstance(entry, dict):
142                if not entry.has_key('.hasinit'):
143                    raise NameError, 'package directory missing __init__.py'
144                populate(entry, path + [ name ])
145            else:
146                pyfile,name,ext,filename = entry
147                files.append((pyfile, path, name, ext, filename))
148    populate(tree)
149
150    for pyfile, path, name, ext, filename in files:
151        WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename)
152
153def MakeDefinesPyFile(target, source, env):
154    f = file(str(target[0]), 'w')
155    print >>f, "import __main__"
156    print >>f, "__main__.m5_build_env = ",
157    print >>f, m5scons.flatten_defines(env['CPPDEFINES'])
158    f.close()
159
160CFileCounter = 0
161def MakePythonCFile(target, source, env):
162    global CFileCounter
163    target = file(str(target[0]), 'w')
164
165    print >>target, '''\
166#include "base/embedfile.hh"
167
168namespace {
169'''
170    for src in source:
171        src = str(src)
172        fname = os.path.basename(src)
173        name = 'embedded_file%d' % CFileCounter
174        CFileCounter += 1
175        WriteCFile(target, src, name)
176        print >>target, '''\
177EmbedMap %(name)s("%(fname)s",
178    %(name)s_string, %(name)s_length);
179
180''' % locals()
181    print >>target, '''\
182
183/* namespace */ }
184'''
185
186embedded_py_files = [ 'mpy_importer.py', '../util/pbs/jobfile.py' ]
187objpath = os.path.join(env['SRCDIR'], 'python/m5')
188for root, dirs, files in os.walk(objpath, topdown=True):
189    for i,dir in enumerate(dirs):
190        if dir == 'SCCS':
191            del dirs[i]
192            break
193
194    assert(root.startswith(objpath))
195    for f in files:
196        if f.endswith('.mpy') or f.endswith('.py'):
197            embedded_py_files.append(os.path.join(root, f))
198
199embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh')
200env.Command('defines.py', None, MakeDefinesPyFile)
201env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile)
202env.Depends('embedded_py.cc', embedfile_hh)
203env.Command('embedded_py.cc',
204            ['string_importer.py', 'defines.py', 'embedded_py.py'],
205            MakePythonCFile)
206