# -*- 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 collections
import copy
import distutils.spawn
import itertools
import os
import os.path
import re
import sys

import SCons

from gem5_scons import Configure, error, FromValue, ToValue, Transform, warning
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('*')

if env['CONF']['USE_EFENCE']:
    env.Append(LIBS=['efence'])

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

build_env = list(env['CONF'].items())

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

class SourceLib(SourceItem):
    def __init__(self, *args, **kwargs):
        self.priority = kwargs.pop('priority', 0)
        super().__init__(*args, **kwargs)

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.File('gem5py')
gem5py_m5 = gem5py_env.File('gem5py_m5')
gem5py_env['GEM5PY'] = gem5py
gem5py_env['GEM5PY_M5'] = gem5py_m5
gem5py_env['OBJSUFFIX'] = '.pyo'
# 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'''
    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.modpath = modpath

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

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

    def __init__(self, source, *, sim_objects=None, enums=None,
            tags=None, add_tags=None):
        '''Specify the source file and any tags (automatically in
        the m5.objects package)'''
        if sim_objects is None:
            if enums is None:
                error(f"SimObject({source}...) must list c++ sim_objects or "
                      "enums (set either to [] if there are none).")
            sim_objects = []
        if enums is None:
            enums = []

        super().__init__('m5.objects', source, tags, add_tags)

        build_dir = Dir(env['BUILDDIR'])
        module = self.modpath

        # Generate all of the SimObject param C++ files.
        for simobj in sim_objects:
            # Some helper functions
            srcs = [ Value(module), Value(simobj),
                    "${GEM5PY_M5}", "${PYSCRIPT}" ]
            def cmdline(*args):
                all_args = [ 'GEM5PY_M5', 'PYSCRIPT', 'MODULE' ] + list(args)
                return ' '.join(list('"${%s}"' % arg for arg in all_args))

            # Params header.
            gem5py_env.Command([ "${PARAMS_HH}" ], srcs,
                    MakeAction(cmdline('PARAMS_HH'), Transform("SO Param", 2)),
                    MODULE=module,
                    SIMOBJ=simobj,
                    PYSCRIPT=build_tools.File('sim_object_param_struct_hh.py'),
                    PARAMS_HH=build_dir.File(f'params/{simobj}.hh'))

            # Params cc.
            cc_file = build_dir.File(f'python/_m5/param_{simobj}.cc')
            gem5py_env.Command([ "${PARAMS_CC}" ], srcs,
                    MakeAction(cmdline('PARAMS_CC', 'USE_PYTHON'),
                        Transform("SO Param", 2)),
                    PYSCRIPT=build_tools.File('sim_object_param_struct_cc.py'),
                    MODULE=module,
                    SIMOBJ=simobj,
                    PARAMS_CC=cc_file,
                    USE_PYTHON=env['USE_PYTHON'])
            Source(cc_file, tags=self.tags,
                   add_tags=('python' if env['USE_PYTHON'] else None))

            # CXX config header.
            gem5py_env.Command([ "${CXXCONFIG_HH}" ], srcs,
                    MakeAction(cmdline('CXXCONFIG_HH'),
                        Transform("CXXCPRHH", 2)),
                    PYSCRIPT=build_tools.File('cxx_config_hh.py'),
                    MODULE=module,
                    CXXCONFIG_HH=build_dir.File(f'cxx_config/{simobj}.hh'))

            # CXX config cc.
            cc_file=build_dir.File(f'cxx_config/{simobj}.cc')
            gem5py_env.Command([ "${CXXCONFIG_CC}" ], srcs,
                    MakeAction(cmdline('CXXCONFIG_CC'),
                        Transform("CXXCPRCC", 2)),
                    PYSCRIPT=build_tools.File('cxx_config_cc.py'),
                    MODULE=module,
                    CXXCONFIG_CC=cc_file)
            if GetOption('with_cxx_config'):
                Source(cc_file, tags=self.tags)

        # C++ versions of enum params.
        for enum in enums:
            gem5py_env.Command([ "${ENUM_HH}" ],
                    [ Value(module), Value(enum),
                        "${GEM5PY_M5}", "${ENUMHH_PY}" ],
                    MakeAction('"${GEM5PY_M5}" "${ENUMHH_PY}" "${MODULE}" ' \
                            '"${ENUM_HH}"',
                        Transform("ENUMDECL", 2)),
                    MODULE=module,
                    ENUM=enum,
                    ENUM_HH=build_dir.File(f'enums/{enum}.hh'),
                    ENUMHH_PY=build_tools.File('enum_hh.py'))
            cc_file = build_dir.File(f'enums/{enum}.cc')
            gem5py_env.Command([ "${ENUM_CC}" ],
                    [ Value(module), Value(enum),
                        "${GEM5PY_M5}", "${ENUMCC_PY}" ],
                    MakeAction('"${GEM5PY_M5}" "${ENUMCC_PY}" "${MODULE}" ' \
                            '"${ENUM_CC}" "${USE_PYTHON}"',
                        Transform("ENUM STR", 2)),
                    MODULE=module,
                    ENUM=enum,
                    ENUM_CC=cc_file,
                    ENUMCC_PY=build_tools.File('enum_cc.py'),
                    USE_PYTHON=env['USE_PYTHON'])
            Source(cc_file, tags=self.tags,
                   add_tags=('python' if env['USE_PYTHON'] else None))

# 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_scanner = SCons.Scanner.Classic(name='ProtobufScanner',
                                       suffixes=['.proto'],
                                       path_variable='BUILDDIR',
                                       regex=r'^import\s+\"(.*\.proto)\"\;$')
env.Append(SCANNERS=protoc_scanner)

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

# To understand these variables and attributes, see:
# https://scons.org/doc/production/HTML/scons-man.html#variable_substitution
protoc_action = MakeAction('${PROTOC} --cpp_out ${TARGET.dir.abspath} '
        '--proto_path ${SOURCE.dir.abspath} ${SOURCE.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'''
    Source(source, tags, add_tags, append={'CXXFLAGS': '-Wno-array-bounds'})

env['PROTOC_GRPC'] = distutils.spawn.find_executable('grpc_cpp_plugin')
if env['PROTOC_GRPC']:
    with Configure(env) as conf:
        if (not env['HAVE_PKG_CONFIG'] or
            not conf.CheckPkgConfig(['grpc++'], '--libs')):
            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)
        isLib = lambda arg: isinstance(arg, SourceLib)
        # If something isn't a library or filter, assume it's a source file.
        isSourceFile = lambda arg: not isFilter(arg) and not isLib(arg)
        self.filters = list(filter(isFilter, srcs_and_filts))
        self.sourceLibs = list(filter(isLib, srcs_and_filts))
        source_files = list(filter(isSourceFile, srcs_and_filts))

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

        self.dir = Dir('.')

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

    def libs(self, env):
        libs = copy.copy(self.sourceLibs)
        for f in self.filters:
            libs += SourceLib.all.apply_filter(env, f)
        return libs

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

        env = env.Clone()

        libs = self.libs(env)
        # Higher priority libraries should be earlier in the list.
        libs.sort(key=lambda l: l.priority, reverse=True)
        if libs:
            env.Append(LIBS=list(lib.source for lib in libs))

        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)

        libs = self.libs(env)
        # Higher priority libraries should be earlier in the list.
        libs.sort(key=lambda l: l.priority, reverse=True)
        if libs:
            env.Append(LIBS=list(lib.source for lib in libs))

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

########################################################################
#
# 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 env['CONF'].keys():
    env.ConfigFile(opt)

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

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

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


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

gem5py_m5_env = gem5py_env.Clone()
gem5py_env.Append(CPPPATH=env['CPPPATH'])
gem5py_env.Append(LIBS='z')
gem5py_env.Program(gem5py, 'python/gem5py.cc')[0]
m5_module_source = \
        Source.all.with_all_tags(env, 'm5_module', 'gem5 lib')
m5_module_static = list(map(lambda s: s.static(gem5py_env), m5_module_source))
gem5py_env.Program(gem5py_m5, [ 'python/gem5py.cc' ] + m5_module_static)


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