# -*- mode:python -*-

# Copyright (c) 2004-2005 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert

import array
import bisect
import imp
import marshal
import os
import re
import sys
import zlib

from os.path import basename, dirname, exists, isdir, isfile, join as joinpath

import SCons

# This file defines how to build a particular configuration of M5
# based on variable settings in the 'env' build environment.

Import('*')

# Children need to see the environment
Export('env')

build_env = dict([(opt, env[opt]) for opt in export_vars])

########################################################################
# Code for adding source files of various types
#
class SourceMeta(type):
    def __init__(cls, name, bases, dict):
        super(SourceMeta, cls).__init__(name, bases, dict)
        cls.all = []
        
    def get(cls, **kwargs):
        for src in cls.all:
            for attr,value in kwargs.iteritems():
                if getattr(src, attr) != value:
                    break
            else:
                yield src

class SourceFile(object):
    __metaclass__ = SourceMeta
    def __init__(self, source):
        tnode = source
        if not isinstance(source, SCons.Node.FS.File):
            tnode = File(source)

        self.tnode = tnode
        self.snode = tnode.srcnode()
        self.filename = str(tnode)
        self.dirname = dirname(self.filename)
        self.basename = basename(self.filename)
        index = self.basename.rfind('.')
        if index <= 0:
            # dot files aren't extensions
            self.extname = self.basename, None
        else:
            self.extname = self.basename[:index], self.basename[index+1:]

        for base in type(self).__mro__:
            if issubclass(base, SourceFile):
                bisect.insort_right(base.all, self)       

    def __lt__(self, other): return self.filename < other.filename
    def __le__(self, other): return self.filename <= other.filename
    def __gt__(self, other): return self.filename > other.filename
    def __ge__(self, other): return self.filename >= other.filename
    def __eq__(self, other): return self.filename == other.filename
    def __ne__(self, other): return self.filename != other.filename
        
class Source(SourceFile):
    '''Add a c/c++ source file to the build'''
    def __init__(self, source, Werror=True, swig=False, bin_only=False,
                 skip_lib=False):
        super(Source, self).__init__(source)

        self.Werror = Werror
        self.swig = swig
        self.bin_only = bin_only
        self.skip_lib = bin_only or skip_lib

class PySource(SourceFile):
    '''Add a python source file to the named package'''
    invalid_sym_char = re.compile('[^A-z0-9_]')
    modules = {}
    tnodes = {}
    symnames = {}
    
    def __init__(self, package, source):
        super(PySource, self).__init__(source)

        modname,ext = self.extname
        assert ext == 'py'

        if package:
            path = package.split('.')
        else:
            path = []

        modpath = path[:]
        if modname != '__init__':
            modpath += [ modname ]
        modpath = '.'.join(modpath)

        arcpath = path + [ self.basename ]
        debugname = self.snode.abspath
        if not exists(debugname):
            debugname = self.tnode.abspath

        self.package = package
        self.modname = modname
        self.modpath = modpath
        self.arcname = joinpath(*arcpath)
        self.debugname = debugname
        self.compiled = File(self.filename + 'c')
        self.assembly = File(self.filename + '.s')
        self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath)

        PySource.modules[modpath] = self
        PySource.tnodes[self.tnode] = self
        PySource.symnames[self.symname] = self

class SimObject(PySource):
    '''Add a SimObject python file as a python source object and add
    it to a list of sim object modules'''

    fixed = False
    modnames = []

    def __init__(self, source):
        super(SimObject, self).__init__('m5.objects', source)
        if self.fixed:
            raise AttributeError, "Too late to call SimObject now."

        bisect.insort_right(SimObject.modnames, self.modname)

class SwigSource(SourceFile):
    '''Add a swig file to build'''

    def __init__(self, package, source):
        super(SwigSource, self).__init__(source)

        modname,ext = self.extname
        assert ext == 'i'

        self.module = modname
        cc_file = joinpath(self.dirname, modname + '_wrap.cc')
        py_file = joinpath(self.dirname, modname + '.py')

        self.cc_source = Source(cc_file, swig=True)
        self.py_source = PySource(package, py_file)

unit_tests = []
def UnitTest(target, sources):
    if not isinstance(sources, (list, tuple)):
        sources = [ sources ]

    sources = [ Source(src, skip_lib=True) for src in sources ]
    unit_tests.append((target, sources))

# Children should have access
Export('Source')
Export('PySource')
Export('SimObject')
Export('SwigSource')
Export('UnitTest')

########################################################################
#
# Trace Flags
#
trace_flags = {}
def TraceFlag(name, desc=None):
    if name in trace_flags:
        raise AttributeError, "Flag %s already specified" % name
    trace_flags[name] = (name, (), desc)

def CompoundFlag(name, flags, desc=None):
    if name in trace_flags:
        raise AttributeError, "Flag %s already specified" % name

    compound = tuple(flags)
    trace_flags[name] = (name, compound, desc)

Export('TraceFlag')
Export('CompoundFlag')

########################################################################
#
# Set some compiler variables
#

# Include file paths are rooted in this directory.  SCons will
# automatically expand '.' to refer to both the source directory and
# the corresponding build directory to pick up generated include
# files.
env.Append(CPPPATH=Dir('.'))

for extra_dir in extras_dir_list:
    env.Append(CPPPATH=Dir(extra_dir))

# Add a flag defining what THE_ISA should be for all compilation
env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])

# Workaround for bug in SCons version > 0.97d20071212
# Scons bug id: 2006 M5 Bug id: 308 
for root, dirs, files in os.walk(base_dir, topdown=True):
    Dir(root[len(base_dir) + 1:])

########################################################################
#
# Walk the tree and execute all SConscripts in subdirectories
#

here = Dir('.').srcnode().abspath
for root, dirs, files in os.walk(base_dir, topdown=True):
    if root == here:
        # we don't want to recurse back into this SConscript
        continue

    if 'SConscript' in files:
        build_dir = joinpath(env['BUILDDIR'], root[len(base_dir) + 1:])
        SConscript(joinpath(root, 'SConscript'), build_dir=build_dir)

for extra_dir in extras_dir_list:
    prefix_len = len(dirname(extra_dir)) + 1
    for root, dirs, files in os.walk(extra_dir, topdown=True):
        if 'SConscript' in files:
            build_dir = joinpath(env['BUILDDIR'], root[prefix_len:])
            SConscript(joinpath(root, 'SConscript'), build_dir=build_dir)

for opt in export_vars:
    env.ConfigFile(opt)

########################################################################
#
# Prevent any SimObjects from being added after this point, they
# should all have been added in the SConscripts above
#
class DictImporter(object):
    '''This importer takes a dictionary of arbitrary module names that
    map to arbitrary filenames.'''
    def __init__(self, modules):
        self.modules = modules
        self.installed = set()

    def __del__(self):
        self.unload()

    def unload(self):
        import sys
        for module in self.installed:
            del sys.modules[module]
        self.installed = set()

    def find_module(self, fullname, path):
        if fullname == 'defines':
            return self

        if fullname == 'm5.objects':
            return self

        if fullname.startswith('m5.internal'):
            return None

        source = self.modules.get(fullname, None)
        if source is not None and exists(source.snode.abspath):
            return self

        return None

    def load_module(self, fullname):
        mod = imp.new_module(fullname)
        sys.modules[fullname] = mod
        self.installed.add(fullname)

        mod.__loader__ = self
        if fullname == 'm5.objects':
            mod.__path__ = fullname.split('.')
            return mod

        if fullname == 'defines':
            mod.__dict__['buildEnv'] = build_env
            return mod

        source = self.modules[fullname]
        if source.modname == '__init__':
            mod.__path__ = source.modpath
        mod.__file__ = source.snode.abspath

        exec file(source.snode.abspath, 'r') in mod.__dict__

        return mod

# install the python importer so we can grab stuff from the source
# tree itself.  We can't have SimObjects added after this point or
# else we won't know about them for the rest of the stuff.
SimObject.fixed = True
importer = DictImporter(PySource.modules)
sys.meta_path[0:0] = [ importer ]

import m5

# import all sim objects so we can populate the all_objects list
# make sure that we're working with a list, then let's sort it
for modname in SimObject.modnames:
    exec('from m5.objects import %s' % modname)

# we need to unload all of the currently imported modules so that they
# will be re-imported the next time the sconscript is run
importer.unload()
sys.meta_path.remove(importer)

sim_objects = m5.SimObject.allClasses
all_enums = m5.params.allEnums

all_params = {}
for name,obj in sorted(sim_objects.iteritems()):
    for param in obj._params.local.values():
        if not hasattr(param, 'swig_decl'):
            continue
        pname = param.ptype_str
        if pname not in all_params:
            all_params[pname] = param

########################################################################
#
# calculate extra dependencies
#
module_depends = ["m5", "m5.SimObject", "m5.params"]
depends = [ PySource.modules[dep].tnode for dep in module_depends ]

########################################################################
#
# Commands for the basic automatically generated python files
#

# Generate Python file containing a dict specifying the current
# build_env flags.
def makeDefinesPyFile(target, source, env):
    f = file(str(target[0]), 'w')
    build_env, hg_info = [ x.get_contents() for x in source ]
    print >>f, "buildEnv = %s" % build_env
    print >>f, "hgRev = '%s'" % hg_info
    f.close()

defines_info = [ Value(build_env), Value(env['HG_INFO']) ]
# Generate a file with all of the compile options in it
env.Command('python/m5/defines.py', defines_info, makeDefinesPyFile)
PySource('m5', 'python/m5/defines.py')

# Generate python file containing info about the M5 source code
def makeInfoPyFile(target, source, env):
    f = file(str(target[0]), 'w')
    for src in source:
        data = ''.join(file(src.srcnode().abspath, 'r').xreadlines())
        print >>f, "%s = %s" % (src, repr(data))
    f.close()

# Generate a file that wraps the basic top level files
env.Command('python/m5/info.py',
            [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ],
            makeInfoPyFile)
PySource('m5', 'python/m5/info.py')

# Generate the __init__.py file for m5.objects
def makeObjectsInitFile(target, source, env):
    f = file(str(target[0]), 'w')
    print >>f, 'from params import *'
    print >>f, 'from m5.SimObject import *'
    for module in source:
        print >>f, 'from %s import *' % module.get_contents()
    f.close()

# Generate an __init__.py file for the objects package
env.Command('python/m5/objects/__init__.py',
            map(Value, SimObject.modnames),
            makeObjectsInitFile)
PySource('m5.objects', 'python/m5/objects/__init__.py')

########################################################################
#
# Create all of the SimObject param headers and enum headers
#

def createSimObjectParam(target, source, env):
    assert len(target) == 1 and len(source) == 1

    hh_file = file(target[0].abspath, 'w')
    name = str(source[0].get_contents())
    obj = sim_objects[name]

    print >>hh_file, obj.cxx_decl()
    hh_file.close()

def createSwigParam(target, source, env):
    assert len(target) == 1 and len(source) == 1

    i_file = file(target[0].abspath, 'w')
    name = str(source[0].get_contents())
    param = all_params[name]

    for line in param.swig_decl():
        print >>i_file, line
    i_file.close()

def createEnumStrings(target, source, env):
    assert len(target) == 1 and len(source) == 1

    cc_file = file(target[0].abspath, 'w')
    name = str(source[0].get_contents())
    obj = all_enums[name]

    print >>cc_file, obj.cxx_def()
    cc_file.close()

def createEnumParam(target, source, env):
    assert len(target) == 1 and len(source) == 1

    hh_file = file(target[0].abspath, 'w')
    name = str(source[0].get_contents())
    obj = all_enums[name]

    print >>hh_file, obj.cxx_decl()
    hh_file.close()

# Generate all of the SimObject param struct header files
params_hh_files = []
for name,simobj in sorted(sim_objects.iteritems()):
    py_source = PySource.modules[simobj.__module__]
    extra_deps = [ py_source.tnode ]

    hh_file = File('params/%s.hh' % name)
    params_hh_files.append(hh_file)
    env.Command(hh_file, Value(name), createSimObjectParam)
    env.Depends(hh_file, depends + extra_deps)

# Generate any parameter header files needed
params_i_files = []
for name,param in all_params.iteritems():
    if isinstance(param, m5.params.VectorParamDesc):
        ext = 'vptype'
    else:
        ext = 'ptype'

    i_file = File('params/%s_%s.i' % (name, ext))
    params_i_files.append(i_file)
    env.Command(i_file, Value(name), createSwigParam)
    env.Depends(i_file, depends)

# Generate all enum header files
for name,enum in sorted(all_enums.iteritems()):
    py_source = PySource.modules[enum.__module__]
    extra_deps = [ py_source.tnode ]

    cc_file = File('enums/%s.cc' % name)
    env.Command(cc_file, Value(name), createEnumStrings)
    env.Depends(cc_file, depends + extra_deps)
    Source(cc_file)

    hh_file = File('enums/%s.hh' % name)
    env.Command(hh_file, Value(name), createEnumParam)
    env.Depends(hh_file, depends + extra_deps)

# Build the big monolithic swigged params module (wraps all SimObject
# param structs and enum structs)
def buildParams(target, source, env):
    names = [ s.get_contents() for s in source ]
    objs = [ sim_objects[name] for name in names ]
    out = file(target[0].abspath, 'w')

    ordered_objs = []
    obj_seen = set()
    def order_obj(obj):
        name = str(obj)
        if name in obj_seen:
            return

        obj_seen.add(name)
        if str(obj) != 'SimObject':
            order_obj(obj.__bases__[0])

        ordered_objs.append(obj)

    for obj in objs:
        order_obj(obj)

    enums = set()
    predecls = []
    pd_seen = set()

    def add_pds(*pds):
        for pd in pds:
            if pd not in pd_seen:
                predecls.append(pd)
                pd_seen.add(pd)

    for obj in ordered_objs:
        params = obj._params.local.values()
        for param in params:
            ptype = param.ptype
            if issubclass(ptype, m5.params.Enum):
                if ptype not in enums:
                    enums.add(ptype)
            pds = param.swig_predecls()
            if isinstance(pds, (list, tuple)):
                add_pds(*pds)
            else:
                add_pds(pds)

    print >>out, '%module params'

    print >>out, '%{'
    for obj in ordered_objs:
        print >>out, '#include "params/%s.hh"' % obj
    print >>out, '%}'

    for pd in predecls:
        print >>out, pd

    enums = list(enums)
    enums.sort()
    for enum in enums:
        print >>out, '%%include "enums/%s.hh"' % enum.__name__
    print >>out

    for obj in ordered_objs:
        if obj.swig_objdecls:
            for decl in obj.swig_objdecls:
                print >>out, decl
            continue

        class_path = obj.cxx_class.split('::')
        classname = class_path[-1]
        namespaces = class_path[:-1]
        namespaces.reverse()

        code = ''

        if namespaces:
            code += '// avoid name conflicts\n'
            sep_string = '_COLONS_'
            flat_name = sep_string.join(class_path)
            code += '%%rename(%s) %s;\n' % (flat_name, classname)

        code += '// stop swig from creating/wrapping default ctor/dtor\n'
        code += '%%nodefault %s;\n' % classname
        code += 'class %s ' % classname
        if obj._base:
            code += ': public %s' % obj._base.cxx_class
        code += ' {};\n'

        for ns in namespaces:
            new_code = 'namespace %s {\n' % ns
            new_code += code
            new_code += '}\n'
            code = new_code

        print >>out, code

    print >>out, '%%include "src/sim/sim_object_params.hh"' % obj
    for obj in ordered_objs:
        print >>out, '%%include "params/%s.hh"' % obj

params_file = File('params/params.i')
names = sorted(sim_objects.keys())
env.Command(params_file, map(Value, names), buildParams)
env.Depends(params_file, params_hh_files + params_i_files + depends)
SwigSource('m5.objects', params_file)

# Build all swig modules
for swig in SwigSource.all:
    env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode,
                '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
                '-o ${TARGETS[0]} $SOURCES')
    env.Depends(swig.py_source.tnode, swig.tnode)
    env.Depends(swig.cc_source.tnode, swig.tnode)

# Generate the main swig init file
def makeSwigInit(target, source, env):
    f = file(str(target[0]), 'w')
    print >>f, 'extern "C" {'
    for module in source:
        print >>f, '    void init_%s();' % module.get_contents()
    print >>f, '}'
    print >>f, 'void initSwig() {'
    for module in source:
        print >>f, '    init_%s();' % module.get_contents()
    print >>f, '}'
    f.close()

env.Command('python/swig/init.cc',
            map(Value, sorted(s.module for s in SwigSource.all)),
            makeSwigInit)
Source('python/swig/init.cc')

def getFlags(source_flags):
    flagsMap = {}
    flagsList = []
    for s in source_flags:
        val = eval(s.get_contents())
        name, compound, desc = val
        flagsList.append(val)
        flagsMap[name] = bool(compound)
    
    for name, compound, desc in flagsList:
        for flag in compound:
            if flag not in flagsMap:
                raise AttributeError, "Trace flag %s not found" % flag
            if flagsMap[flag]:
                raise AttributeError, \
                    "Compound flag can't point to another compound flag"

    flagsList.sort()
    return flagsList


# Generate traceflags.py
def traceFlagsPy(target, source, env):
    assert(len(target) == 1)

    f = file(str(target[0]), 'w')
   
    allFlags = getFlags(source)

    print >>f, 'basic = ['
    for flag, compound, desc in allFlags:
        if not compound:
            print >>f, "    '%s'," % flag
    print >>f, "    ]"
    print >>f

    print >>f, 'compound = ['
    print >>f, "    'All',"
    for flag, compound, desc in allFlags:
        if compound:
            print >>f, "    '%s'," % flag
    print >>f, "    ]"
    print >>f

    print >>f, "all = frozenset(basic + compound)"
    print >>f

    print >>f, 'compoundMap = {'
    all = tuple([flag for flag,compound,desc in allFlags if not compound])
    print >>f, "    'All' : %s," % (all, )
    for flag, compound, desc in allFlags:
        if compound:
            print >>f, "    '%s' : %s," % (flag, compound)
    print >>f, "    }"
    print >>f

    print >>f, 'descriptions = {'
    print >>f, "    'All' : 'All flags',"
    for flag, compound, desc in allFlags:
        print >>f, "    '%s' : '%s'," % (flag, desc)
    print >>f, "    }"

    f.close()

def traceFlagsCC(target, source, env):
    assert(len(target) == 1)

    f = file(str(target[0]), 'w')

    allFlags = getFlags(source)

    # file header
    print >>f, '''
/*
 * DO NOT EDIT THIS FILE! Automatically generated
 */

#include "base/traceflags.hh"

using namespace Trace;

const char *Trace::flagStrings[] =
{'''

    # The string array is used by SimpleEnumParam to map the strings
    # provided by the user to enum values.
    for flag, compound, desc in allFlags:
        if not compound:
            print >>f, '    "%s",' % flag

    print >>f, '    "All",'
    for flag, compound, desc in allFlags:
        if compound:
            print >>f, '    "%s",' % flag

    print >>f, '};'
    print >>f
    print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1)
    print >>f

    #
    # Now define the individual compound flag arrays.  There is an array
    # for each compound flag listing the component base flags.
    #
    all = tuple([flag for flag,compound,desc in allFlags if not compound])
    print >>f, 'static const Flags AllMap[] = {'
    for flag, compound, desc in allFlags:
        if not compound:
            print >>f, "    %s," % flag
    print >>f, '};'
    print >>f

    for flag, compound, desc in allFlags:
        if not compound:
            continue
        print >>f, 'static const Flags %sMap[] = {' % flag
        for flag in compound:
            print >>f, "    %s," % flag
        print >>f, "    (Flags)-1"
        print >>f, '};'
        print >>f

    #
    # Finally the compoundFlags[] array maps the compound flags
    # to their individual arrays/
    #
    print >>f, 'const Flags *Trace::compoundFlags[] ='
    print >>f, '{'
    print >>f, '    AllMap,'
    for flag, compound, desc in allFlags:
        if compound:
            print >>f, '    %sMap,' % flag
    # file trailer
    print >>f, '};'

    f.close()

def traceFlagsHH(target, source, env):
    assert(len(target) == 1)

    f = file(str(target[0]), 'w')

    allFlags = getFlags(source)

    # file header boilerplate
    print >>f, '''
/*
 * DO NOT EDIT THIS FILE!
 *
 * Automatically generated from traceflags.py
 */

#ifndef __BASE_TRACE_FLAGS_HH__
#define __BASE_TRACE_FLAGS_HH__

namespace Trace {

enum Flags {'''

    # Generate the enum.  Base flags come first, then compound flags.
    idx = 0
    for flag, compound, desc in allFlags:
        if not compound:
            print >>f, '    %s = %d,' % (flag, idx)
            idx += 1

    numBaseFlags = idx
    print >>f, '    NumFlags = %d,' % idx

    # put a comment in here to separate base from compound flags
    print >>f, '''
// The remaining enum values are *not* valid indices for Trace::flags.
// They are "compound" flags, which correspond to sets of base
// flags, and are used by changeFlag.'''

    print >>f, '    All = %d,' % idx
    idx += 1
    for flag, compound, desc in allFlags:
        if compound:
            print >>f, '    %s = %d,' % (flag, idx)
            idx += 1

    numCompoundFlags = idx - numBaseFlags
    print >>f, '    NumCompoundFlags = %d' % numCompoundFlags

    # trailer boilerplate
    print >>f, '''\
}; // enum Flags

// Array of strings for SimpleEnumParam
extern const char *flagStrings[];
extern const int numFlagStrings;

// Array of arraay pointers: for each compound flag, gives the list of
// base flags to set.  Inidividual flag arrays are terminated by -1.
extern const Flags *compoundFlags[];

/* namespace Trace */ }

#endif // __BASE_TRACE_FLAGS_HH__
'''

    f.close()

flags = map(Value, trace_flags.values())
env.Command('base/traceflags.py', flags, traceFlagsPy)
PySource('m5', 'base/traceflags.py')

env.Command('base/traceflags.hh', flags, traceFlagsHH)
env.Command('base/traceflags.cc', flags, traceFlagsCC)
Source('base/traceflags.cc')

# embed python files.  All .py files that have been indicated by a
# PySource() call in a SConscript need to be embedded into the M5
# library.  To do that, we compile the file to byte code, marshal the
# byte code, compress it, and then generate an assembly file that
# inserts the result into the data section with symbols indicating the
# beginning, and end (and with the size at the end)
def objectifyPyFile(target, source, env):
    '''Action function to compile a .py into a code object, marshal
    it, compress it, and stick it into an asm file so the code appears
    as just bytes with a label in the data section'''

    src = file(str(source[0]), 'r').read()
    dst = file(str(target[0]), 'w')

    pysource = PySource.tnodes[source[0]]
    compiled = compile(src, pysource.debugname, 'exec')
    marshalled = marshal.dumps(compiled)
    compressed = zlib.compress(marshalled)
    data = compressed

    # Some C/C++ compilers prepend an underscore to global symbol
    # names, so if they're going to do that, we need to prepend that
    # leading underscore to globals in the assembly file.
    if env['LEADING_UNDERSCORE']:
        sym = '_' + pysource.symname
    else:
        sym = pysource.symname

    step = 16
    print >>dst, ".data"
    print >>dst, ".globl %s_beg" % sym
    print >>dst, ".globl %s_end" % sym
    print >>dst, "%s_beg:" % sym
    for i in xrange(0, len(data), step):
        x = array.array('B', data[i:i+step])
        print >>dst, ".byte", ','.join([str(d) for d in x])
    print >>dst, "%s_end:" % sym
    print >>dst, ".long %d" % len(marshalled)

for source in PySource.all:
    env.Command(source.assembly, source.tnode, objectifyPyFile)
    Source(source.assembly)

# Generate init_python.cc which creates a bunch of EmbeddedPyModule
# structs that describe the embedded python code.  One such struct
# contains information about the importer that python uses to get at
# the embedded files, and then there's a list of all of the rest that
# the importer uses to load the rest on demand.
def pythonInit(target, source, env):
    dst = file(str(target[0]), 'w')

    def dump_mod(sym, endchar=','):
        pysource = PySource.symnames[sym]
        print >>dst, '    { "%s",' % pysource.arcname
        print >>dst, '      "%s",' % pysource.modpath
        print >>dst, '       %s_beg, %s_end,' % (sym, sym)
        print >>dst, '       %s_end - %s_beg,' % (sym, sym)
        print >>dst, '       *(int *)%s_end }%s'  % (sym, endchar)
    
    print >>dst, '#include "sim/init.hh"'

    for sym in source:
        sym = sym.get_contents()
        print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym)

    print >>dst, "const EmbeddedPyModule embeddedPyImporter = "
    dump_mod("PyEMB_importer", endchar=';');
    print >>dst

    print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {"
    for i,sym in enumerate(source):
        sym = sym.get_contents()
        if sym == "PyEMB_importer":
            # Skip the importer since we've already exported it
            continue
        dump_mod(sym)
    print >>dst, "    { 0, 0, 0, 0, 0, 0 }"
    print >>dst, "};"


env.Command('sim/init_python.cc',
            map(Value, (s.symname for s in PySource.all)),
            pythonInit)
Source('sim/init_python.cc')

########################################################################
#
# Define binaries.  Each different build type (debug, opt, etc.) gets
# a slightly different build environment.
#

# List of constructed environments to pass back to SConstruct
envList = []

date_source = Source('base/date.cc', skip_lib=True)

# Function to create a new build environment as clone of current
# environment 'env' with modified object suffix and optional stripped
# binary.  Additional keyword arguments are appended to corresponding
# build environment vars.
def makeEnv(label, objsfx, strip = False, **kwargs):
    # SCons doesn't know to append a library suffix when there is a '.' in the
    # name.  Use '_' instead.
    libname = 'm5_' + label
    exename = 'm5.' + label

    new_env = env.Clone(OBJSUFFIX=objsfx, SHOBJSUFFIX=objsfx + 's')
    new_env.Label = label
    new_env.Append(**kwargs)

    swig_env = new_env.Clone()
    swig_env.Append(CCFLAGS='-Werror')
    if env['GCC']:
        swig_env.Append(CCFLAGS='-Wno-uninitialized')
        swig_env.Append(CCFLAGS='-Wno-sign-compare')
        swig_env.Append(CCFLAGS='-Wno-parentheses')

    werror_env = new_env.Clone()
    werror_env.Append(CCFLAGS='-Werror')

    def make_obj(source, static, extra_deps = None):
        '''This function adds the specified source to the correct
        build environment, and returns the corresponding SCons Object
        nodes'''

        if source.swig:
            env = swig_env
        elif source.Werror:
            env = werror_env
        else:
            env = new_env

        if static:
            obj = env.StaticObject(source.tnode)
        else:
            obj = env.SharedObject(source.tnode)

        if extra_deps:
            env.Depends(obj, extra_deps)

        return obj

    static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)]
    shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)]

    static_date = make_obj(date_source, static=True, extra_deps=static_objs)
    static_objs.append(static_date)
    
    shared_date = make_obj(date_source, static=False, extra_deps=shared_objs)
    shared_objs.append(shared_date)

    # First make a library of everything but main() so other programs can
    # link against m5.
    static_lib = new_env.StaticLibrary(libname, static_objs)
    shared_lib = new_env.SharedLibrary(libname, shared_objs)

    for target, sources in unit_tests:
        objs = [ make_obj(s, static=True) for s in sources ]
        new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs)

    # Now link a stub with main() and the static library.
    bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ]
    progname = exename
    if strip:
        progname += '.unstripped'

    targets = new_env.Program(progname, bin_objs + static_objs)

    if strip:
        if sys.platform == 'sunos5':
            cmd = 'cp $SOURCE $TARGET; strip $TARGET'
        else:
            cmd = 'strip $SOURCE -o $TARGET'
        targets = new_env.Command(exename, progname, cmd)
            
    new_env.M5Binary = targets[0]
    envList.append(new_env)

# Debug binary
ccflags = {}
if env['GCC']:
    if sys.platform == 'sunos5':
        ccflags['debug'] = '-gstabs+'
    else:
        ccflags['debug'] = '-ggdb3'
    ccflags['opt'] = '-g -O3'
    ccflags['fast'] = '-O3'
    ccflags['prof'] = '-O3 -g -pg'
elif env['SUNCC']:
    ccflags['debug'] = '-g0'
    ccflags['opt'] = '-g -O'
    ccflags['fast'] = '-fast'
    ccflags['prof'] = '-fast -g -pg'
elif env['ICC']:
    ccflags['debug'] = '-g -O0'
    ccflags['opt'] = '-g -O'
    ccflags['fast'] = '-fast'
    ccflags['prof'] = '-fast -g -pg'
else:
    print 'Unknown compiler, please fix compiler options'
    Exit(1)

makeEnv('debug', '.do',
        CCFLAGS = Split(ccflags['debug']),
        CPPDEFINES = ['DEBUG', 'TRACING_ON=1'])

# Optimized binary
makeEnv('opt', '.o',
        CCFLAGS = Split(ccflags['opt']),
        CPPDEFINES = ['TRACING_ON=1'])

# "Fast" binary
makeEnv('fast', '.fo', strip = True,
        CCFLAGS = Split(ccflags['fast']),
        CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'])

# Profiled binary
makeEnv('prof', '.po',
        CCFLAGS = Split(ccflags['prof']),
        CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
        LINKFLAGS = '-pg')

Return('envList')
