SConscript revision 1858
11046SN/A# -*- mode:python -*-
21046SN/A
31762SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan
41046SN/A# All rights reserved.
51046SN/A#
61046SN/A# Redistribution and use in source and binary forms, with or without
71046SN/A# modification, are permitted provided that the following conditions are
81046SN/A# met: redistributions of source code must retain the above copyright
91046SN/A# notice, this list of conditions and the following disclaimer;
101046SN/A# redistributions in binary form must reproduce the above copyright
111046SN/A# notice, this list of conditions and the following disclaimer in the
121046SN/A# documentation and/or other materials provided with the distribution;
131046SN/A# neither the name of the copyright holders nor the names of its
141046SN/A# contributors may be used to endorse or promote products derived from
151046SN/A# this software without specific prior written permission.
161046SN/A#
171046SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181046SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191046SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201046SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211046SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221046SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231046SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241046SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251046SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261046SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
271046SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.eduimport os, os.path, re, sys
302665Ssaidi@eecs.umich.edu
311046SN/AImport('env')
321530SN/A
332655Sstever@eecs.umich.eduimport scons_helper
342655Sstever@eecs.umich.edu
352655Sstever@eecs.umich.edudef WriteEmbeddedPyFile(target, source, path, name, ext, filename):
362655Sstever@eecs.umich.edu    if isinstance(source, str):
372655Sstever@eecs.umich.edu        source = file(source, 'r')
381530SN/A
391530SN/A    if isinstance(target, str):
401530SN/A        target = file(target, 'w')
412667Sstever@eecs.umich.edu
422667Sstever@eecs.umich.edu    print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \
431046SN/A          (`path`, `name`, `ext`, `filename`)
442655Sstever@eecs.umich.edu
452655Sstever@eecs.umich.edu    for line in source:
462655Sstever@eecs.umich.edu        line = line
472655Sstever@eecs.umich.edu        # escape existing backslashes
482655Sstever@eecs.umich.edu        line = line.replace('\\', '\\\\')
491046SN/A        # escape existing triple quotes
502655Sstever@eecs.umich.edu        line = line.replace("'''", r"\'\'\'")
512655Sstever@eecs.umich.edu
522655Sstever@eecs.umich.edu        print >>target, line,
532655Sstever@eecs.umich.edu
541046SN/A    print >>target, "''')"
552655Sstever@eecs.umich.edu    print >>target
562655Sstever@eecs.umich.edu
572655Sstever@eecs.umich.edudef WriteCFile(target, source, name):
582667Sstever@eecs.umich.edu    if isinstance(source, str):
592655Sstever@eecs.umich.edu        source = file(source, 'r')
602655Sstever@eecs.umich.edu
612655Sstever@eecs.umich.edu    if isinstance(target, str):
622655Sstever@eecs.umich.edu        target = file(target, 'w')
632655Sstever@eecs.umich.edu
642655Sstever@eecs.umich.edu    print >>target, 'const char %s_string[] = {' % name
652655Sstever@eecs.umich.edu
662655Sstever@eecs.umich.edu    count = 0
671046SN/A    from array import array
682655Sstever@eecs.umich.edu    try:
692655Sstever@eecs.umich.edu        while True:
702667Sstever@eecs.umich.edu            foo = array('B')
711046SN/A            foo.fromfile(source, 10000)
722655Sstever@eecs.umich.edu            l = [ str(i) for i in foo.tolist() ]
731046SN/A            count += len(l)
742655Sstever@eecs.umich.edu            for i in xrange(0,9999,20):
752655Sstever@eecs.umich.edu                print >>target, ','.join(l[i:i+20]) + ','
761439SN/A    except EOFError:
771530SN/A        l = [ str(i) for i in foo.tolist() ]
782889Sbinkertn@umich.edu        count += len(l)
791530SN/A        for i in xrange(0,len(l),20):
801439SN/A            print >>target, ','.join(l[i:i+20]) + ','
811858SN/A        print >>target, ','.join(l[i:]) + ','
822667Sstever@eecs.umich.edu
831858SN/A    print >>target, '};'
842889Sbinkertn@umich.edu    print >>target, 'const int %s_length = %d;' % (name, count)
852889Sbinkertn@umich.edu    print >>target
862889Sbinkertn@umich.edu
872889Sbinkertn@umich.edudef splitpath(path):
882889Sbinkertn@umich.edu    dir,file = os.path.split(path)
892889Sbinkertn@umich.edu    path = []
902889Sbinkertn@umich.edu    assert(file)
912889Sbinkertn@umich.edu    while dir:
922889Sbinkertn@umich.edu        dir,base = os.path.split(dir)
932889Sbinkertn@umich.edu        path.insert(0, base)
942889Sbinkertn@umich.edu    return path, file
952655Sstever@eecs.umich.edu
962655Sstever@eecs.umich.edudef MakeEmbeddedPyFile(target, source, env):
972667Sstever@eecs.umich.edu    target = file(str(target[0]), 'w')
982889Sbinkertn@umich.edu   
992655Sstever@eecs.umich.edu    tree = {}
1002655Sstever@eecs.umich.edu    for src in source:
1013869Sbinkertn@umich.edu        src = str(src)
1023869Sbinkertn@umich.edu        path,pyfile = splitpath(src)
1033869Sbinkertn@umich.edu        node = tree
1043869Sbinkertn@umich.edu        for dir in path:
1053869Sbinkertn@umich.edu            if not node.has_key(dir):
1063869Sbinkertn@umich.edu                node[dir] = { }
1073645Sbinkertn@umich.edu            node = node[dir]
1083869Sbinkertn@umich.edu
1093869Sbinkertn@umich.edu        name,ext = pyfile.split('.')
1103871Sbinkertn@umich.edu        if name == '__init__':
1114045Sbinkertn@umich.edu            node['.hasinit'] = True
1124042Sbinkertn@umich.edu        node[pyfile] = (src,name,ext,src)
1132667Sstever@eecs.umich.edu
1142655Sstever@eecs.umich.edu    done = False
1152655Sstever@eecs.umich.edu    while not done:
1162655Sstever@eecs.umich.edu        done = True
1172655Sstever@eecs.umich.edu        for name,entry in tree.items():
1182655Sstever@eecs.umich.edu            if not isinstance(entry, dict): continue
1192655Sstever@eecs.umich.edu            if entry.has_key('.hasinit'): continue
1202655Sstever@eecs.umich.edu
1212655Sstever@eecs.umich.edu            done = False
1222655Sstever@eecs.umich.edu            del tree[name]
1232655Sstever@eecs.umich.edu            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
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
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 = [ '../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
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)
208