113540Sandrea.mondelli@ucf.edu#!/usr/bin/env python2.7
23855Sbinkertn@umich.edu# Copyright (c) 2006 The Regents of The University of Michigan
33855Sbinkertn@umich.edu# All rights reserved.
43855Sbinkertn@umich.edu#
53855Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without
63855Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are
73855Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright
83855Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer;
93855Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright
103855Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the
113855Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution;
123855Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its
133855Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from
143855Sbinkertn@umich.edu# this software without specific prior written permission.
153855Sbinkertn@umich.edu#
163855Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173855Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183855Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193855Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203855Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213855Sbinkertn@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223855Sbinkertn@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233855Sbinkertn@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243855Sbinkertn@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253855Sbinkertn@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263855Sbinkertn@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273855Sbinkertn@umich.edu#
283855Sbinkertn@umich.edu# Authors: Nathan Binkert
293855Sbinkertn@umich.edu
303855Sbinkertn@umich.eduimport os, re, sys
313855Sbinkertn@umich.edufrom os.path import isdir, isfile, join as joinpath
323855Sbinkertn@umich.edu
333855Sbinkertn@umich.eduhomedir = os.environ['HOME']
343855Sbinkertn@umich.edu
353855Sbinkertn@umich.edudef do_compile():
363855Sbinkertn@umich.edu    #
373855Sbinkertn@umich.edu    # Find SCons
383855Sbinkertn@umich.edu    #
393855Sbinkertn@umich.edu    search_dirs = [ joinpath(homedir, 'local/lib'), '/opt/local/lib',
403855Sbinkertn@umich.edu                    '/usr/local/lib', '/usr/lib' ]
413855Sbinkertn@umich.edu
423855Sbinkertn@umich.edu    if os.environ.has_key("SCONS_LIB_DIR"):
433855Sbinkertn@umich.edu        search_dirs.append(os.environ["SCONS_LIB_DIR"])
443855Sbinkertn@umich.edu
453855Sbinkertn@umich.edu    local = re.compile(r'^scons-local-([0-9]*)\.([0-9]*)\.([0-9]*)$')
463855Sbinkertn@umich.edu    standard = re.compile(r'^scons-([0-9]*)\.([0-9]*)\.([0-9]*)$')
473855Sbinkertn@umich.edu
483855Sbinkertn@umich.edu    scons_dirs = []
493855Sbinkertn@umich.edu    for dir in search_dirs:
503855Sbinkertn@umich.edu        if not isdir(dir):
513855Sbinkertn@umich.edu            continue
523855Sbinkertn@umich.edu
533855Sbinkertn@umich.edu        entries = os.listdir(dir)
543855Sbinkertn@umich.edu        for entry in entries:
553855Sbinkertn@umich.edu            if not entry.startswith('scons'):
563855Sbinkertn@umich.edu                continue
573855Sbinkertn@umich.edu
583855Sbinkertn@umich.edu            version = (0,0,0)
593855Sbinkertn@umich.edu            path = joinpath(dir, entry)
603855Sbinkertn@umich.edu
613855Sbinkertn@umich.edu            match = local.search(entry)
623855Sbinkertn@umich.edu            if not match:
633855Sbinkertn@umich.edu                match = standard.search(entry)
643855Sbinkertn@umich.edu
653855Sbinkertn@umich.edu            if match:
663855Sbinkertn@umich.edu                version = match.group(1), match.group(2), match.group(3)
673855Sbinkertn@umich.edu
683855Sbinkertn@umich.edu            scons_dirs.append((version, path))
693855Sbinkertn@umich.edu
703855Sbinkertn@umich.edu    scons_dirs.sort()
713855Sbinkertn@umich.edu    scons_dirs.reverse()
723855Sbinkertn@umich.edu
733855Sbinkertn@umich.edu    if not scons_dirs:
743855Sbinkertn@umich.edu        print >>sys.stderr, \
753855Sbinkertn@umich.edu              "could not find scons in the following dirs: %s" % search_dirs
763855Sbinkertn@umich.edu        sys.exit(1)
773855Sbinkertn@umich.edu
783855Sbinkertn@umich.edu    sys.path = [ scons_dirs[0][1] ] + sys.path
793855Sbinkertn@umich.edu
803855Sbinkertn@umich.edu    # invoke SCons
813855Sbinkertn@umich.edu    import SCons.Script
823855Sbinkertn@umich.edu    SCons.Script.main()
833855Sbinkertn@umich.edu
843855Sbinkertn@umich.edu#
853855Sbinkertn@umich.edu# do argument parsing
863855Sbinkertn@umich.edu#
873855Sbinkertn@umich.eduprogname = sys.argv[0]
883855Sbinkertn@umich.edu
893855Sbinkertn@umich.eduimport optparse
903855Sbinkertn@umich.edu
913855Sbinkertn@umich.eduusage = '''%prog [compile options] <version> [SCons options]
923855Sbinkertn@umich.edu
933855Sbinkertn@umich.edu%prog assumes that the user has a directory called ~/m5/<version> where
943855Sbinkertn@umich.eduthe source tree resides, and a directory called ~/build, where %prog
953855Sbinkertn@umich.eduwill create ~/build/<version> if it does not exist and build the resulting
963855Sbinkertn@umich.edusimulators there.
973855Sbinkertn@umich.edu
983855Sbinkertn@umich.eduIf ~/build is set up in such a way that it points to a local disk on
993855Sbinkertn@umich.edueach host, compiles will be very efficient.  For example:
1003855Sbinkertn@umich.edu~/build -> /z/<username>/.build  (Assuming that /z is a local disk and
1013855Sbinkertn@umich.edunot NFS mounted, whereas your home directory is NFS mounted).
1023855Sbinkertn@umich.edu'''
1033855Sbinkertn@umich.eduversion = '%prog 0.1'
1043855Sbinkertn@umich.eduparser = optparse.OptionParser(usage=usage, version=version,
1053855Sbinkertn@umich.edu                               formatter=optparse.TitledHelpFormatter())
1063855Sbinkertn@umich.eduparser.disable_interspersed_args()
1073855Sbinkertn@umich.edu
1083855Sbinkertn@umich.edu# current option group
1093855Sbinkertn@umich.edugroup = None
1103855Sbinkertn@umich.edu
1113855Sbinkertn@umich.edudef set_group(*args, **kwargs):
1123855Sbinkertn@umich.edu    '''set the current option group'''
1133855Sbinkertn@umich.edu    global group
1143855Sbinkertn@umich.edu    if not args and not kwargs:
1153855Sbinkertn@umich.edu        group = None
1163855Sbinkertn@umich.edu    else:
1173855Sbinkertn@umich.edu        group = parser.add_option_group(*args, **kwargs)
1183855Sbinkertn@umich.edu
1193855Sbinkertn@umich.edudef add_option(*args, **kwargs):
1203855Sbinkertn@umich.edu    if group:
1213855Sbinkertn@umich.edu        return group.add_option(*args, **kwargs)
1223855Sbinkertn@umich.edu    else:
1233855Sbinkertn@umich.edu        return parser.add_option(*args, **kwargs)
1243855Sbinkertn@umich.edu
1253855Sbinkertn@umich.edudef bool_option(name, default, help):
1263855Sbinkertn@umich.edu    '''add a boolean option called --name and --no-name.
1273855Sbinkertn@umich.edu    Display help depending on which is the default'''
1283855Sbinkertn@umich.edu
1293855Sbinkertn@umich.edu    tname = '--%s' % name
1303855Sbinkertn@umich.edu    fname = '--no-%s' % name
1313855Sbinkertn@umich.edu    dest = name.replace('-', '_')
1323855Sbinkertn@umich.edu    if default:
1333855Sbinkertn@umich.edu        thelp = optparse.SUPPRESS_HELP
1343855Sbinkertn@umich.edu        fhelp = help
1353855Sbinkertn@umich.edu    else:
1363855Sbinkertn@umich.edu        thelp = help
1373855Sbinkertn@umich.edu        fhelp = optparse.SUPPRESS_HELP
1383855Sbinkertn@umich.edu
1393855Sbinkertn@umich.edu    add_option(tname, action="store_true", default=default, help=thelp)
1403855Sbinkertn@umich.edu    add_option(fname, action="store_false", dest=dest, help=fhelp)
1413855Sbinkertn@umich.edu
1423855Sbinkertn@umich.eduadd_option('-n', '--no-compile', default=False, action='store_true',
1433855Sbinkertn@umich.edu           help="don't actually compile, just echo SCons command line")
1443855Sbinkertn@umich.eduadd_option('--everything', default=False, action='store_true',
1453855Sbinkertn@umich.edu           help="compile everything that can be compiled")
1463855Sbinkertn@umich.eduadd_option('-E', "--experimental", action='store_true', default=False,
1473855Sbinkertn@umich.edu           help="enable experimental builds")
1483855Sbinkertn@umich.eduadd_option('-v', "--verbose", default=False, action='store_true',
1493855Sbinkertn@umich.edu           help="be verbose")
15011320Ssteve.reinhardt@amd.com
1513855Sbinkertn@umich.eduset_group("Output binary types")
1523855Sbinkertn@umich.edubool_option("debug", default=False, help="compile debug binaries")
1533855Sbinkertn@umich.edubool_option("opt", default=False, help="compile opt binaries")
1543855Sbinkertn@umich.edubool_option("fast", default=False, help="compile fast binaries")
1553855Sbinkertn@umich.edubool_option("prof", default=False, help="compile profile binaries")
1563855Sbinkertn@umich.eduadd_option('-a', "--all-bin", default=False, action='store_true',
1573855Sbinkertn@umich.edu           help="compile debug, opt, and fast binaries")
1583855Sbinkertn@umich.edu
1593855Sbinkertn@umich.eduset_group("ISA options")
1603855Sbinkertn@umich.edubool_option("alpha", default=False, help="compile Alpha")
1613855Sbinkertn@umich.edubool_option("mips", default=False, help="compile MIPS")
1623855Sbinkertn@umich.edubool_option("sparc", default=False, help="compile SPARC")
1633855Sbinkertn@umich.eduadd_option('-i', "--all-isa", default=False, action='store_true',
1643855Sbinkertn@umich.edu           help="compile all ISAs")
1653855Sbinkertn@umich.edu
1663855Sbinkertn@umich.eduset_group("Emulation options")
1673855Sbinkertn@umich.edubool_option("syscall", default=True,
1683855Sbinkertn@umich.edu            help="Do not compile System Call Emulation mode")
1693855Sbinkertn@umich.edubool_option("fullsys", default=True,
1703855Sbinkertn@umich.edu            help="Do not compile Full System mode")
1713855Sbinkertn@umich.edu
1723855Sbinkertn@umich.edudef usage(exitcode=None):
1733855Sbinkertn@umich.edu    parser.print_help()
1743855Sbinkertn@umich.edu    if exitcode is not None:
1753855Sbinkertn@umich.edu        sys.exit(exitcode)
1763855Sbinkertn@umich.edu
1773855Sbinkertn@umich.edu(options, args) = parser.parse_args()
1783855Sbinkertn@umich.edu
1793855Sbinkertn@umich.eduif options.everything:
1803855Sbinkertn@umich.edu    options.all_bin = True
1813855Sbinkertn@umich.edu    options.prof = True
1823855Sbinkertn@umich.edu    options.all_isa = True
1833855Sbinkertn@umich.edu
1843855Sbinkertn@umich.eduif options.all_bin:
1853855Sbinkertn@umich.edu    options.debug = True
1863855Sbinkertn@umich.edu    options.opt = True
1873855Sbinkertn@umich.edu    options.fast = True
1883855Sbinkertn@umich.edu
1893855Sbinkertn@umich.edubinaries = []
1903855Sbinkertn@umich.eduif options.debug:
1913855Sbinkertn@umich.edu    binaries.append('m5.debug')
1923855Sbinkertn@umich.eduif options.opt:
1933855Sbinkertn@umich.edu    binaries.append('m5.opt')
1943855Sbinkertn@umich.eduif options.fast:
1953855Sbinkertn@umich.edu    binaries.append('m5.fast')
1963855Sbinkertn@umich.eduif options.prof:
1973855Sbinkertn@umich.edu    binaries.append('m5.prof')
1983855Sbinkertn@umich.edu
1993855Sbinkertn@umich.eduif not binaries:
2003855Sbinkertn@umich.edu    binaries.append('m5.debug')
2013855Sbinkertn@umich.edu
2023855Sbinkertn@umich.eduif options.all_isa:
2033855Sbinkertn@umich.edu    options.alpha = True
2043855Sbinkertn@umich.edu    options.mips = True
2053855Sbinkertn@umich.edu    options.sparc = True
2063855Sbinkertn@umich.edu
2073855Sbinkertn@umich.eduisas = []
2083855Sbinkertn@umich.eduif options.alpha:
2093855Sbinkertn@umich.edu    isas.append('alpha')
2103855Sbinkertn@umich.eduif options.mips:
2113855Sbinkertn@umich.edu    isas.append('mips')
2123855Sbinkertn@umich.eduif options.sparc:
2133855Sbinkertn@umich.edu    isas.append('sparc')
2143855Sbinkertn@umich.edu
2153855Sbinkertn@umich.eduif not isas:
2163855Sbinkertn@umich.edu    isas.append('alpha')
2173855Sbinkertn@umich.edu
2183855Sbinkertn@umich.edumodes = []
2193855Sbinkertn@umich.eduif options.syscall:
2203855Sbinkertn@umich.edu    modes.append('syscall')
2213855Sbinkertn@umich.eduif options.fullsys:
2223855Sbinkertn@umich.edu    modes.append('fullsys')
2233855Sbinkertn@umich.edu
2243855Sbinkertn@umich.eduif not modes:
2253855Sbinkertn@umich.edu    sys.exit("must specify at least one mode")
2263855Sbinkertn@umich.edu
2273855Sbinkertn@umich.edu#
2283855Sbinkertn@umich.edu# Convert options into SCons command line arguments
2293855Sbinkertn@umich.edu#
2303855Sbinkertn@umich.edu
2313855Sbinkertn@umich.edu# valid combinations of ISA and emulation mode
2323855Sbinkertn@umich.eduvalid = { ('alpha', 'syscall') : 'ALPHA_SE',
2333855Sbinkertn@umich.edu          ('alpha', 'fullsys') : 'ALPHA_FS',
2343855Sbinkertn@umich.edu          ('mips',  'syscall') : 'MIPS_SE',
2353855Sbinkertn@umich.edu          ('sparc', 'syscall') : 'SPARC_SE' }
2363855Sbinkertn@umich.edu
2373855Sbinkertn@umich.edu# experimental combinations of ISA and emulation mode
2383855Sbinkertn@umich.eduexperiment = { ('mips', 'fullsys') : 'MIPS_FS',
2393855Sbinkertn@umich.edu               ('sparc', 'fullsys') : 'SPARC_FS' }
2403855Sbinkertn@umich.edu
2413855Sbinkertn@umich.eduif options.experimental:
2423855Sbinkertn@umich.edu    valid.update(experiment)
2433855Sbinkertn@umich.edu
2443855Sbinkertn@umich.edubuilds = []
2453855Sbinkertn@umich.edufor isa in isas:
2463855Sbinkertn@umich.edu    for mode in modes:
2473855Sbinkertn@umich.edu        try:
2483855Sbinkertn@umich.edu            build = valid[(isa, mode)]
2493855Sbinkertn@umich.edu            builds.append(build)
2503855Sbinkertn@umich.edu        except KeyError:
2513855Sbinkertn@umich.edu            pass
2523855Sbinkertn@umich.edu
2533855Sbinkertn@umich.eduif not builds:
2543855Sbinkertn@umich.edu    sys.exit("must specify at least one valid combination of ISA and mode")
2553855Sbinkertn@umich.edu
2563855Sbinkertn@umich.eduif not args:
2573855Sbinkertn@umich.edu    usage(2)
2583855Sbinkertn@umich.edu
2593855Sbinkertn@umich.eduversion = args[0]
2603855Sbinkertn@umich.edudel args[0]
2613855Sbinkertn@umich.edu
2623855Sbinkertn@umich.edufor bin in binaries:
2633855Sbinkertn@umich.edu    for build in builds:
2643855Sbinkertn@umich.edu        args.append('%s/%s' % (build, bin))
2653855Sbinkertn@umich.edu
2663855Sbinkertn@umich.edu#
2673855Sbinkertn@umich.edu# set up compile
2683855Sbinkertn@umich.edu#
2693855Sbinkertn@umich.edubuild_base = joinpath(homedir, 'build')
2703855Sbinkertn@umich.edum5_base = joinpath(homedir, 'm5')
2713855Sbinkertn@umich.edu
2723855Sbinkertn@umich.eduif not isdir(build_base):
2733855Sbinkertn@umich.edu    sys.exit('build directory %s not found' % build_base)
2743855Sbinkertn@umich.edu
2753855Sbinkertn@umich.eduif not isdir(m5_base):
2763855Sbinkertn@umich.edu    sys.exit('m5 base directory %s not found' % m5_base)
2773855Sbinkertn@umich.edu
2783855Sbinkertn@umich.edum5_dir = joinpath(m5_base, version)
2793855Sbinkertn@umich.eduif not isdir(m5_dir):
2803855Sbinkertn@umich.edu    sys.exit('source directory %s not found' % m5_dir)
2813855Sbinkertn@umich.edu
2823855Sbinkertn@umich.edu# support M5 1.x
2833855Sbinkertn@umich.eduoldstyle = isfile(joinpath(m5_dir, 'SConscript'))
2843855Sbinkertn@umich.eduif oldstyle:
2853855Sbinkertn@umich.edu    ext_dir = joinpath(m5_base, 'ext')
2863855Sbinkertn@umich.edu    test_dir = joinpath(m5_base, 'test.' + version)
2873855Sbinkertn@umich.edu
2883855Sbinkertn@umich.edu    if not isdir(ext_dir):
2893855Sbinkertn@umich.edu        sys.exit('ext directory not found at %s' % ext_dir)
2903855Sbinkertn@umich.edu
2913855Sbinkertn@umich.edu    if not isdir(test_dir):
2923855Sbinkertn@umich.edu        sys.exit('test directory not found at %s' % test_dir)
2933855Sbinkertn@umich.edu
2943855Sbinkertn@umich.edubuild_dir = joinpath(build_base, version)
2953855Sbinkertn@umich.eduif not isdir(build_dir):
2963855Sbinkertn@umich.edu    os.mkdir(build_dir)
2973855Sbinkertn@umich.edu    # need some symlinks for m5 1.x
2983855Sbinkertn@umich.edu    if oldstyle:
2993855Sbinkertn@umich.edu        os.symlink(m5_dir, joinpath(build_dir, 'm5'))
3003855Sbinkertn@umich.edu        os.symlink(ext_dir, joinpath(build_dir, 'ext'))
3013855Sbinkertn@umich.edu        os.symlink(test_dir, joinpath(build_dir, 'test'))
3023855Sbinkertn@umich.edu        os.symlink(joinpath(m5_dir, 'build', 'SConstruct'),
3033855Sbinkertn@umich.edu                   joinpath(build_dir, 'SConstruct'))
3043855Sbinkertn@umich.edu        os.symlink(joinpath(m5_dir, 'build', 'default_options'),
3053855Sbinkertn@umich.edu                   joinpath(build_dir, 'default_options'))
3063855Sbinkertn@umich.edu
3073855Sbinkertn@umich.edusys.argv = [ progname ]
3083855Sbinkertn@umich.eduif oldstyle:
3093855Sbinkertn@umich.edu    os.chdir(build_dir)
3103855Sbinkertn@umich.edu    sys.argv.extend(args)
3113855Sbinkertn@umich.eduelse:
3123855Sbinkertn@umich.edu    os.chdir(m5_dir)
3133855Sbinkertn@umich.edu    for arg in args:
3143855Sbinkertn@umich.edu        if not arg.startswith('-') and '=' not in arg:
3153855Sbinkertn@umich.edu            arg = joinpath(build_dir, 'build', arg)
3163855Sbinkertn@umich.edu        sys.argv.append(arg)
3173855Sbinkertn@umich.edu
3183855Sbinkertn@umich.eduif options.no_compile or options.verbose:
3193855Sbinkertn@umich.edu    for arg in sys.argv[1:]:
3203855Sbinkertn@umich.edu        print arg
3213855Sbinkertn@umich.edu
3223855Sbinkertn@umich.eduif not options.no_compile:
3233855Sbinkertn@umich.edu    do_compile()
324