#!/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.
#
# Authors: Nathan Binkert

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()
