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("mips", default
=False, help="compile MIPS")
159 bool_option("sparc", default
=False, help="compile SPARC")
160 add_option('-i', "--all-isa", default
=False, action
='store_true',
161 help="compile all ISAs")
163 set_group("Emulation options")
164 bool_option("syscall", default
=True,
165 help="Do not compile System Call Emulation mode")
166 bool_option("fullsys", default
=True,
167 help="Do not compile Full System mode")
169 def usage(exitcode
=None):
171 if exitcode
is not None:
174 (options
, args
) = parser
.parse_args()
176 if options
.everything
:
177 options
.all_bin
= True
179 options
.all_isa
= True
188 binaries
.append('m5.debug')
190 binaries
.append('m5.opt')
192 binaries
.append('m5.fast')
194 binaries
.append('m5.prof')
197 binaries
.append('m5.debug')
211 modes
.append('syscall')
213 modes
.append('fullsys')
216 sys
.exit("must specify at least one mode")
219 # Convert options into SCons command line arguments
222 # valid combinations of ISA and emulation mode
224 ('mips', 'syscall') : 'MIPS_SE',
225 ('sparc', 'syscall') : 'SPARC_SE' }
227 # experimental combinations of ISA and emulation mode
228 experiment
= { ('mips', 'fullsys') : 'MIPS_FS',
229 ('sparc', 'fullsys') : 'SPARC_FS' }
231 if options
.experimental
:
232 valid
.update(experiment
)
238 build
= valid
[(isa
, mode
)]
244 sys
.exit("must specify at least one valid combination of ISA and mode")
254 args
.append('%s/%s' % (build
, bin
))
259 build_base
= joinpath(homedir
, 'build')
260 m5_base
= joinpath(homedir
, 'm5')
262 if not isdir(build_base
):
263 sys
.exit('build directory %s not found' % build_base
)
265 if not isdir(m5_base
):
266 sys
.exit('m5 base directory %s not found' % m5_base
)
268 m5_dir
= joinpath(m5_base
, version
)
269 if not isdir(m5_dir
):
270 sys
.exit('source directory %s not found' % m5_dir
)
273 oldstyle
= isfile(joinpath(m5_dir
, 'SConscript'))
275 ext_dir
= joinpath(m5_base
, 'ext')
276 test_dir
= joinpath(m5_base
, 'test.' + version
)
278 if not isdir(ext_dir
):
279 sys
.exit('ext directory not found at %s' % ext_dir
)
281 if not isdir(test_dir
):
282 sys
.exit('test directory not found at %s' % test_dir
)
284 build_dir
= joinpath(build_base
, version
)
285 if not isdir(build_dir
):
287 # need some symlinks for m5 1.x
289 os
.symlink(m5_dir
, joinpath(build_dir
, 'm5'))
290 os
.symlink(ext_dir
, joinpath(build_dir
, 'ext'))
291 os
.symlink(test_dir
, joinpath(build_dir
, 'test'))
292 os
.symlink(joinpath(m5_dir
, 'build', 'SConstruct'),
293 joinpath(build_dir
, 'SConstruct'))
294 os
.symlink(joinpath(m5_dir
, 'build', 'default_options'),
295 joinpath(build_dir
, 'default_options'))
297 sys
.argv
= [ progname
]
300 sys
.argv
.extend(args
)
304 if not arg
.startswith('-') and '=' not in arg
:
305 arg
= joinpath(build_dir
, 'build', arg
)
308 if options
.no_compile
or options
.verbose
:
309 for arg
in sys
.argv
[1:]:
312 if not options
.no_compile
: