# -*- mode:python -*-

# Copyright (c) 2018, 2020 ARM Limited
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# 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.

import array
import bisect
import distutils.spawn
import functools
import imp
import importlib
import importlib.abc
import importlib.machinery
import importlib.util
import os
import os.path
import re
import sys
import zlib

import SCons

from gem5_scons import Transform, warning, error, ToValue, FromValue

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

Import('*')

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

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

from m5.util import code_formatter

########################################################################
# Code for adding source files of various types
#
# When specifying a source file of some type, a set of tags can be
# specified for that file.

def tag_implies(env, tag, tag_list):
    '''
    Associates a tag X to a list of tags which are implied by X.

    For example, assume:
    - Each file <X>.cc is tagged with the tag "Tag <X>".
    - B.cc refers to symbols from A.cc
    - C.cc refers to symbols from B.cc
    - D.cc refers to symbols from A.cc and C.cc

    Then:
    - "Tag A" is implied by "Tag B"
    - "Tag B" is implied by "Tag C"
    - "Tag A" is transitively implied by "Tag C" (from "Tag B")
    - "Tag A" and "Tag C" are implied by "Tag D"
    - "Tag B" is transitively implied by "Tag D" (from "Tag C")
    - "Tag A" is transitively implied by "Tag D" (from transitive "Tag B")

    All of these implications are simply declared as:
        env.TagImplies("Tag B", "Tag A")
        env.TagImplies("Tag C", "Tag B")
        env.TagImplies("Tag D", ["Tag A", "Tag C"])

    So that any use of a tag will automatically include its transitive tags
    after being resolved.
    '''

    env.SetDefault(_tag_implies={})
    implications = env['_tag_implies']

    if isinstance(tag_list, str):
        tag_list = frozenset([tag_list])
    if not isinstance(tag_list, frozenset):
        tag_list = frozenset(tag_list)
    if tag in implications:
        implications[tag] |= tag_list
    else:
        implications[tag] = tag_list

    # Check if any of the tags on which the new tag depends on already
    # has a list of implications. If so, add the list to the new tag's
    # implications
    for t in tag_list:
        if t in implications:
            implications[tag] |= implications[t]

    # Check if another tag depends on this tag. If so, add this tag's
    # implications to that tag.
    for t,implied in implications.items():
        if tag in implied:
            implications[t] |= implications[tag]

env.AddMethod(tag_implies, 'TagImplies')

def resolve_tags(env, tags):
    '''
    Returns the complete set of tags implied (dependencies) by the
    supplied tags.
    '''

    implications = env.SetDefault(_tag_implies={})
    implications = env['_tag_implies']

    if isinstance(tags, str):
        tags = frozenset([tags])
    if not isinstance(tags, frozenset):
        tags = frozenset(tags)

    tags = tags.copy()
    for tag in tags:
        if tag in implications:
            tags |= implications[tag]
    return tags

class SourceFilter(object):
    factories = {}
    def __init__(self, predicate):
        self.predicate = predicate

    def __or__(self, other):
        return SourceFilter(lambda env, tags: self.predicate(env, tags) or
                                              other.predicate(env, tags))

    def __and__(self, other):
        return SourceFilter(lambda env, tags: self.predicate(env, tags) and
                                              other.predicate(env, tags))

def with_any_tags(*tags):
    '''Return a list of sources with any of the supplied tags.'''
    return SourceFilter(lambda env, stags: \
        len(resolve_tags(env, tags) & stags) > 0)

def with_all_tags(*tags):
    '''Return a list of sources with all of the supplied tags.'''
    return SourceFilter(lambda env, stags: resolve_tags(env, tags) <= stags)

def with_tag(tag):
    '''Return a list of sources with the supplied tag.'''
    return with_any_tags(*[tag])

def without_tags(*tags):
    '''Return a list of sources without any of the supplied tags.'''
    return SourceFilter(lambda env, stags: \
        len(resolve_tags(env, tags) & stags) == 0)

def without_tag(tag):
    '''Return a list of sources without the supplied tag.'''
    return without_tags(*[tag])

SourceFilter.factories.update({
    'with_any_tags': with_any_tags,
    'with_all_tags': with_all_tags,
    'with_tag': with_tag,
    'without_tags': without_tags,
    'without_tag': without_tag,
})

Export(SourceFilter.factories)

class SourceList(list):
    def apply_filter(self, env, f):
        def match(source):
            return f.predicate(env, source.tags)
        return SourceList(filter(match, self))

    def __getattr__(self, name):
        func = SourceFilter.factories.get(name, None)
        if not func:
            raise AttributeError

        @functools.wraps(func)
        def wrapper(env, *args, **kwargs):
            return self.apply_filter(env, func(*args, **kwargs))
        return wrapper

class SourceMeta(type):
    '''Meta class for source files that keeps track of all files of a
    particular type.'''
    def __init__(cls, name, bases, dict):
        super(SourceMeta, cls).__init__(name, bases, dict)
        cls.all = SourceList()

class SourceFile(object, metaclass=SourceMeta):
    '''Base object that encapsulates the notion of a source file.
    This includes, the source node, target node, various manipulations
    of those.  A source file also specifies a set of tags which
    describing arbitrary properties of the source file.'''

    def __init__(self, source, tags=None, add_tags=None, append=None):
        if tags is None:
            tags='gem5 lib'
        if isinstance(tags, str):
            tags = { tags }
        if not isinstance(tags, set):
            tags = set(tags)
        self.tags = tags

        if add_tags:
            if isinstance(add_tags, str):
                add_tags = { add_tags }
            if not isinstance(add_tags, set):
                add_tags = set(add_tags)
            self.tags |= add_tags

        self.append = append

        tnode = File(source)

        self.tnode = tnode
        self.filename = str(self.tnode)
        self.snode = tnode.srcnode()

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

    def static(self, env):
        if self.append:
            env = env.Clone()
            env.Append(**self.append)
        return env.StaticObject(self.tnode)

    def shared(self, env):
        if self.append:
            env = env.Clone()
            env.Append(**self.append)
        return env.SharedObject(self.tnode)

def bytesToCppArray(code, symbol, data):
    '''
    Output an array of bytes to a code formatter as a c++ array declaration.
    '''
    code('const std::uint8_t ${symbol}[] = {')
    code.indent()
    step = 16
    for i in range(0, len(data), step):
        x = array.array('B', data[i:i + step])
        strs = map(lambda i: f'{i},', x)
        code(functools.reduce(lambda x, y: x + y, strs))
    code.dedent()
    code('};')

def build_blob(target, source, env):
    '''
    Embed an arbitrary blob into the gem5 executable,
    and make it accessible to C++ as a byte array.
    '''

    with open(str(source[0]), 'rb') as f:
        data = f.read()
    symbol = str(source[1])
    cc, hh = target

    hh_code = code_formatter()
    hh_code('''\
#include <cstddef>
#include <cstdint>

namespace gem5
{
namespace Blobs
{

extern const std::size_t ${symbol}_len;
extern const std::uint8_t ${symbol}[];

} // namespace Blobs
} // namespace gem5
''')
    hh_code.write(str(hh))

    include_path = os.path.relpath(hh.abspath, env['BUILDDIR'])

    cc_code = code_formatter()
    cc_code('''\
#include "${include_path}"

namespace gem5
{
namespace Blobs
{

const std::size_t ${symbol}_len = ${{len(data)}};
''')
    bytesToCppArray(cc_code, symbol, data)
    cc_code('''
} // namespace Blobs
} // namespace gem5
''')
    cc_code.write(str(cc))

blob_action = MakeAction(build_blob, Transform("EMBED BLOB"))

def blob_emitter(target, source, env):
    symbol = str(target[0])
    cc_file = File(symbol + '.cc')
    hh_file = File(symbol + '.hh')
    return [cc_file, hh_file], [source, Value(symbol)]

blob_builder = Builder(action=blob_action, emitter=blob_emitter)
env.Append(BUILDERS={'Blob': blob_builder})

def GdbXml(xml_id, symbol):
    cc, hh = env.Blob(symbol, xml_id)
    Source(cc)

class Source(SourceFile):
    pass

# Build a small helper that marshals the Python code using the same version
# of Python as gem5. This is in an unorthodox location to avoid building it
# for every variant.
py_marshal = marshal_env.Program('marshal', 'python/marshal.cc')[0]

# 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 a c++ file that
# inserts the result into an array.
def embedPyFile(target, source, env):
    def c_str(string):
        if string is None:
            return "0"
        return '"%s"' % string

    '''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. The action takes two
    sources:

    source[0]: Binary used to marshal Python sources
    source[1]: Python script to marshal
    '''

    import subprocess

    marshalled = subprocess.check_output(
            [source[0].abspath, str(source[1])], env=env['ENV'])

    compressed = zlib.compress(marshalled)
    data = compressed
    pysource = PySource.tnodes[source[1]]

    code = code_formatter()
    code('''\
#include "sim/init.hh"

namespace gem5
{
namespace
{

''')
    bytesToCppArray(code, 'embedded_module_data', data)
    # The name of the EmbeddedPython object doesn't matter since it's in an
    # anonymous namespace, and it's constructor takes care of installing it
    # into a global list.
    code('''
EmbeddedPython embedded_module_info(
    ${{c_str(pysource.abspath)}},
    ${{c_str(pysource.modpath)}},
    embedded_module_data,
    ${{len(data)}},
    ${{len(marshalled)}});

} // anonymous namespace
} // namespace gem5
''')
    code.write(str(target[0]))

class PySource(SourceFile):
    '''Add a python source file to the named package'''
    modules = {}
    tnodes = {}

    def __init__(self, package, source, tags=None, add_tags=None):
        '''specify the python package, the source file, and any tags'''
        super(PySource, self).__init__(source, tags, add_tags)

        basename = os.path.basename(self.filename)
        modname, ext = os.path.splitext(basename)
        assert ext == '.py'

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

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

        abspath = self.snode.abspath
        if not os.path.exists(abspath):
            abspath = self.tnode.abspath

        self.package = package
        self.modname = modname
        self.modpath = modpath
        self.abspath = abspath
        self.cpp = File(self.filename + '.cc')

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

        marshal_env.Command(self.cpp, [ py_marshal, self.tnode ],
                        MakeAction(embedPyFile, Transform("EMBED PY")))

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, tags=None, add_tags=None):
        '''Specify the source file and any tags (automatically in
        the m5.objects package)'''
        super(SimObject, self).__init__('m5.objects', source, tags, add_tags)
        if self.fixed:
            raise AttributeError("Too late to call SimObject now.")

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


# This regular expression is simplistic and assumes that the import takes up
# the entire line, doesn't have the keyword "public", uses double quotes, has
# no whitespace at the end before or after the ;, and is all on one line. This
# should still cover most cases, and a completely accurate scanner would be
# MUCH more complex.
protoc_import_re = re.compile(r'^import\s+\"(.*\.proto)\"\;$', re.M)

def protoc_scanner(node, env, path):
    deps = []
    for imp in protoc_import_re.findall(node.get_text_contents()):
        deps.append(Dir(env['BUILDDIR']).File(imp))
    return deps

env.Append(SCANNERS=Scanner(function=protoc_scanner, skeys=['.proto']))

def protoc_emitter(target, source, env):
    root, ext = os.path.splitext(source[0].get_abspath())
    return [root + '.pb.cc', root + '.pb.h'], source

protoc_action = MakeAction('${PROTOC} --cpp_out ${BUILDDIR} '
        '--proto_path ${BUILDDIR} ${SOURCE.get_abspath()}',
        Transform("PROTOC"))
protobuf_builder = Builder(action=protoc_action, emitter=protoc_emitter,
        src_suffix='.proto')
env.Append(BUILDERS={'ProtoBufCC' : protobuf_builder})

c_file, cxx_file = SCons.Tool.createCFileBuilders(env)
cxx_file.add_action('.proto', protoc_action)
cxx_file.add_emitter('.proto', protoc_emitter)

def ProtoBuf(source, tags=None, add_tags=None):
    '''Add a Protocol Buffer to build'''

    if not env['HAVE_PROTOC'] or not env['HAVE_PROTOBUF']:
        error('Got protobuf to build, but lacks support!')

    '''Specify the source file, and any tags'''
    Source(source, tags, add_tags, append={'CXXFLAGS': '-Wno-array-bounds'})

env['PROTOC_GRPC'] = distutils.spawn.find_executable('grpc_cpp_plugin')
if env['PROTOC_GRPC']:
    env.Append(LIBS=['grpc++'])

def protoc_grpc_emitter(target, source, env):
    root, ext = os.path.splitext(source[0].get_abspath())
    return [root + '.grpc.pb.cc', root + '.grpc.pb.h'], source

protoc_grpc_action=MakeAction('${PROTOC} --grpc_out ${BUILDDIR} '
        '--plugin=protoc-gen-grpc=${PROTOC_GRPC} --proto_path ${BUILDDIR} '
        '${SOURCE.get_abspath()}',
        Transform("PROTOC"))

env.Append(BUILDERS={'GrpcProtoBufCC' : Builder(
            action=protoc_grpc_action,
            emitter=protoc_grpc_emitter
        )})

def GrpcProtoBuf(source, tags=None, add_tags=None):
    '''Add a GRPC protocol buffer to the build'''

    if not env['PROTOC_GRPC']:
        error('No grpc_cpp_plugin found')

    Source(env.GrpcProtoBufCC(source=source)[0], tags=tags, add_tags=add_tags)
    Source(env.ProtoBufCC(source=source)[0], tags=tags, add_tags=add_tags)



date_source = File('base/date.cc')

class TopLevelMeta(type):
    '''Meta class for top level build products, ie binaries and libraries.'''
    all = []

    def __init__(cls, name, bases, d):
        TopLevelMeta.all.append(cls)
        super(TopLevelMeta, cls).__init__(name, bases, d)
        cls.all = []

class TopLevelBase(object, metaclass=TopLevelMeta):
    '''Base class for linked build products.'''

    def __init__(self, target, *srcs_and_filts):
        '''Specify the target name and any sources. Sources that are
        not SourceFiles are evalued with Source().'''
        super(TopLevelBase, self).__init__()
        self.all.append(self)
        self.target = target

        isFilter = lambda arg: isinstance(arg, SourceFilter)
        self.filters = filter(isFilter, srcs_and_filts)
        sources = filter(lambda a: not isFilter(a), srcs_and_filts)

        srcs = SourceList()
        for src in sources:
            if not isinstance(src, SourceFile):
                src = Source(src, tags=[])
            srcs.append(src)
        self.srcs = srcs

        self.dir = Dir('.')

    def sources(self, env):
        srcs = self.srcs
        for f in self.filters:
            srcs += Source.all.apply_filter(env, f)
        return srcs

    def srcs_to_objs(self, env, sources):
        return list([ s.static(env) for s in sources ])

    @classmethod
    def declare_all(cls, env):
        return list([ instance.declare(env) for instance in cls.all ])

class StaticLib(TopLevelBase):
    '''Base class for creating a static library from sources.'''

    def declare(self, env):
        objs = self.srcs_to_objs(env, self.sources(env))

        date_obj = env.StaticObject(date_source)
        env.Depends(date_obj, objs)

        return env.StaticLibrary(self.target, [date_obj, objs])[0]

class SharedLib(TopLevelBase):
    '''Base class for creating a shared library from sources.'''

    def srcs_to_objs(self, env, sources):
        return list([ s.shared(env) for s in sources ])

    def declare(self, env):
        objs = self.srcs_to_objs(env, self.sources(env))

        date_obj = env.SharedObject(date_source)
        env.Depends(date_obj, objs)

        return env.SharedLibrary(self.target, [date_obj, objs])[0]

class Executable(TopLevelBase):
    '''Base class for creating an executable from sources.'''

    def path(self, env):
        return self.dir.File(self.target + '.${ENV_LABEL}')

    def declare(self, env, objs=None):
        if objs is None:
            objs = self.srcs_to_objs(env, self.sources(env))

        env = env.Clone()
        env['BIN_RPATH_PREFIX'] = os.path.relpath(
                env['BUILDDIR'], self.path(env).dir.abspath)

        date_obj = env.StaticObject(date_source)
        env.Depends(date_obj, objs)

        executable = env.Program(self.path(env).abspath, [date_obj, objs])[0]

        if sys.platform == 'sunos5':
            cmd = 'cp $SOURCE $TARGET; strip $TARGET'
        else:
            cmd = 'strip $SOURCE -o $TARGET'
        stripped = env.Command(str(executable) + '.stripped',
                executable, MakeAction(cmd, Transform("STRIP")))[0]

        return [executable, stripped]

class GTest(Executable):
    '''Create a unit test based on the google test framework.'''
    all = []
    def __init__(self, *srcs_and_filts, **kwargs):
        if not kwargs.pop('skip_lib', False):
            srcs_and_filts = srcs_and_filts + (with_tag('gtest lib'),)
        super(GTest, self).__init__(*srcs_and_filts)

    @classmethod
    def declare_all(cls, env):
        env = env.Clone()
        env['OBJSUFFIX'] = '.t' + env['OBJSUFFIX'][1:]
        env['SHOBJSUFFIX'] = '.t' + env['SHOBJSUFFIX'][1:]
        env.Append(LIBS=env['GTEST_LIBS'])
        env.Append(CPPFLAGS=env['GTEST_CPPFLAGS'])
        env['GTEST_OUT_DIR'] = \
            Dir(env['BUILDDIR']).Dir('unittests.${ENV_LABEL}')
        return super(GTest, cls).declare_all(env)

    def declare(self, env):
        binary, stripped = super(GTest, self).declare(env)

        out_dir = env['GTEST_OUT_DIR']
        xml_file = out_dir.Dir(str(self.dir)).File(self.target + '.xml')
        AlwaysBuild(env.Command(xml_file.abspath, binary,
            "${SOURCES[0]} --gtest_output=xml:${TARGETS[0]}"))

        return binary


# Children should have access
Export('GdbXml')
Export('Source')
Export('PySource')
Export('SimObject')
Export('ProtoBuf')
Export('GrpcProtoBuf')
Export('Executable')
Export('GTest')

########################################################################
#
# Debug Flags
#

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

    name, components, desc, fmt = FromValue(source[0])

    code = code_formatter()

    typename = "CompoundFlag" if components else "SimpleFlag"
    component_flag_decls = \
            ''.join('extern SimpleFlag& %s;\n' % flag for flag in components)

    # file header boilerplate
    code('''\
#ifndef __DEBUG_${name}_HH__
#define __DEBUG_${name}_HH__

#include "base/compiler.hh" // For namespace deprecation

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Debug, debug);
namespace debug
{

class SimpleFlag;
class CompoundFlag;
extern ${typename}& ${name};
${component_flag_decls}

} // namespace debug
} // namespace gem5

#endif // __DEBUG_${name}_HH__
''')

    code.write(str(target[0]))

debug_flags = {}
def DebugFlag(name, desc=None, fmt=False):
    if name == "All":
        raise AttributeError('The "All" flag name is reserved')
    if name in debug_flags:
        raise AttributeError("Flag {} already specified".format(name))

    flag = (name, (), desc, fmt)
    debug_flags[name] = flag

    hh_file = Dir(env['BUILDDIR']).Dir('debug').File('%s.hh' % name)
    env.Command(hh_file, ToValue(flag),
            MakeAction(makeDebugFlagHH, Transform("TRACING", 0)))

def CompoundFlag(name, flags, desc=None):
    if name == "All":
        raise AttributeError('The "All" flag name is reserved')
    if name in debug_flags:
        raise AttributeError('Flag {} already specified'.format(name))

    flag = (name, flags, desc, False)
    debug_flags[name] = flag

    env.Command(Dir(env['BUILDDIR']).Dir('debug').File('%s.hh' % name),
            ToValue(flag),
            MakeAction(makeDebugFlagHH, Transform("TRACING", 0)))

def DebugFormatFlag(name, desc=None):
    DebugFlag(name, desc, True)

Export('DebugFlag')
Export('CompoundFlag')
Export('DebugFormatFlag')

########################################################################
#
# 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))

# Workaround for bug in SCons version > 0.97d20071212
# Scons bug id: 2006 gem5 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 = os.path.join(env['BUILDDIR'], root[len(base_dir) + 1:])
        SConscript(os.path.join(root, 'SConscript'), variant_dir=build_dir)

for extra_dir in extras_dir_list:
    prefix_len = len(os.path.dirname(extra_dir)) + 1

    # Also add the corresponding build directory to pick up generated
    # include files.
    env.Append(CPPPATH=Dir(env['BUILDDIR']).Dir(extra_dir[prefix_len:]))

    for root, dirs, files in os.walk(extra_dir, topdown=True):
        # if build lives in the extras directory, don't walk down it
        if 'build' in dirs:
            dirs.remove('build')

        if 'SConscript' in files:
            build_dir = os.path.join(env['BUILDDIR'], root[prefix_len:])
            SConscript(os.path.join(root, 'SConscript'), variant_dir=build_dir)

for opt in export_vars:
    env.ConfigFile(opt)

def makeTheISA(source, target, env):
    isas = sorted(set(env.Split('${ALL_ISAS}')))
    target_isa = env['TARGET_ISA']
    is_null_isa = '1' if (target_isa.lower() == 'null') else '0'

    def namespace(isa):
        return isa[0].upper() + isa[1:].lower() + 'ISA'


    code = code_formatter()
    code('''\
#ifndef __CONFIG_THE_ISA_HH__
#define __CONFIG_THE_ISA_HH__

#define IS_NULL_ISA ${{is_null_isa}}
#define TheISA ${{namespace(target_isa)}}

#endif // __CONFIG_THE_ISA_HH__''')

    code.write(str(target[0]))

env.Command('config/the_isa.hh', [],
            MakeAction(makeTheISA, Transform("CFG ISA", 0)))

def makeTheGPUISA(source, target, env):
    gpu_isa = env['TARGET_GPU_ISA']

    namespace = gpu_isa[0].upper() + gpu_isa[1:].lower() + 'ISA'

    code = code_formatter()
    code('''\
#ifndef TheGpuISA
#define TheGpuISA ${namespace}
#endif // TheGpuISA''')

    code.write(str(target[0]))

env.Command('config/the_gpu_isa.hh', [],
            MakeAction(makeTheGPUISA, Transform("CFG ISA", 0)))

########################################################################
#
# Prevent any SimObjects from being added after this point, they
# should all have been added in the SConscripts above
#
SimObject.fixed = True

class SimpleModuleLoader(importlib.abc.Loader):
    '''A simple wrapper which delegates setting up a module to a function.'''
    def __init__(self, executor):
        super(SimpleModuleLoader, self).__init__()
        self.executor = executor
    def create_module(self, spec):
        return None

    def exec_module(self, module):
        self.executor(module)

class M5MetaPathFinder(importlib.abc.MetaPathFinder):
    def __init__(self, modules):
        super(M5MetaPathFinder, self).__init__()
        self.modules = modules
        self.installed = set()

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

    def find_spec(self, fullname, path, target=None):
        spec = None

        # If this isn't even in the m5 package, ignore it.
        if fullname.startswith('m5.'):
            if fullname.startswith('m5.objects'):
                # When imported in this context, return a spec for a dummy
                # package which just serves to house the modules within it.
                # This is subtley different from "import * from m5.objects"
                # which relies on the __init__.py in m5.objects. That in turn
                # indirectly relies on the c++ based _m5 package which doesn't
                # exist yet.
                if fullname == 'm5.objects':
                    dummy_loader = SimpleModuleLoader(lambda x: None)
                    spec = importlib.machinery.ModuleSpec(
                            name=fullname, loader=dummy_loader,
                            is_package=True)
                    spec.loader_state = self.modules.keys()

                # If this is a module within the m5.objects package, return a
                # spec that maps to its source file.
                elif fullname in self.modules:
                    source = self.modules[fullname]
                    spec = importlib.util.spec_from_file_location(
                            name=fullname, location=source.abspath)

            # The artificial m5.defines subpackage.
            elif fullname == 'm5.defines':
                def build_m5_defines(module):
                    module.__dict__['buildEnv'] = dict(build_env)

                spec = importlib.util.spec_from_loader(name=fullname,
                        loader=SimpleModuleLoader(build_m5_defines))

        # If we're handling this module, write it down so we can unload it
        # later.
        if spec is not None:
            self.installed.add(fullname)

        return spec

import m5.SimObject
import m5.params

m5.SimObject.clear()
m5.params.clear()

# 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.
importer = M5MetaPathFinder(PySource.modules)
sys.meta_path[0:0] = [ importer ]

# 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

for name,obj in sorted(sim_objects.items()):
    for param in obj._params.local.values():
        # load the ptype attribute now because it depends on the
        # current version of SimObject.allClasses, but when scons
        # actually uses the value, all versions of
        # SimObject.allClasses will have been loaded
        param.ptype

########################################################################
#
# calculate extra dependencies
#
module_depends = ["m5", "m5.SimObject", "m5.params"]
depends = [ PySource.modules[dep].snode for dep in module_depends ]
depends.sort(key = lambda x: x.name)

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

# Generate Python file containing a dict specifying the current
# buildEnv flags.
def makeDefinesPyFile(target, source, env):
    build_env = source[0].get_contents().decode('utf-8')

    code = code_formatter()
    code("""
import _m5.core
import m5.util

buildEnv = dict($build_env)

compileDate = _m5.core.compileDate
gem5Version = _m5.core.gem5Version
_globals = globals()
for key,val in _m5.core.__dict__.items():
    if key.startswith('flag_'):
        flag = key[5:]
        _globals[flag] = val
del _globals
""")
    code.write(target[0].abspath)

defines_info = Value(build_env)
# Generate a file with all of the compile options in it
env.Command('python/m5/defines.py', defines_info,
            MakeAction(makeDefinesPyFile, Transform("DEFINES", 0)))
PySource('m5', 'python/m5/defines.py')

# Generate python file containing info about the M5 source code
def makeInfoPyFile(target, source, env):
    code = code_formatter()
    for src in source:
        with open(src.srcnode().abspath, 'r') as f:
            data = ''.join(f)
        code('$src = ${{repr(data)}}')
    code.write(str(target[0]))

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

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

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

    name = source[0].get_text_contents()
    obj = sim_objects[name]

    code = code_formatter()
    obj.cxx_param_decl(code)
    code.write(target[0].abspath)

def createSimObjectCxxConfig(is_header):
    def body(target, source, env):
        assert len(target) == 1 and len(source) == 1

        name = source[0].get_contents().decode('utf-8')
        obj = sim_objects[name]

        code = code_formatter()
        obj.cxx_config_param_file(code, is_header)
        code.write(target[0].abspath)
    return body

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

    name = source[0].get_text_contents()
    use_python = source[1].read()
    obj = all_enums[name]

    code = code_formatter()
    obj.cxx_def(code)
    if use_python:
        obj.pybind_def(code)
    code.write(target[0].abspath)

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

    name = source[0].get_text_contents()
    obj = all_enums[name]

    code = code_formatter()
    obj.cxx_decl(code)
    code.write(target[0].abspath)

def createSimObjectWrappers(target, source, env):
    name = source[0].get_text_contents()
    obj = sim_objects[name]

    code = code_formatter()
    # We want to generate a single .cc file which contains most of the
    # SimObject autogenerated code to reduce the number of files to compile and
    # link. We need to pass in whether python is enabled so that the pybind
    # wrappers are only generated when python is enabled
    obj.params_create_decl(code, env['USE_PYTHON'])
    code.write(target[0].abspath)

# Generate all of the SimObject param C++ struct header files
params_hh_files = []
for name,simobj in sorted(sim_objects.items()):
    # If this simobject's source changes, we need to regenerate the header.
    py_source = PySource.modules[simobj.__module__]
    extra_deps = [ py_source.tnode ]

    # Get the params for just this SimObject, excluding base classes.
    params = simobj._params.local.values()
    # Extract the parameters' c++ types.
    types = sorted(map(lambda p: p.ptype.cxx_type, params))
    # If any of these types have changed, we need to regenerate the header.
    extra_deps.append(Value(types))

    hh_file = File('params/%s.hh' % name)
    params_hh_files.append(hh_file)
    env.Command(hh_file, Value(name),
                MakeAction(createSimObjectParamStruct, Transform("SO PARAM")))
    env.Depends(hh_file, depends + extra_deps)

# C++ parameter description files
if GetOption('with_cxx_config'):
    for name,simobj in sorted(sim_objects.items()):
        py_source = PySource.modules[simobj.__module__]
        extra_deps = [ py_source.tnode ]

        cxx_config_hh_file = File('cxx_config/%s.hh' % name)
        cxx_config_cc_file = File('cxx_config/%s.cc' % name)
        env.Command(cxx_config_hh_file, Value(name),
                    MakeAction(createSimObjectCxxConfig(True),
                    Transform("CXXCPRHH")))
        env.Command(cxx_config_cc_file, Value(name),
                    MakeAction(createSimObjectCxxConfig(False),
                    Transform("CXXCPRCC")))
        env.Depends(cxx_config_hh_file, depends + extra_deps +
                    [File('params/%s.hh' % name), File('sim/cxx_config.hh')])
        env.Depends(cxx_config_cc_file, depends + extra_deps +
                    [cxx_config_hh_file])
        Source(cxx_config_cc_file)

    cxx_config_init_cc_file = File('cxx_config/init.cc')

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

        code = code_formatter()

        for name,simobj in sorted(sim_objects.items()):
            if not hasattr(simobj, 'abstract') or not simobj.abstract:
                code('#include "cxx_config/${name}.hh"')
        code()
        code('namespace gem5')
        code('{')
        code()
        code('void cxxConfigInit()')
        code('{')
        code.indent()
        for name,simobj in sorted(sim_objects.items()):
            not_abstract = not hasattr(simobj, 'abstract') or \
                not simobj.abstract
            if not_abstract and 'type' in simobj.__dict__:
                code('cxx_config_directory["${name}"] = '
                     '${name}CxxConfigParams::makeDirectoryEntry();')
        code.dedent()
        code('}')
        code('')
        code('} // namespace gem5')
        code.write(target[0].abspath)

    py_source = PySource.modules[simobj.__module__]
    extra_deps = [ py_source.tnode ]
    env.Command(cxx_config_init_cc_file, Value(name),
        MakeAction(createCxxConfigInitCC, Transform("CXXCINIT")))
    cxx_param_hh_files = ["cxx_config/%s.hh" % simobj
        for name,simobj in sorted(sim_objects.items())
        if not hasattr(simobj, 'abstract') or not simobj.abstract]
    Depends(cxx_config_init_cc_file, cxx_param_hh_files +
            [File('sim/cxx_config.hh')])
    Source(cxx_config_init_cc_file)

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

    cc_file = File('enums/%s.cc' % name)
    env.Command(cc_file, [Value(name), Value(env['USE_PYTHON'])],
                MakeAction(createEnumStrings, Transform("ENUM STR")))
    env.Depends(cc_file, depends + extra_deps)
    Source(cc_file)

    hh_file = File('enums/%s.hh' % name)
    env.Command(hh_file, Value(name),
                MakeAction(createEnumDecls, Transform("ENUMDECL")))
    env.Depends(hh_file, depends + extra_deps)

# Generate SimObject Python bindings and create method wrapper files
for name,simobj in sorted(sim_objects.items()):
    py_source = PySource.modules[simobj.__module__]
    extra_deps = [ py_source.tnode ]
    cc_file = File('python/_m5/param_%s.cc' % name)
    env.Command(cc_file, Value(name),
                MakeAction(createSimObjectWrappers,
                            Transform("SO PyB/C")))
    env.Depends(cc_file, depends + extra_deps)
    Source(cc_file, add_tags='python')

#
# Handle debug flags
#
def makeDebugFlagCC(target, source, env):
    assert(len(target) == 1 and len(source) == 1)

    code = code_formatter()

    # delay definition of CompoundFlags until after all the definition
    # of all constituent SimpleFlags
    comp_code = code_formatter()

    # file header
    code('''
#include "base/compiler.hh" // For namespace deprecation
#include "base/debug.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Debug, debug);
namespace debug
{

''')

    for name, flag in sorted(source[0].read().items()):
        n, compound, desc, fmt = flag
        assert n == name

        # We intentionally make flag a reference to a heap allocated object so
        # (1) It has a similar interface to a global object like before
        # (2) It does not get destructed at the end of simulation
        # The second property is desirable as global objects from different
        # translation units do not have a defined destruction order, so it'll
        # be unsafe to access debug flags in their destructor in such cases.
        if not compound:
            code('SimpleFlag& $name = *(')
            code.indent()
            if fmt:
                code('new SimpleFlag("$name", "$desc", true)')
            else:
                code('new SimpleFlag("$name", "$desc", false)')
            code.dedent()
            code(');')
        else:
            comp_code('CompoundFlag& $name = *(')
            comp_code.indent()
            comp_code('new CompoundFlag("$name", "$desc", {')
            comp_code.indent()
            for flag in compound:
                comp_code('&$flag,')
            comp_code.dedent()
            comp_code('})')
            comp_code.dedent()
            comp_code(');')

    code.append(comp_code)
    code()
    code('} // namespace debug')
    code('} // namespace gem5')

    code.write(str(target[0]))

# Generate the files for the debug and debug-format flags
env.Command('debug/flags.cc', Value(debug_flags),
            MakeAction(makeDebugFlagCC, Transform("TRACING", 0)))
Source('debug/flags.cc', add_tags='gem5 trace')

# version tags
tags = \
env.Command('sim/tags.cc', None,
            MakeAction('util/cpt_upgrader.py --get-cc-file > $TARGET',
                       Transform("VER TAGS")))
env.AlwaysBuild(tags)

if main['USE_PYTHON']:
    for source in PySource.all:
        Source(source.cpp, tags=source.tags, add_tags='python')

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

env['SHOBJSUFFIX'] = '${OBJSUFFIX}s'

envs = {
    'debug': env.Clone(ENV_LABEL='debug', OBJSUFFIX='.do'),
    'opt': env.Clone(ENV_LABEL='opt', OBJSUFFIX='.o'),
    'fast': env.Clone(ENV_LABEL='fast', OBJSUFFIX='.fo'),
    'prof': env.Clone(ENV_LABEL='prof', OBJSUFFIX='.po'),
    'perf': env.Clone(ENV_LABEL='perf', OBJSUFFIX='.gpo')
}

envs['debug'].Append(CPPDEFINES=['DEBUG', 'TRACING_ON=1'])
envs['opt'].Append(CCFLAGS=['-g'], CPPDEFINES=['TRACING_ON=1'])
envs['fast'].Append(CPPDEFINES=['NDEBUG', 'TRACING_ON=0'])
envs['prof'].Append(CCFLAGS=['-g', '-pg'], LDFLAGS=['-pg'],
        CPPDEFINES=['NDEBUG', 'TRACING_ON=0'])
envs['perf'].Append(CCFLAGS=['-g'], CPPDEFINES=['NDEBUG', 'TRACING_ON=0'],
        LDFLAGS=['-Wl,--no-as-needed', '-lprofiler', '-Wl,--as-needed'])

# For Link Time Optimization, the optimisation flags used to compile
# individual files are decoupled from those used at link time
# (i.e. you can compile with -O3 and perform LTO with -O0), so we need
# to also update the linker flags based on the target.
if env['GCC']:
    if sys.platform == 'sunos5':
        envs['debug'].Append(CCFLAGS=['-gstabs+'])
    else:
        envs['debug'].Append(CCFLAGS=['-ggdb3'])
    envs['debug'].Append(LDFLAGS=['-O0'])
    # opt, fast, prof and perf all share the same cc flags, also add
    # the optimization to the ldflags as LTO defers the optimization
    # to link time
    for target in ['opt', 'fast', 'prof', 'perf']:
        envs[target].Append(CCFLAGS=['-O3', '${LTO_CCFLAGS}'])
        envs[target].Append(LDFLAGS=['-O3', '${LTO_LDFLAGS}'])

elif env['CLANG']:
    envs['debug'].Append(CCFLAGS=['-g', '-O0'])
    # opt, fast, prof and perf all share the same cc flags
    for target in ['opt', 'fast', 'prof', 'perf']:
        envs[target].Append(CCFLAGS=['-O3'])
else:
    error('Unknown compiler, please fix compiler options')


# To speed things up, we only instantiate the build environments we need. We
# try to identify the needed environment for each target; if we can't, we fall
# back on instantiating all the environments just to be safe.

# A set of all the extensions on targets.
target_exts = set({ os.path.splitext(t)[1] for t in BUILD_TARGETS })
needed_envs = set()
for ext in target_exts:
    match = next((e for e in envs.values() if ext in (
                    '.' + e['ENV_LABEL'], e['OBJSUFFIX'])), None)
    if match:
        needed_envs.add(match['ENV_LABEL'])
    else:
        needed_envs |= set(envs.keys())
        break


# SCons doesn't know to append a library suffix when there is a '.' in the
# name. Use '_' instead.
lib_name = 'gem5_${ENV_LABEL}'

lib_filter = with_tag('gem5 lib')

# Without Python, leave out all Python content from the library builds. The
# option doesn't affect gem5 built as a program.
if GetOption('without_python'):
    lib_filter = lib_filter & without_tag('python')

StaticLib(lib_name, lib_filter)
SharedLib(lib_name, lib_filter)

Executable('gem5', with_any_tags('gem5 lib', 'main'))


# Function to create a new build environment as clone of current
# environment 'env' with modified object suffix and optional stripped
# binary.
for env in (envs[e] for e in needed_envs):
    for cls in TopLevelMeta.all:
        cls.declare_all(env)
