# -*- mode:python -*-

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

###################################################
#
# SCons top-level build description (SConstruct) file.
#
# To build M5, you need a directory with three things:
# 1. A copy of this file (named SConstruct).
# 2. A link named 'm5' to the top of the M5 simulator source tree.
# 3. A link named 'ext' to the top of the M5 external source tree.
#
# Then type 'scons' to build the default configuration (see below), or
# 'scons <CONFIG>/<binary>' to build some other configuration (e.g.,
# 'ALPHA_FS/m5.opt' for the optimized full-system version).
#
###################################################

# Python library imports
import sys
import os

# Check for recent-enough Python and SCons versions
EnsurePythonVersion(2,3)
EnsureSConsVersion(0,96)

# The absolute path to the current directory (where this file lives).
ROOT = Dir('.').abspath

# Paths to the M5 and external source trees (local symlinks).
SRCDIR = os.path.join(ROOT, 'm5')
EXT_SRCDIR = os.path.join(ROOT, 'ext')

# Check for 'm5' and 'ext' links, die if they don't exist.
if not os.path.isdir(SRCDIR):
    print "Error: '%s' must be a link to the M5 source tree." % SRCDIR
    Exit(1)

if not os.path.isdir('ext'):
    print "Error: '%s' must be a link to the M5 external source tree." \
          % EXT_SRCDIR
    Exit(1)

# tell python where to find m5 python code
sys.path.append(os.path.join(SRCDIR, 'python'))

###################################################
#
# Figure out which configurations to set up.
#
#
# It's prohibitive to do all the combinations of base configurations
# and options, so we have to infer which ones the user wants.
#
# 1. If there are command-line targets, the configuration(s) are inferred
#    from the directories of those targets.  If scons was invoked from a
#    subdirectory (using 'scons -u'), those targets have to be
#    interpreted relative to that subdirectory.
#
# 2. If there are no command-line targets, and scons was invoked from a
#    subdirectory (using 'scons -u'), the configuration is inferred from
#    the name of the subdirectory.
#
# 3. If there are no command-line targets and scons was invoked from
#    the root build directory, a default configuration is used.  The
#    built-in default is ALPHA_SE, but this can be overridden by setting the
#    M5_DEFAULT_CONFIG shell environment veriable.
#
# In cases 2 & 3, the specific file target defaults to 'm5.debug', but
# this can be overridden by setting the M5_DEFAULT_BINARY shell
# environment veriable.
#
###################################################

# Find default configuration & binary.
default_config = os.environ.get('M5_DEFAULT_CONFIG', 'ALPHA_SE')
default_binary = os.environ.get('M5_DEFAULT_BINARY', 'm5.debug')

# Ask SCons which directory it was invoked from.  If you invoke SCons
# from a subdirectory you must use the '-u' flag.
launch_dir = GetLaunchDir()

# Build a list 'my_targets' of all the targets relative to ROOT.
if launch_dir == ROOT:
    # invoked from root build dir
    if len(COMMAND_LINE_TARGETS) != 0:
        # easy: use specified targets as is
        my_targets = COMMAND_LINE_TARGETS
    else:
        # default target (ALPHA_SE/m5.debug, unless overridden)
        target = os.path.join(default_config, default_binary)
        my_targets = [target]
        Default(target)
else:
    # invoked from subdirectory
    if not launch_dir.startswith(ROOT):
        print "Error: launch dir (%s) not a subdirectory of ROOT (%s)!" \
              (launch_dir, ROOT)
        Exit(1)
    # make launch_dir relative to ROOT (strip ROOT plus slash off front)
    launch_dir = launch_dir[len(ROOT)+1:]
    if len(COMMAND_LINE_TARGETS) != 0:
        # make specified targets relative to ROOT
        my_targets = map(lambda x: os.path.join(launch_dir, x),
                         COMMAND_LINE_TARGETS)
    else:
        # build default binary (m5.debug, unless overridden) using the
        # config inferred by the invocation directory (the first
        # subdirectory after ROOT)
        target = os.path.join(launch_dir.split('/')[0], default_binary)
        my_targets = [target]
        Default(target)

# Normalize target paths (gets rid of '..' in the middle, etc.)
my_targets = map(os.path.normpath, my_targets)

# Generate a list of the unique configs that the collected targets reference.
build_dirs = []
for t in my_targets:
    dir = t.split('/')[0]
    if dir not in build_dirs:
        build_dirs.append(dir)

###################################################
#
# Set up the default build environment.  This environment is copied
# and modified according to each selected configuration.
#
###################################################

env = Environment(ENV = os.environ,  # inherit user's environment vars
                  ROOT = ROOT,
                  SRCDIR = SRCDIR,
                  EXT_SRCDIR = EXT_SRCDIR)

env.SConsignFile("sconsign")

# I waffle on this setting... it does avoid a few painful but
# unnecessary builds, but it also seems to make trivial builds take
# noticeably longer.
if False:
    env.TargetSignatures('content')

# M5_EXT is used by isa_parser.py to find the PLY package.
env.Append(ENV = { 'M5_EXT' : EXT_SRCDIR })

# Set up default C++ compiler flags
env.Append(CCFLAGS='-pipe')
env.Append(CCFLAGS='-fno-strict-aliasing')
env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
if sys.platform == 'cygwin':
    # cygwin has some header file issues...
    env.Append(CCFLAGS=Split("-Wno-uninitialized"))
env.Append(CPPPATH=[os.path.join(EXT_SRCDIR + '/dnet')])

# Default libraries
env.Append(LIBS=['z'])

# Platform-specific configuration
conf = Configure(env)

# Check for <fenv.h> (C99 FP environment control)
have_fenv = conf.CheckHeader('fenv.h', '<>')
if not have_fenv:
    print "Warning: Header file <fenv.h> not found."
    print "         This host has no IEEE FP rounding mode control."

# Check for mysql.
mysql_config = WhereIs('mysql_config')
have_mysql = mysql_config != None

# Check MySQL version.
if have_mysql:
    mysql_version = os.popen(mysql_config + ' --version').read()
    mysql_version = mysql_version.split('.')
    mysql_major = int(mysql_version[0])
    mysql_minor = int(mysql_version[1])
    # This version check is probably overly conservative, but it deals
    # with the versions we have installed.
    if mysql_major < 3 or \
           mysql_major == 3 and mysql_minor < 23 or \
           mysql_major == 4 and mysql_minor < 1:
        print "Warning: MySQL v3.23 or v4.1 or newer required."
        have_mysql = False

# Set up mysql_config commands.
if have_mysql:
    mysql_config_include = mysql_config + ' --include'
    if os.system(mysql_config_include + ' > /dev/null') != 0:
        # older mysql_config versions don't support --include, use
        # --cflags instead
        mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g'
    # This seems to work in all versions
    mysql_config_libs = mysql_config + ' --libs'

env = conf.Finish()

# Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new
# value becomes sticky).
sticky_opts = Options(args=ARGUMENTS)
sticky_opts.AddOptions(
    EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha')),
    BoolOption('FULL_SYSTEM', 'Full-system support', False),
    BoolOption('ALPHA_TLASER',
               'Model Alpha TurboLaser platform (vs. Tsunami)', False),
    BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
    BoolOption('EFENCE', 'Link with Electric Fence malloc debugger',
               False),
    BoolOption('SS_COMPATIBLE_FP',
               'Make floating-point results compatible with SimpleScalar',
               False),
    BoolOption('STATS_BINNING', 'Bin statistics by CPU mode', have_mysql),
    BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
    BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
    ('CC', 'C compiler', os.environ.get('CC', env['CC'])),
    ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
    BoolOption('BATCH', 'Use batch pool for build and tests', False),
    ('BATCH_CMD', 'Batch pool submission command name', 'qdo')
    )

# Non-sticky options only apply to the current build.
nonsticky_opts = Options(args=ARGUMENTS)
nonsticky_opts.AddOptions(
    BoolOption('update_ref', 'Update test reference outputs', False)
    )

# These options get exported to #defines in config/*.hh (see m5/SConscript).
env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
                     'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
                     'STATS_BINNING']

# Define a handy 'no-op' action
def no_action(target, source, env):
    return 0

env.NoAction = Action(no_action, None)

# libelf build is described in its own SConscript file.
# SConscript-global is the build in build/libelf shared among all
# configs.
env.SConscript('m5/libelf/SConscript-global', exports = 'env')

###################################################
#
# Define a SCons builder for configuration flag headers.
#
###################################################

# This function generates a config header file that #defines the
# option symbol to the current option setting (0 or 1).  The source
# operands are the name of the option and a Value node containing the
# value of the option.
def build_config_file(target, source, env):
    (option, value) = [s.get_contents() for s in source]
    f = file(str(target[0]), 'w')
    print >> f, '#define', option, value
    f.close()
    return None

# Generate the message to be printed when building the config file.
def build_config_file_string(target, source, env):
    (option, value) = [s.get_contents() for s in source]
    return "Defining %s as %s in %s." % (option, value, target[0])

# Combine the two functions into a scons Action object.
config_action = Action(build_config_file, build_config_file_string)

# The emitter munges the source & target node lists to reflect what
# we're really doing.
def config_emitter(target, source, env):
    # extract option name from Builder arg
    option = str(target[0])
    # True target is config header file
    target = os.path.join('config', option.lower() + '.hh')
    # Force value to 0/1 even if it's a Python bool
    val = int(eval(str(env[option])))
    # Sources are option name & value (packaged in SCons Value nodes)
    return ([target], [Value(option), Value(val)])

config_builder = Builder(emitter = config_emitter, action = config_action)

env.Append(BUILDERS = { 'ConfigFile' : config_builder })

###################################################
#
# Define build environments for selected configurations.
#
###################################################

# rename base env
base_env = env

for build_dir in build_dirs:
    # Make a copy of the default environment to use for this config.
    env = base_env.Copy()
    # Set env according to the build directory config.

    sticky_opts.files = []
    # Name of default options file is taken from 'default=' on command
    # line if set, otherwise name of build dir.
    default_options_file = os.path.join('build_options', 'default',
                                        ARGUMENTS.get('default', build_dir))
    if os.path.isfile(default_options_file):
        sticky_opts.files.append(default_options_file)
    current_options_file = os.path.join('build_options', 'current', build_dir)
    if os.path.isfile(current_options_file):
        sticky_opts.files.append(current_options_file)
    else:
        # if file doesn't exist, make sure at least the directory is there
        # so we can create it later
        opt_dir = os.path.dirname(current_options_file)
        if not os.path.isdir(opt_dir):
            os.mkdir(opt_dir)
    if not sticky_opts.files:
        print "%s: No options file found in build_options, using defaults." \
              % build_dir

    # Apply current option settings to env
    sticky_opts.Update(env)
    nonsticky_opts.Update(env)

    # Process option settings.

    if not have_fenv and env['USE_FENV']:
        print "Warning: <fenv.h> not available; " \
              "forcing USE_FENV to False in", build_dir + "."
        env['USE_FENV'] = False

    if not env['USE_FENV']:
        print "Warning: No IEEE FP rounding mode control in", build_dir + "."
        print "         FP results may deviate slightly from other platforms."

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

    if env['USE_MYSQL']:
        if not have_mysql:
            print "Warning: MySQL not available; " \
                  "forcing USE_MYSQL to False in", build_dir + "."
            env['USE_MYSQL'] = False
        else:
            print "Compiling in", build_dir, "with MySQL support."
            env.ParseConfig(mysql_config_libs)
            env.ParseConfig(mysql_config_include)

    # Save sticky option settings back to current options file
    sticky_opts.Save(current_options_file, env)

    # Do this after we save setting back, or else we'll tack on an
    # extra 'qdo' every time we run scons.
    if env['BATCH']:
        env['CC']  = env['BATCH_CMD'] + ' ' + env['CC']
        env['CXX'] = env['BATCH_CMD'] + ' ' + env['CXX']

    # The m5/SConscript file sets up the build rules in 'env' according
    # to the configured options.  It returns a list of environments,
    # one for each variant build (debug, opt, etc.)
    envList = SConscript('m5/SConscript', build_dir = build_dir,
                         exports = 'env', duplicate = False)

    # Set up the regression tests for each build.
    for e in envList:
        SConscript('m5-test/SConscript',
                   build_dir = os.path.join(build_dir, 'test', e.Label),
                   exports = { 'env' : e }, duplicate = False)

###################################################
#
# Let SCons do its thing.  At this point SCons will use the defined
# build environments to build the requested targets.
#
###################################################

