1 #!/usr/bin/env python2.7
2 # Copyright (c) 2006 The Regents of The University of Michigan
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met: redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer;
9 # redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution;
12 # neither the name of the copyright holders nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 from os
.path
import isdir
, isfile
, join
as joinpath
31 homedir
= os
.environ
['HOME']
37 search_dirs
= [ joinpath(homedir
, 'local/lib'), '/opt/local/lib',
38 '/usr/local/lib', '/usr/lib' ]
40 if os
.environ
.has_key("SCONS_LIB_DIR"):
41 search_dirs
.append(os
.environ
["SCONS_LIB_DIR"])
43 local
= re
.compile(r
'^scons-local-([0-9]*)\.([0-9]*)\.([0-9]*)$')
44 standard
= re
.compile(r
'^scons-([0-9]*)\.([0-9]*)\.([0-9]*)$')
47 for dir in search_dirs
:
51 entries
= os
.listdir(dir)
53 if not entry
.startswith('scons'):
57 path
= joinpath(dir, entry
)
59 match
= local
.search(entry
)
61 match
= standard
.search(entry
)
64 version
= match
.group(1), match
.group(2), match
.group(3)
66 scons_dirs
.append((version
, path
))
73 "could not find scons in the following dirs: %s" % search_dirs
76 sys
.path
= [ scons_dirs
[0][1] ] + sys
.path
85 progname
= sys
.argv
[0]
89 usage
= '''%prog [compile options] <version> [SCons options]
91 %prog assumes that the user has a directory called ~/m5/<version> where
92 the source tree resides, and a directory called ~/build, where %prog
93 will create ~/build/<version> if it does not exist and build the resulting
96 If ~/build is set up in such a way that it points to a local disk on
97 each host, compiles will be very efficient. For example:
98 ~/build -> /z/<username>/.build (Assuming that /z is a local disk and
99 not NFS mounted, whereas your home directory is NFS mounted).
101 version
= '%prog 0.1'
102 parser
= optparse
.OptionParser(usage
=usage
, version
=version
,
103 formatter
=optparse
.TitledHelpFormatter())
104 parser
.disable_interspersed_args()
106 # current option group
109 def set_group(*args
, **kwargs
):
110 '''set the current option group'''
112 if not args
and not kwargs
:
115 group
= parser
.add_option_group(*args
, **kwargs
)
117 def add_option(*args
, **kwargs
):
119 return group
.add_option(*args
, **kwargs
)
121 return parser
.add_option(*args
, **kwargs
)
123 def bool_option(name
, default
, help):
124 '''add a boolean option called --name and --no-name.
125 Display help depending on which is the default'''
127 tname
= '--%s' % name
128 fname
= '--no-%s' % name
129 dest
= name
.replace('-', '_')
131 thelp
= optparse
.SUPPRESS_HELP
135 fhelp
= optparse
.SUPPRESS_HELP
137 add_option(tname
, action
="store_true", default
=default
, help=thelp
)
138 add_option(fname
, action
="store_false", dest
=dest
, help=fhelp
)
140 add_option('-n', '--no-compile', default
=False, action
='store_true',
141 help="don't actually compile, just echo SCons command line")
142 add_option('--everything', default
=False, action
='store_true',
143 help="compile everything that can be compiled")
144 add_option('-E', "--experimental", action
='store_true', default
=False,
145 help="enable experimental builds")
146 add_option('-v', "--verbose", default
=False, action
='store_true',
149 set_group("Output binary types")
150 bool_option("debug", default
=False, help="compile debug binaries")
151 bool_option("opt", default
=False, help="compile opt binaries")
152 bool_option("fast", default
=False, help="compile fast binaries")
153 bool_option("prof", default
=False, help="compile profile binaries")
154 add_option('-a', "--all-bin", default
=False, action
='store_true',
155 help="compile debug, opt, and fast binaries")
157 set_group("ISA options")
158 bool_option("alpha", default
=False, help="compile Alpha")
159 bool_option("mips", default
=False, help="compile MIPS")
160 bool_option("sparc", default
=False, help="compile SPARC")
161 add_option('-i', "--all-isa", default
=False, action
='store_true',
162 help="compile all ISAs")
164 set_group("Emulation options")
165 bool_option("syscall", default
=True,
166 help="Do not compile System Call Emulation mode")
167 bool_option("fullsys", default
=True,
168 help="Do not compile Full System mode")
170 def usage(exitcode
=None):
172 if exitcode
is not None:
175 (options
, args
) = parser
.parse_args()
177 if options
.everything
:
178 options
.all_bin
= True
180 options
.all_isa
= True
189 binaries
.append('m5.debug')
191 binaries
.append('m5.opt')
193 binaries
.append('m5.fast')
195 binaries
.append('m5.prof')
198 binaries
.append('m5.debug')
218 modes
.append('syscall')
220 modes
.append('fullsys')
223 sys
.exit("must specify at least one mode")
226 # Convert options into SCons command line arguments
229 # valid combinations of ISA and emulation mode
230 valid
= { ('alpha', 'syscall') : 'ALPHA_SE',
231 ('alpha', 'fullsys') : 'ALPHA_FS',
232 ('mips', 'syscall') : 'MIPS_SE',
233 ('sparc', 'syscall') : 'SPARC_SE' }
235 # experimental combinations of ISA and emulation mode
236 experiment
= { ('mips', 'fullsys') : 'MIPS_FS',
237 ('sparc', 'fullsys') : 'SPARC_FS' }
239 if options
.experimental
:
240 valid
.update(experiment
)
246 build
= valid
[(isa
, mode
)]
252 sys
.exit("must specify at least one valid combination of ISA and mode")
262 args
.append('%s/%s' % (build
, bin
))
267 build_base
= joinpath(homedir
, 'build')
268 m5_base
= joinpath(homedir
, 'm5')
270 if not isdir(build_base
):
271 sys
.exit('build directory %s not found' % build_base
)
273 if not isdir(m5_base
):
274 sys
.exit('m5 base directory %s not found' % m5_base
)
276 m5_dir
= joinpath(m5_base
, version
)
277 if not isdir(m5_dir
):
278 sys
.exit('source directory %s not found' % m5_dir
)
281 oldstyle
= isfile(joinpath(m5_dir
, 'SConscript'))
283 ext_dir
= joinpath(m5_base
, 'ext')
284 test_dir
= joinpath(m5_base
, 'test.' + version
)
286 if not isdir(ext_dir
):
287 sys
.exit('ext directory not found at %s' % ext_dir
)
289 if not isdir(test_dir
):
290 sys
.exit('test directory not found at %s' % test_dir
)
292 build_dir
= joinpath(build_base
, version
)
293 if not isdir(build_dir
):
295 # need some symlinks for m5 1.x
297 os
.symlink(m5_dir
, joinpath(build_dir
, 'm5'))
298 os
.symlink(ext_dir
, joinpath(build_dir
, 'ext'))
299 os
.symlink(test_dir
, joinpath(build_dir
, 'test'))
300 os
.symlink(joinpath(m5_dir
, 'build', 'SConstruct'),
301 joinpath(build_dir
, 'SConstruct'))
302 os
.symlink(joinpath(m5_dir
, 'build', 'default_options'),
303 joinpath(build_dir
, 'default_options'))
305 sys
.argv
= [ progname
]
308 sys
.argv
.extend(args
)
312 if not arg
.startswith('-') and '=' not in arg
:
313 arg
= joinpath(build_dir
, 'build', arg
)
316 if options
.no_compile
or options
.verbose
:
317 for arg
in sys
.argv
[1:]:
320 if not options
.no_compile
: