29a30
> from zipfile import PyZipFile
30a32,35
> # handy function for path joins
> def join(*args):
> return os.path.normpath(os.path.join(*args))
>
33c38
< import scons_helper
---
> # This SConscript is in charge of collecting .py files and generating a zip archive that is appended to the m5 binary.
35,37c40,42
< def WriteEmbeddedPyFile(target, source, path, name, ext, filename):
< if isinstance(source, str):
< source = file(source, 'r')
---
> # Copy .py source files here (relative to src/python in the build
> # directory).
> pyzip_root = 'zip'
39,40c44,48
< if isinstance(target, str):
< target = file(target, 'w')
---
> # List of files & directories to include in the zip file. To include
> # a package, list only the root directory of the package, not any
> # internal .py files (else they will get the path stripped off when
> # they are imported into the zip file).
> pyzip_files = []
42,43c50,53
< print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \
< (`path`, `name`, `ext`, `filename`)
---
> # List of additional files on which the zip archive depends, but which
> # are not included in pyzip_files... i.e. individual .py files within
> # a package.
> pyzip_dep_files = []
45,50c55,66
< for line in source:
< line = line
< # escape existing backslashes
< line = line.replace('\\', '\\\\')
< # escape existing triple quotes
< line = line.replace("'''", r"\'\'\'")
---
> # Add the specified package to the zip archive. Adds the directory to
> # pyzip_files and all included .py files to pyzip_dep_files.
> def addPkg(pkgdir):
> pyzip_files.append(join(pyzip_root, pkgdir))
> origdir = os.getcwd()
> srcdir = join(Dir('.').srcnode().abspath, pkgdir)
> os.chdir(srcdir)
> for path, dirs, files in os.walk('.'):
> for i,dir in enumerate(dirs):
> if dir == 'SCCS':
> del dirs[i]
> break
52c68,73
< print >>target, line,
---
> for f in files:
> if f.endswith('.py'):
> source = join(pkgdir, path, f)
> target = join(pyzip_root, source)
> pyzip_dep_files.append(target)
> env.CopyFile(target, source)
54,55c75
< print >>target, "''')"
< print >>target
---
> os.chdir(origdir)
57,149c77,78
< def WriteCFile(target, source, name):
< if isinstance(source, str):
< source = file(source, 'r')
<
< if isinstance(target, str):
< target = file(target, 'w')
<
< print >>target, 'const char %s_string[] = {' % name
<
< count = 0
< from array import array
< try:
< while True:
< foo = array('B')
< foo.fromfile(source, 10000)
< l = [ str(i) for i in foo.tolist() ]
< count += len(l)
< for i in xrange(0,9999,20):
< print >>target, ','.join(l[i:i+20]) + ','
< except EOFError:
< l = [ str(i) for i in foo.tolist() ]
< count += len(l)
< for i in xrange(0,len(l),20):
< print >>target, ','.join(l[i:i+20]) + ','
< print >>target, ','.join(l[i:]) + ','
<
< print >>target, '};'
< print >>target, 'const int %s_length = %d;' % (name, count)
< print >>target
<
< def splitpath(path):
< dir,file = os.path.split(path)
< path = []
< assert(file)
< while dir:
< dir,base = os.path.split(dir)
< path.insert(0, base)
< return path, file
<
< def MakeEmbeddedPyFile(target, source, env):
< target = file(str(target[0]), 'w')
<
< tree = {}
< for src in source:
< src = str(src)
< path,pyfile = splitpath(src)
< node = tree
< for dir in path:
< if not node.has_key(dir):
< node[dir] = { }
< node = node[dir]
<
< name,ext = pyfile.split('.')
< if name == '__init__':
< node['.hasinit'] = True
< node[pyfile] = (src,name,ext,src)
<
< done = False
< while not done:
< done = True
< for name,entry in tree.items():
< if not isinstance(entry, dict): continue
< if entry.has_key('.hasinit'): continue
<
< done = False
< del tree[name]
< for key,val in entry.iteritems():
< if tree.has_key(key):
< raise NameError, \
< "dir already has %s can't add it again" % key
< tree[key] = val
<
< files = []
< def populate(node, path = []):
< names = node.keys()
< names.sort()
< for name in names:
< if name == '.hasinit':
< continue
<
< entry = node[name]
< if isinstance(entry, dict):
< if not entry.has_key('.hasinit'):
< raise NameError, 'package directory missing __init__.py'
< populate(entry, path + [ name ])
< else:
< pyfile,name,ext,filename = entry
< files.append((pyfile, path, name, ext, filename))
< populate(tree)
<
< for pyfile, path, name, ext, filename in files:
< WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename)
<
---
> # Generate Python file that contains a dict specifying the current
> # build_env flags.
157,199d85
< CFileCounter = 0
< def MakePythonCFile(target, source, env):
< global CFileCounter
< target = file(str(target[0]), 'w')
<
< print >>target, '''\
< #include "base/embedfile.hh"
<
< namespace {
< '''
< for src in source:
< src = str(src)
< fname = os.path.basename(src)
< name = 'embedded_file%d' % CFileCounter
< CFileCounter += 1
< WriteCFile(target, src, name)
< print >>target, '''\
< EmbedMap %(name)s("%(fname)s",
< %(name)s_string, %(name)s_length);
<
< ''' % locals()
< print >>target, '''\
<
< /* namespace */ }
< '''
<
< # base list of .py files to embed
< embedded_py_files = [ os.path.join(env['ROOT'], 'util/pbs/jobfile.py') ]
< # add all .py files in python/m5
< objpath = os.path.join(env['SRCDIR'], 'python', 'm5')
< for root, dirs, files in os.walk(objpath, topdown=True):
< for i,dir in enumerate(dirs):
< if dir == 'SCCS':
< del dirs[i]
< break
<
< assert(root.startswith(objpath))
< for f in files:
< if f.endswith('.py'):
< embedded_py_files.append(os.path.join(root, f))
<
< embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh')
<
203,207c89,103
< env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile)
< env.Depends('embedded_py.cc', embedfile_hh)
< env.Command('embedded_py.cc',
< ['string_importer.py', 'defines.py', 'embedded_py.py'],
< MakePythonCFile)
---
> # Now specify the packages & files for the zip archive.
> addPkg('m5')
> pyzip_files.append('defines.py')
> pyzip_files.append(join(env['ROOT'], 'util/pbs/jobfile.py'))
>
> # Action function to build the zip archive. Uses the PyZipFile module
> # included in the standard Python library.
> def buildPyZip(target, source, env):
> pzf = PyZipFile(str(target[0]), 'w')
> for s in source:
> pzf.writepy(str(s))
>
> # Add the zip file target to the environment.
> env.Command('m5py.zip', pyzip_files, buildPyZip)
> env.Depends('m5py.zip', pyzip_dep_files)