#!/usr/bin/env python2.7
# Copyright (c) 2006 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 os, re, sys
from os.path import isdir, isfile, join as joinpath

homedir = os.environ['HOME']

def do_compile():
    #
    # Find SCons
    #
    search_dirs = [ joinpath(homedir, 'local/lib'), '/opt/local/lib',
                    '/usr/local/lib', '/usr/lib' ]

    if os.environ.has_key("SCONS_LIB_DIR"):
        search_dirs.append(os.environ["SCONS_LIB_DIR"])

    local = re.compile(r'^scons-local-([0-9]*)\.([0-9]*)\.([0-9]*)$')
    standard = re.compile(r'^scons-([0-9]*)\.([0-9]*)\.([0-9]*)$')

    scons_dirs = []
    for dir in search_dirs:
        if not isdir(dir):
            continue

        entries = os.listdir(dir)
        for entry in entries:
            if not entry.startswith('scons'):
                continue

            version = (0,0,0)
            path = joinpath(dir, entry)

            match = local.search(entry)
            if not match:
                match = standard.search(entry)

            if match:
                version = match.group(1), match.group(2), match.group(3)

            scons_dirs.append((version, path))

    scons_dirs.sort()
    scons_dirs.reverse()

    if not scons_dirs:
        print >>sys.stderr, \
              "could not find scons in the following dirs: %s" % search_dirs
        sys.exit(1)

    sys.path = [ scons_dirs[0][1] ] + sys.path

    # invoke SCons
    import SCons.Script
    SCons.Script.main()

#
# do argument parsing
#
progname = sys.argv[0]

import optparse

usage = '''%prog [compile options] <version> [SCons options]

%prog assumes that the user has a directory called ~/m5/<version> where
the source tree resides, and a directory called ~/build, where %prog
will create ~/build/<version> if it does not exist and build the resulting
simulators there.

If ~/build is set up in such a way that it points to a local disk on
each host, compiles will be very efficient.  For example:
~/build -> /z/<username>/.build  (Assuming that /z is a local disk and
not NFS mounted, whereas your home directory is NFS mounted).
'''
version = '%prog 0.1'
parser = optparse.OptionParser(usage=usage, version=version,
                               formatter=optparse.TitledHelpFormatter())
parser.disable_interspersed_args()

# current option group
group = None

def set_group(*args, **kwargs):
    '''set the current option group'''
    global group
    if not args and not kwargs:
        group = None
    else:
        group = parser.add_option_group(*args, **kwargs)

def add_option(*args, **kwargs):
    if group:
        return group.add_option(*args, **kwargs)
    else:
        return parser.add_option(*args, **kwargs)

def bool_option(name, default, help):
    '''add a boolean option called --name and --no-name.
    Display help depending on which is the default'''

    tname = '--%s' % name
    fname = '--no-%s' % name
    dest = name.replace('-', '_')
    if default:
        thelp = optparse.SUPPRESS_HELP
        fhelp = help
    else:
        thelp = help
        fhelp = optparse.SUPPRESS_HELP

    add_option(tname, action="store_true", default=default, help=thelp)
    add_option(fname, action="store_false", dest=dest, help=fhelp)

add_option('-n', '--no-compile', default=False, action='store_true',
           help="don't actually compile, just echo SCons command line")
add_option('--everything', default=False, action='store_true',
           help="compile everything that can be compiled")
add_option('-E', "--experimental", action='store_true', default=False,
           help="enable experimental builds")
add_option('-v', "--verbose", default=False, action='store_true',
           help="be verbose")

set_group("Output binary types")
bool_option("debug", default=False, help="compile debug binaries")
bool_option("opt", default=False, help="compile opt binaries")
bool_option("fast", default=False, help="compile fast binaries")
bool_option("prof", default=False, help="compile profile binaries")
add_option('-a', "--all-bin", default=False, action='store_true',
           help="compile debug, opt, and fast binaries")

set_group("ISA options")
bool_option("mips", default=False, help="compile MIPS")
bool_option("sparc", default=False, help="compile SPARC")
add_option('-i', "--all-isa", default=False, action='store_true',
           help="compile all ISAs")

set_group("Emulation options")
bool_option("syscall", default=True,
            help="Do not compile System Call Emulation mode")
bool_option("fullsys", default=True,
            help="Do not compile Full System mode")

def usage(exitcode=None):
    parser.print_help()
    if exitcode is not None:
        sys.exit(exitcode)

(options, args) = parser.parse_args()

if options.everything:
    options.all_bin = True
    options.prof = True
    options.all_isa = True

if options.all_bin:
    options.debug = True
    options.opt = True
    options.fast = True

binaries = []
if options.debug:
    binaries.append('m5.debug')
if options.opt:
    binaries.append('m5.opt')
if options.fast:
    binaries.append('m5.fast')
if options.prof:
    binaries.append('m5.prof')

if not binaries:
    binaries.append('m5.debug')

if options.all_isa:
    options.mips = True
    options.sparc = True

isas = []
if options.mips:
    isas.append('mips')
if options.sparc:
    isas.append('sparc')

modes = []
if options.syscall:
    modes.append('syscall')
if options.fullsys:
    modes.append('fullsys')

if not modes:
    sys.exit("must specify at least one mode")

#
# Convert options into SCons command line arguments
#

# valid combinations of ISA and emulation mode
valid = {
    ('mips',  'syscall') : 'MIPS_SE',
    ('sparc', 'syscall') : 'SPARC_SE' }

# experimental combinations of ISA and emulation mode
experiment = { ('mips', 'fullsys') : 'MIPS_FS',
               ('sparc', 'fullsys') : 'SPARC_FS' }

if options.experimental:
    valid.update(experiment)

builds = []
for isa in isas:
    for mode in modes:
        try:
            build = valid[(isa, mode)]
            builds.append(build)
        except KeyError:
            pass

if not builds:
    sys.exit("must specify at least one valid combination of ISA and mode")

if not args:
    usage(2)

version = args[0]
del args[0]

for bin in binaries:
    for build in builds:
        args.append('%s/%s' % (build, bin))

#
# set up compile
#
build_base = joinpath(homedir, 'build')
m5_base = joinpath(homedir, 'm5')

if not isdir(build_base):
    sys.exit('build directory %s not found' % build_base)

if not isdir(m5_base):
    sys.exit('m5 base directory %s not found' % m5_base)

m5_dir = joinpath(m5_base, version)
if not isdir(m5_dir):
    sys.exit('source directory %s not found' % m5_dir)

# support M5 1.x
oldstyle = isfile(joinpath(m5_dir, 'SConscript'))
if oldstyle:
    ext_dir = joinpath(m5_base, 'ext')
    test_dir = joinpath(m5_base, 'test.' + version)

    if not isdir(ext_dir):
        sys.exit('ext directory not found at %s' % ext_dir)

    if not isdir(test_dir):
        sys.exit('test directory not found at %s' % test_dir)

build_dir = joinpath(build_base, version)
if not isdir(build_dir):
    os.mkdir(build_dir)
    # need some symlinks for m5 1.x
    if oldstyle:
        os.symlink(m5_dir, joinpath(build_dir, 'm5'))
        os.symlink(ext_dir, joinpath(build_dir, 'ext'))
        os.symlink(test_dir, joinpath(build_dir, 'test'))
        os.symlink(joinpath(m5_dir, 'build', 'SConstruct'),
                   joinpath(build_dir, 'SConstruct'))
        os.symlink(joinpath(m5_dir, 'build', 'default_options'),
                   joinpath(build_dir, 'default_options'))

sys.argv = [ progname ]
if oldstyle:
    os.chdir(build_dir)
    sys.argv.extend(args)
else:
    os.chdir(m5_dir)
    for arg in args:
        if not arg.startswith('-') and '=' not in arg:
            arg = joinpath(build_dir, 'build', arg)
        sys.argv.append(arg)

if options.no_compile or options.verbose:
    for arg in sys.argv[1:]:
        print arg

if not options.no_compile:
    do_compile()
