#! /usr/bin/env python2.7
# Copyright (c) 2005-2007 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.
#
# Authors: Steve Reinhardt

import sys
import os
import optparse
import datetime
from subprocess import call

progname = os.path.basename(sys.argv[0])

optparser = optparse.OptionParser()
add_option = optparser.add_option
add_option('-v', '--verbose', action='store_true', default=False,
           help='echo commands before executing')
add_option('--builds',
           default='ALPHA,' \
           'MIPS,' \
           'NULL,' \
           'NULL_MOESI_hammer,' \
           'NULL_MESI_Two_Level,'  \
           'NULL_MOESI_CMP_directory,' \
           'NULL_MOESI_CMP_token,' \
           'POWER,' \
           'SPARC,' \
           'X86,X86_MESI_Two_Level,' \
           'ARM,' \
           'RISCV,' \
           'HSAIL_X86',
           help="comma-separated build targets to test (default: '%default')")
add_option('--modes',
           default='se,fs',
           help="comma-separated modes to test (default: '%default')")
add_option('--test-variants', default='opt',
           help="comma-separated build variants to test (default: '%default')"\
           ", set to '' for none")
add_option('--compile-variants', default='debug,fast',
           help="comma-separated build variants to compile only (not test) " \
           "(default: '%default'), set to '' for none", metavar='VARIANTS')
add_option('--scons-opts', default='', metavar='OPTS',
           help='scons options')
add_option('-j', '--jobs', type='int', default=1, metavar='N',
           help='number of parallel jobs to use (0 to use all cores)')
add_option('-k', '--keep-going', action='store_true',
           help='keep going after errors')
add_option('--update-ref', action='store_true',
           help='update reference outputs')
add_option('-D', '--build-dir', default='', metavar='DIR',
           help='build directory location')
add_option('-n', "--no-exec", default=False, action='store_true',
           help="don't actually invoke scons, just echo SCons command line")

(options, tests) = optparser.parse_args()


# split a comma-separated list, but return an empty list if given the
# empty string
def split_if_nonempty(s):
    if not s:
        return []
    return s.split(',')

# split list options on ',' to get Python lists
builds = split_if_nonempty(options.builds)
modes = split_if_nonempty(options.modes)
test_variants = split_if_nonempty(options.test_variants)
compile_variants = split_if_nonempty(options.compile_variants)

options.build_dir = os.path.join(options.build_dir, 'build')

# Call os.system() and raise exception if return status is non-zero
def system(cmd):
    try:
        retcode = call(cmd, shell=True)
        if retcode < 0:
            print >>sys.stderr, "Child was terminated by signal", -retcode
            print >>sys.stderr, "When attemping to execute: %s" % cmd
            sys.exit(1)
        elif retcode > 0:
            print >>sys.stderr, "Child returned", retcode
            print >>sys.stderr, "When attemping to execute: %s" % cmd
            sys.exit(1)
    except OSError, e:
        print >>sys.stderr, "Execution failed:", e
        print >>sys.stderr, "When attemping to execute: %s" % cmd
        sys.exit(1)

targets = []

# start with compile-only targets, if any
if compile_variants:
    targets += ['%s/%s/gem5.%s' % (options.build_dir, build, variant)
                for variant in compile_variants
                for build in builds]

# By default run the 'quick' tests, all expands to quick and long
if not tests:
    tests = ['quick']
elif 'all' in tests:
    tests = ['quick', 'long']

# set up test targets for scons, since we don't have any quick SPARC
# full-system tests exclude it
targets += ['%s/%s/tests/%s/%s/%s' % (options.build_dir, build, variant, test,
                                      mode)
            for build in builds
            for variant in test_variants
            for test in tests
            for mode in modes
            if not (build == 'SPARC' and test == 'quick' and mode == 'fs')]

def cpu_count():
    if 'bsd' in sys.platform or sys.platform == 'darwin':
        try:
            return int(os.popen('sysctl -n hw.ncpu').read())
        except ValueError:
            pass
    else:
        try:
            return os.sysconf('SC_NPROCESSORS_ONLN')
        except (ValueError, OSError, AttributeError):
            pass

    raise NotImplementedError('cannot determine number of cpus')

scons_opts = options.scons_opts
if options.jobs != 1:
    if options.jobs == 0:
        options.jobs = cpu_count()
    scons_opts += ' -j %d' % options.jobs
if options.keep_going:
    scons_opts += ' -k'
if options.update_ref:
    scons_opts += ' --update-ref'

# We generally compile gem5.fast only to make sure it compiles OK;
# it's not very useful to run as a regression test since assertions
# are disabled.  Thus there's not much point spending time on
# link-time optimization.
scons_opts += ' --no-lto'

cmd = 'scons --ignore-style %s %s' % (scons_opts, ' '.join(targets))
if options.no_exec:
    print cmd
else:
    system(cmd)
    sys.exit(0)
