compile revision 11320:42ecb523c64a
111308Santhony.gutierrez@amd.com#!/usr/bin/env python
211308Santhony.gutierrez@amd.com# Copyright (c) 2006 The Regents of The University of Michigan
311308Santhony.gutierrez@amd.com# All rights reserved.
411308Santhony.gutierrez@amd.com#
511308Santhony.gutierrez@amd.com# Redistribution and use in source and binary forms, with or without
611308Santhony.gutierrez@amd.com# modification, are permitted provided that the following conditions are
711308Santhony.gutierrez@amd.com# met: redistributions of source code must retain the above copyright
811308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer;
911308Santhony.gutierrez@amd.com# redistributions in binary form must reproduce the above copyright
1011308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer in the
1111308Santhony.gutierrez@amd.com# documentation and/or other materials provided with the distribution;
1211308Santhony.gutierrez@amd.com# neither the name of the copyright holders nor the names of its
1311308Santhony.gutierrez@amd.com# contributors may be used to endorse or promote products derived from
1411308Santhony.gutierrez@amd.com# this software without specific prior written permission.
1511308Santhony.gutierrez@amd.com#
1611308Santhony.gutierrez@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711308Santhony.gutierrez@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811308Santhony.gutierrez@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911308Santhony.gutierrez@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011308Santhony.gutierrez@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111308Santhony.gutierrez@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211308Santhony.gutierrez@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311308Santhony.gutierrez@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411308Santhony.gutierrez@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511308Santhony.gutierrez@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611308Santhony.gutierrez@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711308Santhony.gutierrez@amd.com#
2811308Santhony.gutierrez@amd.com# Authors: Nathan Binkert
2911308Santhony.gutierrez@amd.com
3011308Santhony.gutierrez@amd.comimport os, re, sys
3111308Santhony.gutierrez@amd.comfrom os.path import isdir, isfile, join as joinpath
3211308Santhony.gutierrez@amd.com
3311308Santhony.gutierrez@amd.comhomedir = os.environ['HOME']
3411308Santhony.gutierrez@amd.com
3511308Santhony.gutierrez@amd.comdef do_compile():
3611308Santhony.gutierrez@amd.com    #
3711308Santhony.gutierrez@amd.com    # Find SCons
3811308Santhony.gutierrez@amd.com    #
3911308Santhony.gutierrez@amd.com    search_dirs = [ joinpath(homedir, 'local/lib'), '/opt/local/lib',
4011308Santhony.gutierrez@amd.com                    '/usr/local/lib', '/usr/lib' ]
4111308Santhony.gutierrez@amd.com
4211308Santhony.gutierrez@amd.com    if os.environ.has_key("SCONS_LIB_DIR"):
4311670Sandreas.hansson@arm.com        search_dirs.append(os.environ["SCONS_LIB_DIR"])
4411670Sandreas.hansson@arm.com
4511308Santhony.gutierrez@amd.com    local = re.compile(r'^scons-local-([0-9]*)\.([0-9]*)\.([0-9]*)$')
4611308Santhony.gutierrez@amd.com    standard = re.compile(r'^scons-([0-9]*)\.([0-9]*)\.([0-9]*)$')
4711308Santhony.gutierrez@amd.com
4811308Santhony.gutierrez@amd.com    scons_dirs = []
4911308Santhony.gutierrez@amd.com    for dir in search_dirs:
5011308Santhony.gutierrez@amd.com        if not isdir(dir):
5111308Santhony.gutierrez@amd.com            continue
5211308Santhony.gutierrez@amd.com
5311308Santhony.gutierrez@amd.com        entries = os.listdir(dir)
5411308Santhony.gutierrez@amd.com        for entry in entries:
5511308Santhony.gutierrez@amd.com            if not entry.startswith('scons'):
5611308Santhony.gutierrez@amd.com                continue
5711308Santhony.gutierrez@amd.com
5811308Santhony.gutierrez@amd.com            version = (0,0,0)
5911308Santhony.gutierrez@amd.com            path = joinpath(dir, entry)
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.com            match = local.search(entry)
6211308Santhony.gutierrez@amd.com            if not match:
6311308Santhony.gutierrez@amd.com                match = standard.search(entry)
6411308Santhony.gutierrez@amd.com
6511308Santhony.gutierrez@amd.com            if match:
6611308Santhony.gutierrez@amd.com                version = match.group(1), match.group(2), match.group(3)
6711308Santhony.gutierrez@amd.com
6811308Santhony.gutierrez@amd.com            scons_dirs.append((version, path))
6911308Santhony.gutierrez@amd.com
7011308Santhony.gutierrez@amd.com    scons_dirs.sort()
7111308Santhony.gutierrez@amd.com    scons_dirs.reverse()
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com    if not scons_dirs:
7411308Santhony.gutierrez@amd.com        print >>sys.stderr, \
7511308Santhony.gutierrez@amd.com              "could not find scons in the following dirs: %s" % search_dirs
7611308Santhony.gutierrez@amd.com        sys.exit(1)
7711308Santhony.gutierrez@amd.com
7811308Santhony.gutierrez@amd.com    sys.path = [ scons_dirs[0][1] ] + sys.path
7911308Santhony.gutierrez@amd.com
8011308Santhony.gutierrez@amd.com    # invoke SCons
8111308Santhony.gutierrez@amd.com    import SCons.Script
8211308Santhony.gutierrez@amd.com    SCons.Script.main()
8311308Santhony.gutierrez@amd.com
8411308Santhony.gutierrez@amd.com#
8511308Santhony.gutierrez@amd.com# do argument parsing
8611308Santhony.gutierrez@amd.com#
8711308Santhony.gutierrez@amd.comprogname = sys.argv[0]
8811308Santhony.gutierrez@amd.com
8911308Santhony.gutierrez@amd.comimport optparse
9011308Santhony.gutierrez@amd.com
9111308Santhony.gutierrez@amd.comusage = '''%prog [compile options] <version> [SCons options]
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.com%prog assumes that the user has a directory called ~/m5/<version> where
9411308Santhony.gutierrez@amd.comthe source tree resides, and a directory called ~/build, where %prog
9511308Santhony.gutierrez@amd.comwill create ~/build/<version> if it does not exist and build the resulting
9611308Santhony.gutierrez@amd.comsimulators there.
9711308Santhony.gutierrez@amd.com
9811308Santhony.gutierrez@amd.comIf ~/build is set up in such a way that it points to a local disk on
9911308Santhony.gutierrez@amd.comeach host, compiles will be very efficient.  For example:
10011308Santhony.gutierrez@amd.com~/build -> /z/<username>/.build  (Assuming that /z is a local disk and
10111308Santhony.gutierrez@amd.comnot NFS mounted, whereas your home directory is NFS mounted).
10211308Santhony.gutierrez@amd.com'''
10311308Santhony.gutierrez@amd.comversion = '%prog 0.1'
10411308Santhony.gutierrez@amd.comparser = optparse.OptionParser(usage=usage, version=version,
10511308Santhony.gutierrez@amd.com                               formatter=optparse.TitledHelpFormatter())
10611308Santhony.gutierrez@amd.comparser.disable_interspersed_args()
10711308Santhony.gutierrez@amd.com
10811308Santhony.gutierrez@amd.com# current option group
10911308Santhony.gutierrez@amd.comgroup = None
11011308Santhony.gutierrez@amd.com
11111308Santhony.gutierrez@amd.comdef set_group(*args, **kwargs):
11211308Santhony.gutierrez@amd.com    '''set the current option group'''
11311308Santhony.gutierrez@amd.com    global group
11411308Santhony.gutierrez@amd.com    if not args and not kwargs:
11511308Santhony.gutierrez@amd.com        group = None
11611308Santhony.gutierrez@amd.com    else:
11711308Santhony.gutierrez@amd.com        group = parser.add_option_group(*args, **kwargs)
11811308Santhony.gutierrez@amd.com
11911308Santhony.gutierrez@amd.comdef add_option(*args, **kwargs):
12011308Santhony.gutierrez@amd.com    if group:
12111308Santhony.gutierrez@amd.com        return group.add_option(*args, **kwargs)
12211308Santhony.gutierrez@amd.com    else:
12311308Santhony.gutierrez@amd.com        return parser.add_option(*args, **kwargs)
12411308Santhony.gutierrez@amd.com
12511308Santhony.gutierrez@amd.comdef bool_option(name, default, help):
12611308Santhony.gutierrez@amd.com    '''add a boolean option called --name and --no-name.
12711308Santhony.gutierrez@amd.com    Display help depending on which is the default'''
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.com    tname = '--%s' % name
13011308Santhony.gutierrez@amd.com    fname = '--no-%s' % name
13111308Santhony.gutierrez@amd.com    dest = name.replace('-', '_')
13211308Santhony.gutierrez@amd.com    if default:
13311308Santhony.gutierrez@amd.com        thelp = optparse.SUPPRESS_HELP
13411308Santhony.gutierrez@amd.com        fhelp = help
13511308Santhony.gutierrez@amd.com    else:
13611308Santhony.gutierrez@amd.com        thelp = help
13711308Santhony.gutierrez@amd.com        fhelp = optparse.SUPPRESS_HELP
13811308Santhony.gutierrez@amd.com
13911308Santhony.gutierrez@amd.com    add_option(tname, action="store_true", default=default, help=thelp)
14011308Santhony.gutierrez@amd.com    add_option(fname, action="store_false", dest=dest, help=fhelp)
14111308Santhony.gutierrez@amd.com
14211308Santhony.gutierrez@amd.comadd_option('-n', '--no-compile', default=False, action='store_true',
14311308Santhony.gutierrez@amd.com           help="don't actually compile, just echo SCons command line")
14411308Santhony.gutierrez@amd.comadd_option('--everything', default=False, action='store_true',
14511308Santhony.gutierrez@amd.com           help="compile everything that can be compiled")
14611308Santhony.gutierrez@amd.comadd_option('-E', "--experimental", action='store_true', default=False,
14711308Santhony.gutierrez@amd.com           help="enable experimental builds")
14811308Santhony.gutierrez@amd.comadd_option('-v', "--verbose", default=False, action='store_true',
14911308Santhony.gutierrez@amd.com           help="be verbose")
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.comset_group("Output binary types")
15211308Santhony.gutierrez@amd.combool_option("debug", default=False, help="compile debug binaries")
15311308Santhony.gutierrez@amd.combool_option("opt", default=False, help="compile opt binaries")
15411308Santhony.gutierrez@amd.combool_option("fast", default=False, help="compile fast binaries")
15511308Santhony.gutierrez@amd.combool_option("prof", default=False, help="compile profile binaries")
15611308Santhony.gutierrez@amd.comadd_option('-a', "--all-bin", default=False, action='store_true',
15711308Santhony.gutierrez@amd.com           help="compile debug, opt, and fast binaries")
15811308Santhony.gutierrez@amd.com
15911308Santhony.gutierrez@amd.comset_group("ISA options")
16011308Santhony.gutierrez@amd.combool_option("alpha", default=False, help="compile Alpha")
16111308Santhony.gutierrez@amd.combool_option("mips", default=False, help="compile MIPS")
16211308Santhony.gutierrez@amd.combool_option("sparc", default=False, help="compile SPARC")
16311308Santhony.gutierrez@amd.comadd_option('-i', "--all-isa", default=False, action='store_true',
16411308Santhony.gutierrez@amd.com           help="compile all ISAs")
16511308Santhony.gutierrez@amd.com
16611308Santhony.gutierrez@amd.comset_group("Emulation options")
16711308Santhony.gutierrez@amd.combool_option("syscall", default=True,
16811308Santhony.gutierrez@amd.com            help="Do not compile System Call Emulation mode")
16911308Santhony.gutierrez@amd.combool_option("fullsys", default=True,
17011308Santhony.gutierrez@amd.com            help="Do not compile Full System mode")
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.comdef usage(exitcode=None):
17311308Santhony.gutierrez@amd.com    parser.print_help()
17411308Santhony.gutierrez@amd.com    if exitcode is not None:
17511308Santhony.gutierrez@amd.com        sys.exit(exitcode)
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.com(options, args) = parser.parse_args()
17811308Santhony.gutierrez@amd.com
17911308Santhony.gutierrez@amd.comif options.everything:
18011308Santhony.gutierrez@amd.com    options.all_bin = True
18111308Santhony.gutierrez@amd.com    options.prof = True
18211308Santhony.gutierrez@amd.com    options.all_isa = True
18311308Santhony.gutierrez@amd.com
18411308Santhony.gutierrez@amd.comif options.all_bin:
18511308Santhony.gutierrez@amd.com    options.debug = True
18611308Santhony.gutierrez@amd.com    options.opt = True
18711308Santhony.gutierrez@amd.com    options.fast = True
18811308Santhony.gutierrez@amd.com
18911308Santhony.gutierrez@amd.combinaries = []
19011308Santhony.gutierrez@amd.comif options.debug:
19111308Santhony.gutierrez@amd.com    binaries.append('m5.debug')
19211308Santhony.gutierrez@amd.comif options.opt:
19311308Santhony.gutierrez@amd.com    binaries.append('m5.opt')
19411308Santhony.gutierrez@amd.comif options.fast:
19511308Santhony.gutierrez@amd.com    binaries.append('m5.fast')
19611308Santhony.gutierrez@amd.comif options.prof:
19711308Santhony.gutierrez@amd.com    binaries.append('m5.prof')
19811308Santhony.gutierrez@amd.com
19911308Santhony.gutierrez@amd.comif not binaries:
20011308Santhony.gutierrez@amd.com    binaries.append('m5.debug')
20111308Santhony.gutierrez@amd.com
20211308Santhony.gutierrez@amd.comif options.all_isa:
20311308Santhony.gutierrez@amd.com    options.alpha = True
20411308Santhony.gutierrez@amd.com    options.mips = True
20511308Santhony.gutierrez@amd.com    options.sparc = True
20611308Santhony.gutierrez@amd.com
20711308Santhony.gutierrez@amd.comisas = []
20811308Santhony.gutierrez@amd.comif options.alpha:
20911308Santhony.gutierrez@amd.com    isas.append('alpha')
21011308Santhony.gutierrez@amd.comif options.mips:
21111308Santhony.gutierrez@amd.com    isas.append('mips')
21211308Santhony.gutierrez@amd.comif options.sparc:
21311308Santhony.gutierrez@amd.com    isas.append('sparc')
21411308Santhony.gutierrez@amd.com
21511308Santhony.gutierrez@amd.comif not isas:
21611308Santhony.gutierrez@amd.com    isas.append('alpha')
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.commodes = []
21911308Santhony.gutierrez@amd.comif options.syscall:
22011308Santhony.gutierrez@amd.com    modes.append('syscall')
22111308Santhony.gutierrez@amd.comif options.fullsys:
22211308Santhony.gutierrez@amd.com    modes.append('fullsys')
22311308Santhony.gutierrez@amd.com
22411308Santhony.gutierrez@amd.comif not modes:
22511308Santhony.gutierrez@amd.com    sys.exit("must specify at least one mode")
22611308Santhony.gutierrez@amd.com
22711308Santhony.gutierrez@amd.com#
22811308Santhony.gutierrez@amd.com# Convert options into SCons command line arguments
22911308Santhony.gutierrez@amd.com#
23011308Santhony.gutierrez@amd.com
23111308Santhony.gutierrez@amd.com# valid combinations of ISA and emulation mode
23211308Santhony.gutierrez@amd.comvalid = { ('alpha', 'syscall') : 'ALPHA_SE',
23311308Santhony.gutierrez@amd.com          ('alpha', 'fullsys') : 'ALPHA_FS',
23411308Santhony.gutierrez@amd.com          ('mips',  'syscall') : 'MIPS_SE',
23511308Santhony.gutierrez@amd.com          ('sparc', 'syscall') : 'SPARC_SE' }
23611308Santhony.gutierrez@amd.com
23711308Santhony.gutierrez@amd.com# experimental combinations of ISA and emulation mode
23811308Santhony.gutierrez@amd.comexperiment = { ('mips', 'fullsys') : 'MIPS_FS',
23911308Santhony.gutierrez@amd.com               ('sparc', 'fullsys') : 'SPARC_FS' }
24011308Santhony.gutierrez@amd.com
24111308Santhony.gutierrez@amd.comif options.experimental:
24211308Santhony.gutierrez@amd.com    valid.update(experiment)
24311308Santhony.gutierrez@amd.com
24411308Santhony.gutierrez@amd.combuilds = []
24511308Santhony.gutierrez@amd.comfor isa in isas:
24611308Santhony.gutierrez@amd.com    for mode in modes:
24711308Santhony.gutierrez@amd.com        try:
24811308Santhony.gutierrez@amd.com            build = valid[(isa, mode)]
24911308Santhony.gutierrez@amd.com            builds.append(build)
25011308Santhony.gutierrez@amd.com        except KeyError:
25111308Santhony.gutierrez@amd.com            pass
25211308Santhony.gutierrez@amd.com
25311308Santhony.gutierrez@amd.comif not builds:
25411308Santhony.gutierrez@amd.com    sys.exit("must specify at least one valid combination of ISA and mode")
25511308Santhony.gutierrez@amd.com
25611308Santhony.gutierrez@amd.comif not args:
25711308Santhony.gutierrez@amd.com    usage(2)
25811308Santhony.gutierrez@amd.com
25911308Santhony.gutierrez@amd.comversion = args[0]
26011308Santhony.gutierrez@amd.comdel args[0]
26111308Santhony.gutierrez@amd.com
26211308Santhony.gutierrez@amd.comfor bin in binaries:
26311308Santhony.gutierrez@amd.com    for build in builds:
26411308Santhony.gutierrez@amd.com        args.append('%s/%s' % (build, bin))
26511308Santhony.gutierrez@amd.com
26611308Santhony.gutierrez@amd.com#
26711308Santhony.gutierrez@amd.com# set up compile
26811308Santhony.gutierrez@amd.com#
26911308Santhony.gutierrez@amd.combuild_base = joinpath(homedir, 'build')
27011308Santhony.gutierrez@amd.comm5_base = joinpath(homedir, 'm5')
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.comif not isdir(build_base):
27311308Santhony.gutierrez@amd.com    sys.exit('build directory %s not found' % build_base)
27411308Santhony.gutierrez@amd.com
27511308Santhony.gutierrez@amd.comif not isdir(m5_base):
27611308Santhony.gutierrez@amd.com    sys.exit('m5 base directory %s not found' % m5_base)
27711308Santhony.gutierrez@amd.com
27811308Santhony.gutierrez@amd.comm5_dir = joinpath(m5_base, version)
27911308Santhony.gutierrez@amd.comif not isdir(m5_dir):
28011308Santhony.gutierrez@amd.com    sys.exit('source directory %s not found' % m5_dir)
28111308Santhony.gutierrez@amd.com
28211308Santhony.gutierrez@amd.com# support M5 1.x
28311308Santhony.gutierrez@amd.comoldstyle = isfile(joinpath(m5_dir, 'SConscript'))
28411308Santhony.gutierrez@amd.comif oldstyle:
28511308Santhony.gutierrez@amd.com    ext_dir = joinpath(m5_base, 'ext')
28611308Santhony.gutierrez@amd.com    test_dir = joinpath(m5_base, 'test.' + version)
28711308Santhony.gutierrez@amd.com
28811308Santhony.gutierrez@amd.com    if not isdir(ext_dir):
28911308Santhony.gutierrez@amd.com        sys.exit('ext directory not found at %s' % ext_dir)
29011308Santhony.gutierrez@amd.com
29111308Santhony.gutierrez@amd.com    if not isdir(test_dir):
29211308Santhony.gutierrez@amd.com        sys.exit('test directory not found at %s' % test_dir)
29311308Santhony.gutierrez@amd.com
29411308Santhony.gutierrez@amd.combuild_dir = joinpath(build_base, version)
29511308Santhony.gutierrez@amd.comif not isdir(build_dir):
29611308Santhony.gutierrez@amd.com    os.mkdir(build_dir)
29711308Santhony.gutierrez@amd.com    # need some symlinks for m5 1.x
29811308Santhony.gutierrez@amd.com    if oldstyle:
29911308Santhony.gutierrez@amd.com        os.symlink(m5_dir, joinpath(build_dir, 'm5'))
30011308Santhony.gutierrez@amd.com        os.symlink(ext_dir, joinpath(build_dir, 'ext'))
30111308Santhony.gutierrez@amd.com        os.symlink(test_dir, joinpath(build_dir, 'test'))
30211308Santhony.gutierrez@amd.com        os.symlink(joinpath(m5_dir, 'build', 'SConstruct'),
30311308Santhony.gutierrez@amd.com                   joinpath(build_dir, 'SConstruct'))
30411308Santhony.gutierrez@amd.com        os.symlink(joinpath(m5_dir, 'build', 'default_options'),
30511308Santhony.gutierrez@amd.com                   joinpath(build_dir, 'default_options'))
30611308Santhony.gutierrez@amd.com
30711308Santhony.gutierrez@amd.comsys.argv = [ progname ]
30811308Santhony.gutierrez@amd.comif oldstyle:
30911308Santhony.gutierrez@amd.com    os.chdir(build_dir)
31011308Santhony.gutierrez@amd.com    sys.argv.extend(args)
31111308Santhony.gutierrez@amd.comelse:
31211308Santhony.gutierrez@amd.com    os.chdir(m5_dir)
31311308Santhony.gutierrez@amd.com    for arg in args:
31411308Santhony.gutierrez@amd.com        if not arg.startswith('-') and '=' not in arg:
31511308Santhony.gutierrez@amd.com            arg = joinpath(build_dir, 'build', arg)
31611308Santhony.gutierrez@amd.com        sys.argv.append(arg)
31711308Santhony.gutierrez@amd.com
31811308Santhony.gutierrez@amd.comif options.no_compile or options.verbose:
31911308Santhony.gutierrez@amd.com    for arg in sys.argv[1:]:
32011308Santhony.gutierrez@amd.com        print arg
32111308Santhony.gutierrez@amd.com
32211308Santhony.gutierrez@amd.comif not options.no_compile:
32311308Santhony.gutierrez@amd.com    do_compile()
32411308Santhony.gutierrez@amd.com