compile revision 11320:42ecb523c64a
19020Sgblack@eecs.umich.edu#!/usr/bin/env python 29020Sgblack@eecs.umich.edu# Copyright (c) 2006 The Regents of The University of Michigan 39020Sgblack@eecs.umich.edu# All rights reserved. 49020Sgblack@eecs.umich.edu# 59020Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 69020Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 79020Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 89020Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 99020Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 109020Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 119020Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 129020Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 139020Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 149020Sgblack@eecs.umich.edu# this software without specific prior written permission. 159020Sgblack@eecs.umich.edu# 169020Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179020Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189020Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199020Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209020Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219020Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229020Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239020Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249020Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259020Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269020Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279020Sgblack@eecs.umich.edu# 289020Sgblack@eecs.umich.edu# Authors: Nathan Binkert 299020Sgblack@eecs.umich.edu 309020Sgblack@eecs.umich.eduimport os, re, sys 319020Sgblack@eecs.umich.edufrom os.path import isdir, isfile, join as joinpath 329020Sgblack@eecs.umich.edu 339020Sgblack@eecs.umich.eduhomedir = os.environ['HOME'] 349024Sgblack@eecs.umich.edu 359023Sgblack@eecs.umich.edudef do_compile(): 369022Sgblack@eecs.umich.edu # 379024Sgblack@eecs.umich.edu # Find SCons 389020Sgblack@eecs.umich.edu # 399020Sgblack@eecs.umich.edu search_dirs = [ joinpath(homedir, 'local/lib'), '/opt/local/lib', 409020Sgblack@eecs.umich.edu '/usr/local/lib', '/usr/lib' ] 419020Sgblack@eecs.umich.edu 4211165SRekai.GonzalezAlberquilla@arm.com if os.environ.has_key("SCONS_LIB_DIR"): 439022Sgblack@eecs.umich.edu search_dirs.append(os.environ["SCONS_LIB_DIR"]) 449022Sgblack@eecs.umich.edu 459022Sgblack@eecs.umich.edu local = re.compile(r'^scons-local-([0-9]*)\.([0-9]*)\.([0-9]*)$') 469023Sgblack@eecs.umich.edu standard = re.compile(r'^scons-([0-9]*)\.([0-9]*)\.([0-9]*)$') 479023Sgblack@eecs.umich.edu 489023Sgblack@eecs.umich.edu scons_dirs = [] 4913583Sgabeblack@google.com for dir in search_dirs: 509023Sgblack@eecs.umich.edu if not isdir(dir): 519023Sgblack@eecs.umich.edu continue 5211165SRekai.GonzalezAlberquilla@arm.com 539023Sgblack@eecs.umich.edu entries = os.listdir(dir) 549023Sgblack@eecs.umich.edu for entry in entries: 559023Sgblack@eecs.umich.edu if not entry.startswith('scons'): 569023Sgblack@eecs.umich.edu continue 579023Sgblack@eecs.umich.edu 589023Sgblack@eecs.umich.edu version = (0,0,0) 599023Sgblack@eecs.umich.edu path = joinpath(dir, entry) 609023Sgblack@eecs.umich.edu 619023Sgblack@eecs.umich.edu match = local.search(entry) 629023Sgblack@eecs.umich.edu if not match: 639023Sgblack@eecs.umich.edu match = standard.search(entry) 649023Sgblack@eecs.umich.edu 659023Sgblack@eecs.umich.edu if match: 669023Sgblack@eecs.umich.edu version = match.group(1), match.group(2), match.group(3) 679023Sgblack@eecs.umich.edu 689023Sgblack@eecs.umich.edu scons_dirs.append((version, path)) 699023Sgblack@eecs.umich.edu 709023Sgblack@eecs.umich.edu scons_dirs.sort() 719023Sgblack@eecs.umich.edu scons_dirs.reverse() 729023Sgblack@eecs.umich.edu 739023Sgblack@eecs.umich.edu if not scons_dirs: 749023Sgblack@eecs.umich.edu print >>sys.stderr, \ 759375Sgblack@eecs.umich.edu "could not find scons in the following dirs: %s" % search_dirs 769023Sgblack@eecs.umich.edu sys.exit(1) 779023Sgblack@eecs.umich.edu 789023Sgblack@eecs.umich.edu sys.path = [ scons_dirs[0][1] ] + sys.path 799023Sgblack@eecs.umich.edu 809023Sgblack@eecs.umich.edu # invoke SCons 819023Sgblack@eecs.umich.edu import SCons.Script 829023Sgblack@eecs.umich.edu SCons.Script.main() 839023Sgblack@eecs.umich.edu 849023Sgblack@eecs.umich.edu# 859023Sgblack@eecs.umich.edu# do argument parsing 869023Sgblack@eecs.umich.edu# 879023Sgblack@eecs.umich.eduprogname = sys.argv[0] 889023Sgblack@eecs.umich.edu 899023Sgblack@eecs.umich.eduimport optparse 909023Sgblack@eecs.umich.edu 919023Sgblack@eecs.umich.eduusage = '''%prog [compile options] <version> [SCons options] 929023Sgblack@eecs.umich.edu 939023Sgblack@eecs.umich.edu%prog assumes that the user has a directory called ~/m5/<version> where 949023Sgblack@eecs.umich.eduthe source tree resides, and a directory called ~/build, where %prog 959375Sgblack@eecs.umich.eduwill create ~/build/<version> if it does not exist and build the resulting 9613583Sgabeblack@google.comsimulators there. 979375Sgblack@eecs.umich.edu 989375Sgblack@eecs.umich.eduIf ~/build is set up in such a way that it points to a local disk on 999375Sgblack@eecs.umich.edueach host, compiles will be very efficient. For example: 1009375Sgblack@eecs.umich.edu~/build -> /z/<username>/.build (Assuming that /z is a local disk and 1019478Snilay@cs.wisc.edunot NFS mounted, whereas your home directory is NFS mounted). 1029478Snilay@cs.wisc.edu''' 1039023Sgblack@eecs.umich.eduversion = '%prog 0.1' 1049022Sgblack@eecs.umich.eduparser = optparse.OptionParser(usage=usage, version=version, 1059024Sgblack@eecs.umich.edu formatter=optparse.TitledHelpFormatter()) 1069022Sgblack@eecs.umich.eduparser.disable_interspersed_args() 1079022Sgblack@eecs.umich.edu 1089022Sgblack@eecs.umich.edu# current option group 1099022Sgblack@eecs.umich.edugroup = None 1109022Sgblack@eecs.umich.edu 1119022Sgblack@eecs.umich.edudef set_group(*args, **kwargs): 1129022Sgblack@eecs.umich.edu '''set the current option group''' 1139022Sgblack@eecs.umich.edu global group 1149022Sgblack@eecs.umich.edu if not args and not kwargs: 1159022Sgblack@eecs.umich.edu group = None 1169022Sgblack@eecs.umich.edu else: 1179022Sgblack@eecs.umich.edu group = parser.add_option_group(*args, **kwargs) 1189023Sgblack@eecs.umich.edu 1199023Sgblack@eecs.umich.edudef add_option(*args, **kwargs): 1209023Sgblack@eecs.umich.edu if group: 1219023Sgblack@eecs.umich.edu return group.add_option(*args, **kwargs) 1229023Sgblack@eecs.umich.edu else: 1239023Sgblack@eecs.umich.edu return parser.add_option(*args, **kwargs) 1249023Sgblack@eecs.umich.edu 1259023Sgblack@eecs.umich.edudef bool_option(name, default, help): 1269023Sgblack@eecs.umich.edu '''add a boolean option called --name and --no-name. 1279022Sgblack@eecs.umich.edu Display help depending on which is the default''' 1289020Sgblack@eecs.umich.edu 1299020Sgblack@eecs.umich.edu tname = '--%s' % name 1309020Sgblack@eecs.umich.edu fname = '--no-%s' % name 1319020Sgblack@eecs.umich.edu dest = name.replace('-', '_') 132 if default: 133 thelp = optparse.SUPPRESS_HELP 134 fhelp = help 135 else: 136 thelp = help 137 fhelp = optparse.SUPPRESS_HELP 138 139 add_option(tname, action="store_true", default=default, help=thelp) 140 add_option(fname, action="store_false", dest=dest, help=fhelp) 141 142add_option('-n', '--no-compile', default=False, action='store_true', 143 help="don't actually compile, just echo SCons command line") 144add_option('--everything', default=False, action='store_true', 145 help="compile everything that can be compiled") 146add_option('-E', "--experimental", action='store_true', default=False, 147 help="enable experimental builds") 148add_option('-v', "--verbose", default=False, action='store_true', 149 help="be verbose") 150 151set_group("Output binary types") 152bool_option("debug", default=False, help="compile debug binaries") 153bool_option("opt", default=False, help="compile opt binaries") 154bool_option("fast", default=False, help="compile fast binaries") 155bool_option("prof", default=False, help="compile profile binaries") 156add_option('-a', "--all-bin", default=False, action='store_true', 157 help="compile debug, opt, and fast binaries") 158 159set_group("ISA options") 160bool_option("alpha", default=False, help="compile Alpha") 161bool_option("mips", default=False, help="compile MIPS") 162bool_option("sparc", default=False, help="compile SPARC") 163add_option('-i', "--all-isa", default=False, action='store_true', 164 help="compile all ISAs") 165 166set_group("Emulation options") 167bool_option("syscall", default=True, 168 help="Do not compile System Call Emulation mode") 169bool_option("fullsys", default=True, 170 help="Do not compile Full System mode") 171 172def usage(exitcode=None): 173 parser.print_help() 174 if exitcode is not None: 175 sys.exit(exitcode) 176 177(options, args) = parser.parse_args() 178 179if options.everything: 180 options.all_bin = True 181 options.prof = True 182 options.all_isa = True 183 184if options.all_bin: 185 options.debug = True 186 options.opt = True 187 options.fast = True 188 189binaries = [] 190if options.debug: 191 binaries.append('m5.debug') 192if options.opt: 193 binaries.append('m5.opt') 194if options.fast: 195 binaries.append('m5.fast') 196if options.prof: 197 binaries.append('m5.prof') 198 199if not binaries: 200 binaries.append('m5.debug') 201 202if options.all_isa: 203 options.alpha = True 204 options.mips = True 205 options.sparc = True 206 207isas = [] 208if options.alpha: 209 isas.append('alpha') 210if options.mips: 211 isas.append('mips') 212if options.sparc: 213 isas.append('sparc') 214 215if not isas: 216 isas.append('alpha') 217 218modes = [] 219if options.syscall: 220 modes.append('syscall') 221if options.fullsys: 222 modes.append('fullsys') 223 224if not modes: 225 sys.exit("must specify at least one mode") 226 227# 228# Convert options into SCons command line arguments 229# 230 231# valid combinations of ISA and emulation mode 232valid = { ('alpha', 'syscall') : 'ALPHA_SE', 233 ('alpha', 'fullsys') : 'ALPHA_FS', 234 ('mips', 'syscall') : 'MIPS_SE', 235 ('sparc', 'syscall') : 'SPARC_SE' } 236 237# experimental combinations of ISA and emulation mode 238experiment = { ('mips', 'fullsys') : 'MIPS_FS', 239 ('sparc', 'fullsys') : 'SPARC_FS' } 240 241if options.experimental: 242 valid.update(experiment) 243 244builds = [] 245for isa in isas: 246 for mode in modes: 247 try: 248 build = valid[(isa, mode)] 249 builds.append(build) 250 except KeyError: 251 pass 252 253if not builds: 254 sys.exit("must specify at least one valid combination of ISA and mode") 255 256if not args: 257 usage(2) 258 259version = args[0] 260del args[0] 261 262for bin in binaries: 263 for build in builds: 264 args.append('%s/%s' % (build, bin)) 265 266# 267# set up compile 268# 269build_base = joinpath(homedir, 'build') 270m5_base = joinpath(homedir, 'm5') 271 272if not isdir(build_base): 273 sys.exit('build directory %s not found' % build_base) 274 275if not isdir(m5_base): 276 sys.exit('m5 base directory %s not found' % m5_base) 277 278m5_dir = joinpath(m5_base, version) 279if not isdir(m5_dir): 280 sys.exit('source directory %s not found' % m5_dir) 281 282# support M5 1.x 283oldstyle = isfile(joinpath(m5_dir, 'SConscript')) 284if oldstyle: 285 ext_dir = joinpath(m5_base, 'ext') 286 test_dir = joinpath(m5_base, 'test.' + version) 287 288 if not isdir(ext_dir): 289 sys.exit('ext directory not found at %s' % ext_dir) 290 291 if not isdir(test_dir): 292 sys.exit('test directory not found at %s' % test_dir) 293 294build_dir = joinpath(build_base, version) 295if not isdir(build_dir): 296 os.mkdir(build_dir) 297 # need some symlinks for m5 1.x 298 if oldstyle: 299 os.symlink(m5_dir, joinpath(build_dir, 'm5')) 300 os.symlink(ext_dir, joinpath(build_dir, 'ext')) 301 os.symlink(test_dir, joinpath(build_dir, 'test')) 302 os.symlink(joinpath(m5_dir, 'build', 'SConstruct'), 303 joinpath(build_dir, 'SConstruct')) 304 os.symlink(joinpath(m5_dir, 'build', 'default_options'), 305 joinpath(build_dir, 'default_options')) 306 307sys.argv = [ progname ] 308if oldstyle: 309 os.chdir(build_dir) 310 sys.argv.extend(args) 311else: 312 os.chdir(m5_dir) 313 for arg in args: 314 if not arg.startswith('-') and '=' not in arg: 315 arg = joinpath(build_dir, 'build', arg) 316 sys.argv.append(arg) 317 318if options.no_compile or options.verbose: 319 for arg in sys.argv[1:]: 320 print arg 321 322if not options.no_compile: 323 do_compile() 324