#!/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("alpha", default=False, help="compile Alpha")
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.alpha = True
    options.mips = True
    options.sparc = True

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

if not isas:
    isas.append('alpha')

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 = { ('alpha', 'syscall') : 'ALPHA_SE',
          ('alpha', 'fullsys') : 'ALPHA_FS',
          ('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()
