#!/usr/bin/env python
# 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()
