# Copyright 2020 Google, Inc.
#
# 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 os

main = Environment()

# Includes which are shared with gem5 itself.
common_include = Dir('..').Dir('..').Dir('include')

src_dir = Dir('src')
build_dir = Dir('build')

def abspath(d):
    return os.path.abspath(str(d))

# Universal settings.
main.Append(CCFLAGS=[ '-O2' ])
main.Append(CPPPATH=[ common_include ])

# Propogate the environment's PATH setting.
main['ENV']['PATH'] = os.environ['PATH']

main['CC'] = '${CROSS_COMPILE}gcc'
main['AS'] = '${CROSS_COMPILE}as'
main['LD'] = '${CROSS_COMPILE}ld'
main['AR'] = '${CROSS_COMPILE}ar'

# Detect some dependencies of some forms of the m5 utility/library.
main['HAVE_JAVA'] = all(key in main for key in ('JAVAC', 'JAR'))
main['HAVE_PKG_CONFIG'] = main.Detect('pkg-config') is not None
main['HAVE_LUA51'] = (main['HAVE_PKG_CONFIG'] and
                      os.system('pkg-config --exists lua51') == 0)

# Put the sconsign file in the build dir so everything can be deleted at once.
main.SConsignFile(os.path.join(abspath(build_dir), 'sconsign'))
# Use soft links instead of hard links when setting up a build directory.
main.SetOption('duplicate', 'soft-copy')

for root, dirs, files in os.walk(abspath(src_dir)):
    # Each SConsopts file describes a variant of the m5 utility.
    if 'SConsopts' in files:
        env = main.Clone()

        # The user may override variant settings by setting environment
        # variables of the form ${VARIANT}.${OPTION}. For instance, to set the
        # CROSS_COMPILE prefix for variant foo to bar-, the user would set an
        # environment variable foo.CROSS_COMPILE=bar-.
        #
        # This also considers scons command line settings which may look like
        # environment variables, but are set after "scons" on the command line.
        def get_variant_opt(name, default):
            var_name = env.subst('${VARIANT}.%s' % name)
            env[name] = os.environ.get(
                    var_name, ARGUMENTS.get(var_name, default))

        # Process the variant's settings in the SConsopts file, storing them
        # in a copy of the primary environment.
        env.SConscript(Dir(root).File('SConsopts'),
                       exports=[ 'env', 'get_variant_opt' ])

        # Once all the options have been configured, set up build targets for
        # this variant.
        variant_dir = build_dir.Dir(env.subst('${VARIANT}'))
        env.SConscript(src_dir.File('SConscript'),
                       variant_dir=variant_dir, exports='env')
