# -*- 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 bisect
import collections
import distutils.spawn
import importlib
import importlib.abc
import importlib.machinery
import importlib.util
import os
import os.path
import re
import sys

import SCons

from gem5_scons import Transform, warning, error, ToValue, FromValue
from gem5_scons.sources import *

Export(SourceFilter.factories)

# 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 code_formatter import code_formatter

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

class Source(SourceFile):
    pass

build_tools = Dir('#build_tools')

# Build a small helper that runs Python code using the same version of Python
# as gem5. This is in an unorthodox location to avoid building it for every
# variant.
gem5py_env = gem5py_env.Clone()
gem5py = gem5py_env.Program('gem5py', 'python/gem5py.cc')[0]
gem5py_env['GEM5PY'] = gem5py
# Inject build_tools into PYTHONPATH for when we run gem5py.
pythonpath = gem5py_env['ENV'].get('PYTHONPATH', '').split(':')
pythonpath.append(build_tools.abspath)
gem5py_env['ENV']['PYTHONPATH'] = ':'.join(pythonpath)

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

    def __init__(self, package, source, tags=None, add_tags=None):
        '''specify the python package, the source file, and any tags'''
        super().__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.modname = modname
        self.modpath = modpath
        self.abspath = abspath

        PySource.modules[modpath] = self

        cpp = File(self.filename + '.cc')

        overrides = {
            'PYSOURCE_MODPATH': modpath,
            'PYSOURCE_ABSPATH': abspath,
            'PYSOURCE': File(source),
            'MARSHAL_PY': build_tools.File('marshal.py')
        }
        gem5py_env.Command(cpp,
            [ '${PYSOURCE}', '${GEM5PY}', '${MARSHAL_PY}' ],
            MakeAction('"${GEM5PY}" "${MARSHAL_PY}" "${TARGET}" ' \
                       '"${PYSOURCE}" "${PYSOURCE_MODPATH}" ' \
                       '"${PYSOURCE_ABSPATH}"',
                       Transform("EMBED PY", max_sources=1)),
            **overrides)
        Source(cpp, tags=self.tags, add_tags='python')

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

    def __init__(self, source, tags=None, add_tags=None):
        '''Specify the source file and any tags (automatically in
        the m5.objects package)'''
        super().__init__('m5.objects', source, tags, add_tags)
        if self.fixed:
            raise AttributeError("Too late to call SimObject now.")


# 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().__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().__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)

        executable = env.Program(self.path(env).abspath, 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 Gem5(Executable):
    '''Base class for the main gem5 executable.'''

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

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

        return super().declare(env, objs)


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().__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().declare_all(env)

    def declare(self, env):
        binary, stripped = super().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
#

debug_flags = set()
def DebugFlagCommon(name, flags, desc, fmt, tags, add_tags):
    if name == "All":
        raise AttributeError('The "All" flag name is reserved')
    if name in debug_flags:
        raise AttributeError(f'Flag {name} already specified')

    debug_flags.add(name)

    hh_file = Dir(env['BUILDDIR']).Dir('debug').File(f'{name}.hh')
    gem5py_env.Command(hh_file,
        [ '${GEM5PY}', '${DEBUGFLAGHH_PY}' ],
        MakeAction('"${GEM5PY}" "${DEBUGFLAGHH_PY}" "${TARGET}" "${NAME}" ' \
                   '"${DESC}" "${FMT}" "${COMPONENTS}"',
        Transform("TRACING", 0)),
        DEBUGFLAGHH_PY=build_tools.File('debugflaghh.py'),
        NAME=name, DESC=desc, FMT=('True' if fmt else 'False'),
        COMPONENTS=':'.join(flags))
    cc_file = Dir(env['BUILDDIR']).Dir('debug').File('%s.cc' % name)
    gem5py_env.Command(cc_file,
            [ "${GEM5PY}", "${DEBUGFLAGCC_PY}" ],
            MakeAction('"${GEM5PY}" "${DEBUGFLAGCC_PY}" "${TARGET}" "${NAME}"',
                Transform("TRACING", 0)),
            DEBUGFLAGCC_PY=build_tools.File('debugflagcc.py'), NAME=name)
    if not add_tags:
        add_tags = set()
    if isinstance(add_tags, str):
        add_tags = { add_tags }
    if not isinstance(add_tags, set):
        add_tags = set(add_tags)
    add_tags.add('gem5 trace')
    Source(cc_file, tags=tags, add_tags=add_tags)

def DebugFlag(name, desc=None, fmt=False, tags=None, add_tags=None):
    DebugFlagCommon(name, (), desc, fmt, tags=tags, add_tags=add_tags)
def CompoundFlag(name, flags, desc=None, tags=None, add_tags=None):
    DebugFlagCommon(name, flags, desc, False, tags=tags, add_tags=add_tags)
def DebugFormatFlag(name, desc=None, tags=None, add_tags=None):
    DebugFlag(name, desc, True, tags=tags, add_tags=add_tags)

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().__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().__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
gem5_lib_simobjects = SimObject.all.with_tag(env, 'gem5 lib')
gem5_lib_modnames = sorted(map(lambda so: so.modname, gem5_lib_simobjects))
for modname in gem5_lib_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

########################################################################
#
# 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):
    code = code_formatter()
    code("buildEnv = $0", FromValue(source[0]))
    code.write(target[0].abspath)

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

# Generate a file that wraps the basic top level files
gem5py_env.Command('python/m5/info.py',
            [ File('#/COPYING'), File('#/LICENSE'), File('#/README'),
                "${GEM5PY}", "${INFOPY_PY}" ],
            MakeAction('"${GEM5PY}" "${INFOPY_PY}" "${TARGET}" '
                       '${SOURCES[:-2]}',
                Transform("INFO", 3)),
            INFOPY_PY=build_tools.File('infopy.py'))
PySource('m5', 'python/m5/info.py')

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

# Generate all of the SimObject param C++ struct header files

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)

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'):
    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

    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)
        env.Depends(cxx_config_cc_file, depends + extra_deps)
        Source(cxx_config_cc_file)

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

    def createCxxConfigInitCC(target, source, env):
        assert len(target) == 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)

    env.Command(cxx_config_init_cc_file, [],
        MakeAction(createCxxConfigInitCC, Transform("CXXCINIT")))
    Source(cxx_config_init_cc_file)

# Generate all enum header files
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)

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

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

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

########################################################################
#
# 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'),
}

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'])

# 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(LINKFLAGS=['-O0'])
    # opt and fast share the same cc flags, also add the optimization to the
    # linkflags as LTO defers the optimization to link time
    for target in ['opt', 'fast']:
        envs[target].Append(CCFLAGS=['-O3', '${LTO_CCFLAGS}'])
        envs[target].Append(LINKFLAGS=['-O3', '${LTO_LINKFLAGS}'])

elif env['CLANG']:
    envs['debug'].Append(CCFLAGS=['-g', '-O0'])
    # opt and fast share the same cc flags
    for target in ['opt', 'fast']:
        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)

Gem5('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)
