SConstruct (5749:7015e400bd1d) SConstruct (5863:f73e06bc8765)
1# -*- mode:python -*-
2
3# Copyright (c) 2004-2005 The Regents of The University of Michigan
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met: redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29# Authors: Steve Reinhardt
1# -*- mode:python -*-
2
3# Copyright (c) 2004-2005 The Regents of The University of Michigan
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are
8# met: redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29# Authors: Steve Reinhardt
30# Nathan Binkert
30
31###################################################
32#
33# SCons top-level build description (SConstruct) file.
34#
35# While in this directory ('m5'), just type 'scons' to build the default
36# configuration (see below), or type 'scons build/<CONFIG>/<binary>'
37# to build some other configuration (e.g., 'build/ALPHA_FS/m5.opt' for

--- 20 unchanged lines hidden (view full) ---

58#
59# You can use 'scons -H' to print scons options. If you're in this
60# 'm5' directory (or use -u or -C to tell scons where to find this
61# file), you can use 'scons -h' to print all the M5-specific build
62# options as well.
63#
64###################################################
65
31
32###################################################
33#
34# SCons top-level build description (SConstruct) file.
35#
36# While in this directory ('m5'), just type 'scons' to build the default
37# configuration (see below), or type 'scons build/<CONFIG>/<binary>'
38# to build some other configuration (e.g., 'build/ALPHA_FS/m5.opt' for

--- 20 unchanged lines hidden (view full) ---

59#
60# You can use 'scons -H' to print scons options. If you're in this
61# 'm5' directory (or use -u or -C to tell scons where to find this
62# file), you can use 'scons -h' to print all the M5-specific build
63# options as well.
64#
65###################################################
66
66import sys
67# Check for recent-enough Python and SCons versions.
68try:
69 # Really old versions of scons only take two options for the
70 # function, so check once without the revision and once with the
71 # revision, the first instance will fail for stuff other than
72 # 0.98, and the second will fail for 0.98.0
73 EnsureSConsVersion(0, 98)
74 EnsureSConsVersion(0, 98, 1)
75except SystemExit, e:
76 print """
77For more details, see:
78 http://m5sim.org/wiki/index.php/Compiling_M5
79"""
80 raise
81
82# We ensure the python version early because we have stuff that
83# requires python 2.4
84try:
85 EnsurePythonVersion(2, 4)
86except SystemExit, e:
87 print """
88You can use a non-default installation of the Python interpreter by
89either (1) rearranging your PATH so that scons finds the non-default
90'python' first or (2) explicitly invoking an alternative interpreter
91on the scons script.
92
93For more details, see:
94 http://m5sim.org/wiki/index.php/Using_a_non-default_Python_installation
95"""
96 raise
97
67import os
68import re
98import os
99import re
100import subprocess
101import sys
69
102
70from os.path import isdir, isfile, join as joinpath
103from os import mkdir, environ
104from os.path import abspath, basename, dirname, expanduser, normpath
105from os.path import exists, isdir, isfile
106from os.path import join as joinpath, split as splitpath
71
72import SCons
73
107
108import SCons
109
74# Check for recent-enough Python and SCons versions. If your system's
75# default installation of Python is not recent enough, you can use a
76# non-default installation of the Python interpreter by either (1)
77# rearranging your PATH so that scons finds the non-default 'python'
78# first or (2) explicitly invoking an alternative interpreter on the
79# scons script, e.g., "/usr/local/bin/python2.4 `which scons` [args]".
80EnsurePythonVersion(2,4)
110def read_command(cmd):
111 """run the command cmd, read the results and return them
112 this is sorta like `cmd` in shell"""
113 from subprocess import Popen, PIPE, STDOUT
114 subp = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, close_fds=True)
115 return subp.communicate()[0]
81
116
82# Import subprocess after we check the version since it doesn't exist in
83# Python < 2.4.
84import subprocess
85
86# helper function: compare arrays or strings of version numbers.
87# E.g., compare_version((1,3,25), (1,4,1)')
88# returns -1, 0, 1 if v1 is <, ==, > v2
89def compare_versions(v1, v2):
90 def make_version_list(v):
91 if isinstance(v, (list,tuple)):
92 return v
93 elif isinstance(v, str):

--- 7 unchanged lines hidden (view full) ---

101 for n1,n2 in zip(v1, v2):
102 if n1 < n2: return -1
103 if n1 > n2: return 1
104 # all corresponding values are equal... see if one has extra values
105 if len(v1) < len(v2): return -1
106 if len(v1) > len(v2): return 1
107 return 0
108
117# helper function: compare arrays or strings of version numbers.
118# E.g., compare_version((1,3,25), (1,4,1)')
119# returns -1, 0, 1 if v1 is <, ==, > v2
120def compare_versions(v1, v2):
121 def make_version_list(v):
122 if isinstance(v, (list,tuple)):
123 return v
124 elif isinstance(v, str):

--- 7 unchanged lines hidden (view full) ---

132 for n1,n2 in zip(v1, v2):
133 if n1 < n2: return -1
134 if n1 > n2: return 1
135 # all corresponding values are equal... see if one has extra values
136 if len(v1) < len(v2): return -1
137 if len(v1) > len(v2): return 1
138 return 0
139
109# SCons version numbers need special processing because they can have
110# charecters and an release date embedded in them. This function does
111# the magic to extract them in a similar way to the SCons internal function
112# function does and then checks that the current version is not contained in
113# a list of version tuples (bad_ver_strs)
114def CheckSCons(bad_ver_strs):
115 def scons_ver(v):
116 num_parts = v.split(' ')[0].split('.')
117 major = int(num_parts[0])
118 minor = int(re.match('\d+', num_parts[1]).group())
119 rev = 0
120 rdate = 0
121 if len(num_parts) > 2:
122 try: rev = int(re.match('\d+', num_parts[2]).group())
123 except: pass
124 rev_parts = num_parts[2].split('d')
125 if len(rev_parts) > 1:
126 rdate = int(re.match('\d+', rev_parts[1]).group())
127
128 return (major, minor, rev, rdate)
129
130 sc_ver = scons_ver(SCons.__version__)
131 for bad_ver in bad_ver_strs:
132 bv = (scons_ver(bad_ver[0]), scons_ver(bad_ver[1]))
133 if compare_versions(sc_ver, bv[0]) != -1 and\
134 compare_versions(sc_ver, bv[1]) != 1:
135 print "The version of SCons that you have installed: ", SCons.__version__
136 print "has a bug that prevents it from working correctly with M5."
137 print "Please install a version NOT contained within the following",
138 print "ranges (inclusive):"
139 for bad_ver in bad_ver_strs:
140 print " %s - %s" % bad_ver
141 Exit(2)
142
143CheckSCons((
144 # We need a version that is 0.96.91 or newer
145 ('0.0.0', '0.96.90'),
146 ))
147
148
149# The absolute path to the current directory (where this file lives).
150ROOT = Dir('.').abspath
151
152# Path to the M5 source tree.
153SRCDIR = joinpath(ROOT, 'src')
154
155# tell python where to find m5 python code
156sys.path.append(joinpath(ROOT, 'src/python'))
157
140# The absolute path to the current directory (where this file lives).
141ROOT = Dir('.').abspath
142
143# Path to the M5 source tree.
144SRCDIR = joinpath(ROOT, 'src')
145
146# tell python where to find m5 python code
147sys.path.append(joinpath(ROOT, 'src/python'))
148
149###################################################
150# Mercurial Stuff.
151# 1) Grab repository revision if we know it.
152# 2) Ensure that the style hook is in place.
153###################################################
154
155hg_info = "Unknown"
156try:
157 if not exists(ROOT) or not isdir(ROOT) or \
158 not exists(joinpath(ROOT, ".hg")):
159 raise ValueError(".hg directory not found")
160 hg_info = read_command("cd %s; hg id -n -i -t -b" % ROOT).strip()
161except ImportError, e:
162 print "Mercurial not found"
163except ValueError, e:
164 print e
165except Exception, e:
166 print "Other mercurial exception: %s" % e
167
158def check_style_hook(ui):
159 ui.readconfig(joinpath(ROOT, '.hg', 'hgrc'))
160 style_hook = ui.config('hooks', 'pretxncommit.style', None)
161
162 if not style_hook:
163 print """\
164You're missing the M5 style hook.
165Please install the hook so we can ensure that all code fits a common style.

--- 12 unchanged lines hidden (view full) ---

178
179if ARGUMENTS.get('IGNORE_STYLE') != 'True' and isdir(joinpath(ROOT, '.hg')):
180 try:
181 from mercurial import ui
182 check_style_hook(ui.ui())
183 except ImportError:
184 pass
185
168def check_style_hook(ui):
169 ui.readconfig(joinpath(ROOT, '.hg', 'hgrc'))
170 style_hook = ui.config('hooks', 'pretxncommit.style', None)
171
172 if not style_hook:
173 print """\
174You're missing the M5 style hook.
175Please install the hook so we can ensure that all code fits a common style.

--- 12 unchanged lines hidden (view full) ---

188
189if ARGUMENTS.get('IGNORE_STYLE') != 'True' and isdir(joinpath(ROOT, '.hg')):
190 try:
191 from mercurial import ui
192 check_style_hook(ui.ui())
193 except ImportError:
194 pass
195
196
186###################################################
187#
188# Figure out which configurations to set up based on the path(s) of
189# the target(s).
190#
191###################################################
192
193# Find default configuration & binary.
197###################################################
198#
199# Figure out which configurations to set up based on the path(s) of
200# the target(s).
201#
202###################################################
203
204# Find default configuration & binary.
194Default(os.environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
205Default(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
195
196# helper function: find last occurrence of element in list
197def rfind(l, elt, offs = -1):
198 for i in range(len(l)+offs, 0, -1):
199 if l[i] == elt:
200 return i
201 raise ValueError, "element not found"
202
203# Each target must have 'build' in the interior of the path; the
204# directory below this will determine the build parameters. For
205# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we
206# recognize that ALPHA_SE specifies the configuration because it
207# follow 'build' in the bulid path.
208
209# Generate absolute paths to targets so we can see where the build dir is
210if COMMAND_LINE_TARGETS:
211 # Ask SCons which directory it was invoked from
212 launch_dir = GetLaunchDir()
213 # Make targets relative to invocation directory
206
207# helper function: find last occurrence of element in list
208def rfind(l, elt, offs = -1):
209 for i in range(len(l)+offs, 0, -1):
210 if l[i] == elt:
211 return i
212 raise ValueError, "element not found"
213
214# Each target must have 'build' in the interior of the path; the
215# directory below this will determine the build parameters. For
216# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we
217# recognize that ALPHA_SE specifies the configuration because it
218# follow 'build' in the bulid path.
219
220# Generate absolute paths to targets so we can see where the build dir is
221if COMMAND_LINE_TARGETS:
222 # Ask SCons which directory it was invoked from
223 launch_dir = GetLaunchDir()
224 # Make targets relative to invocation directory
214 abs_targets = map(lambda x: os.path.normpath(joinpath(launch_dir, str(x))),
215 COMMAND_LINE_TARGETS)
225 abs_targets = [ normpath(joinpath(launch_dir, str(x))) for x in \
226 COMMAND_LINE_TARGETS]
216else:
217 # Default targets are relative to root of tree
227else:
228 # Default targets are relative to root of tree
218 abs_targets = map(lambda x: os.path.normpath(joinpath(ROOT, str(x))),
219 DEFAULT_TARGETS)
229 abs_targets = [ normpath(joinpath(ROOT, str(x))) for x in \
230 DEFAULT_TARGETS]
220
221
222# Generate a list of the unique build roots and configs that the
223# collected targets reference.
231
232
233# Generate a list of the unique build roots and configs that the
234# collected targets reference.
224build_paths = []
235variant_paths = []
225build_root = None
226for t in abs_targets:
227 path_dirs = t.split('/')
228 try:
229 build_top = rfind(path_dirs, 'build', -2)
230 except:
231 print "Error: no non-leaf 'build' dir found on target path", t
232 Exit(1)
233 this_build_root = joinpath('/',*path_dirs[:build_top+1])
234 if not build_root:
235 build_root = this_build_root
236 else:
237 if this_build_root != build_root:
238 print "Error: build targets not under same build root\n"\
239 " %s\n %s" % (build_root, this_build_root)
240 Exit(1)
236build_root = None
237for t in abs_targets:
238 path_dirs = t.split('/')
239 try:
240 build_top = rfind(path_dirs, 'build', -2)
241 except:
242 print "Error: no non-leaf 'build' dir found on target path", t
243 Exit(1)
244 this_build_root = joinpath('/',*path_dirs[:build_top+1])
245 if not build_root:
246 build_root = this_build_root
247 else:
248 if this_build_root != build_root:
249 print "Error: build targets not under same build root\n"\
250 " %s\n %s" % (build_root, this_build_root)
251 Exit(1)
241 build_path = joinpath('/',*path_dirs[:build_top+2])
242 if build_path not in build_paths:
243 build_paths.append(build_path)
252 variant_path = joinpath('/',*path_dirs[:build_top+2])
253 if variant_path not in variant_paths:
254 variant_paths.append(variant_path)
244
245# Make sure build_root exists (might not if this is the first build there)
246if not isdir(build_root):
255
256# Make sure build_root exists (might not if this is the first build there)
257if not isdir(build_root):
247 os.mkdir(build_root)
258 mkdir(build_root)
248
249###################################################
250#
251# Set up the default build environment. This environment is copied
252# and modified according to each selected configuration.
253#
254###################################################
255
259
260###################################################
261#
262# Set up the default build environment. This environment is copied
263# and modified according to each selected configuration.
264#
265###################################################
266
256env = Environment(ENV = os.environ, # inherit user's environment vars
267env = Environment(ENV = environ, # inherit user's environment vars
257 ROOT = ROOT,
268 ROOT = ROOT,
258 SRCDIR = SRCDIR)
269 SRCDIR = SRCDIR,
270 HG_INFO = hg_info)
259
260Export('env')
261
271
272Export('env')
273
262env.SConsignFile(joinpath(build_root,"sconsign"))
274env.SConsignFile(joinpath(build_root, "sconsign"))
263
264# Default duplicate option is to use hard links, but this messes up
265# when you use emacs to edit a file in the target dir, as emacs moves
266# file to file~ then copies to file, breaking the link. Symbolic
267# (soft) links work better.
268env.SetOption('duplicate', 'soft-copy')
269
275
276# Default duplicate option is to use hard links, but this messes up
277# when you use emacs to edit a file in the target dir, as emacs moves
278# file to file~ then copies to file, breaking the link. Symbolic
279# (soft) links work better.
280env.SetOption('duplicate', 'soft-copy')
281
270# I waffle on this setting... it does avoid a few painful but
271# unnecessary builds, but it also seems to make trivial builds take
272# noticeably longer.
273if False:
274 env.TargetSignatures('content')
275
276#
282#
277# Set up global sticky options... these are common to an entire build
283# Set up global sticky variables... these are common to an entire build
278# tree (not specific to a particular build like ALPHA_SE)
279#
280
284# tree (not specific to a particular build like ALPHA_SE)
285#
286
281# Option validators & converters for global sticky options
287# Variable validators & converters for global sticky variables
282def PathListMakeAbsolute(val):
283 if not val:
284 return val
288def PathListMakeAbsolute(val):
289 if not val:
290 return val
285 f = lambda p: os.path.abspath(os.path.expanduser(p))
291 f = lambda p: abspath(expanduser(p))
286 return ':'.join(map(f, val.split(':')))
287
288def PathListAllExist(key, val, env):
289 if not val:
290 return
291 paths = val.split(':')
292 for path in paths:
293 if not isdir(path):
294 raise SCons.Errors.UserError("Path does not exist: '%s'" % path)
295
292 return ':'.join(map(f, val.split(':')))
293
294def PathListAllExist(key, val, env):
295 if not val:
296 return
297 paths = val.split(':')
298 for path in paths:
299 if not isdir(path):
300 raise SCons.Errors.UserError("Path does not exist: '%s'" % path)
301
296global_sticky_opts_file = joinpath(build_root, 'options.global')
302global_sticky_vars_file = joinpath(build_root, 'variables.global')
297
303
298global_sticky_opts = Options(global_sticky_opts_file, args=ARGUMENTS)
304global_sticky_vars = Variables(global_sticky_vars_file, args=ARGUMENTS)
299
305
300global_sticky_opts.AddOptions(
301 ('CC', 'C compiler', os.environ.get('CC', env['CC'])),
302 ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
306global_sticky_vars.AddVariables(
307 ('CC', 'C compiler', environ.get('CC', env['CC'])),
308 ('CXX', 'C++ compiler', environ.get('CXX', env['CXX'])),
303 ('BATCH', 'Use batch pool for build and tests', False),
304 ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
305 ('EXTRAS', 'Add Extra directories to the compilation', '',
306 PathListAllExist, PathListMakeAbsolute)
307 )
308
309 ('BATCH', 'Use batch pool for build and tests', False),
310 ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
311 ('EXTRAS', 'Add Extra directories to the compilation', '',
312 PathListAllExist, PathListMakeAbsolute)
313 )
314
309
310# base help text
311help_text = '''
312Usage: scons [scons options] [build options] [target(s)]
313
315# base help text
316help_text = '''
317Usage: scons [scons options] [build options] [target(s)]
318
319Global sticky options:
314'''
315
320'''
321
316help_text += "Global sticky options:\n" \
317 + global_sticky_opts.GenerateHelpText(env)
322help_text += global_sticky_vars.GenerateHelpText(env)
318
323
319# Update env with values from ARGUMENTS & file global_sticky_opts_file
320global_sticky_opts.Update(env)
324# Update env with values from ARGUMENTS & file global_sticky_vars_file
325global_sticky_vars.Update(env)
321
326
322# Save sticky option settings back to current options file
323global_sticky_opts.Save(global_sticky_opts_file, env)
327# Save sticky variable settings back to current variables file
328global_sticky_vars.Save(global_sticky_vars_file, env)
324
329
325# Parse EXTRAS option to build list of all directories where we're
330# Parse EXTRAS variable to build list of all directories where we're
326# look for sources etc. This list is exported as base_dir_list.
327base_dir = joinpath(ROOT, 'src')
328if env['EXTRAS']:
329 extras_dir_list = env['EXTRAS'].split(':')
330else:
331 extras_dir_list = []
332
333Export('base_dir')
334Export('extras_dir_list')
335
336# M5_PLY is used by isa_parser.py to find the PLY package.
337env.Append(ENV = { 'M5_PLY' : str(Dir('ext/ply')) })
331# look for sources etc. This list is exported as base_dir_list.
332base_dir = joinpath(ROOT, 'src')
333if env['EXTRAS']:
334 extras_dir_list = env['EXTRAS'].split(':')
335else:
336 extras_dir_list = []
337
338Export('base_dir')
339Export('extras_dir_list')
340
341# M5_PLY is used by isa_parser.py to find the PLY package.
342env.Append(ENV = { 'M5_PLY' : str(Dir('ext/ply')) })
338env['GCC'] = subprocess.Popen(env['CXX'] + ' --version', shell=True,
339 stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
340 close_fds=True).communicate()[0].find('g++') >= 0
341env['SUNCC'] = subprocess.Popen(env['CXX'] + ' -V', shell=True,
342 stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
343 close_fds=True).communicate()[0].find('Sun C++') >= 0
344env['ICC'] = subprocess.Popen(env['CXX'] + ' -V', shell=True,
345 stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
346 close_fds=True).communicate()[0].find('Intel') >= 0
343env['GCC'] = read_command(env['CXX'] + ' --version').find('g++') >= 0
344env['SUNCC'] = read_command(env['CXX'] + ' -V').find('Sun C++') >= 0
345env['ICC'] = read_command(env['CXX'] + ' -V').find('Intel') >= 0
347if env['GCC'] + env['SUNCC'] + env['ICC'] > 1:
348 print 'Error: How can we have two at the same time?'
349 Exit(1)
350
346if env['GCC'] + env['SUNCC'] + env['ICC'] > 1:
347 print 'Error: How can we have two at the same time?'
348 Exit(1)
349
351
352# Set up default C++ compiler flags
353if env['GCC']:
354 env.Append(CCFLAGS='-pipe')
355 env.Append(CCFLAGS='-fno-strict-aliasing')
356 env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
357 env.Append(CXXFLAGS='-Wno-deprecated')
358elif env['ICC']:
359 pass #Fix me... add warning flags once we clean up icc warnings

--- 25 unchanged lines hidden (view full) ---

385
386# Check for SWIG
387if not env.has_key('SWIG'):
388 print 'Error: SWIG utility not found.'
389 print ' Please install (see http://www.swig.org) and retry.'
390 Exit(1)
391
392# Check for appropriate SWIG version
350# Set up default C++ compiler flags
351if env['GCC']:
352 env.Append(CCFLAGS='-pipe')
353 env.Append(CCFLAGS='-fno-strict-aliasing')
354 env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
355 env.Append(CXXFLAGS='-Wno-deprecated')
356elif env['ICC']:
357 pass #Fix me... add warning flags once we clean up icc warnings

--- 25 unchanged lines hidden (view full) ---

383
384# Check for SWIG
385if not env.has_key('SWIG'):
386 print 'Error: SWIG utility not found.'
387 print ' Please install (see http://www.swig.org) and retry.'
388 Exit(1)
389
390# Check for appropriate SWIG version
393swig_version = os.popen('swig -version').read().split()
391swig_version = read_command('swig -version').split()
394# First 3 words should be "SWIG Version x.y.z"
395if len(swig_version) < 3 or \
396 swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
397 print 'Error determining SWIG version.'
398 Exit(1)
399
400min_swig_version = '1.3.28'
401if compare_versions(swig_version[2], min_swig_version) < 0:

--- 63 unchanged lines hidden (view full) ---

465# way so don't need to check the return code.
466conf.CheckLeading()
467
468# Check if we should compile a 64 bit binary on Mac OS X/Darwin
469try:
470 import platform
471 uname = platform.uname()
472 if uname[0] == 'Darwin' and compare_versions(uname[2], '9.0.0') >= 0:
392# First 3 words should be "SWIG Version x.y.z"
393if len(swig_version) < 3 or \
394 swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
395 print 'Error determining SWIG version.'
396 Exit(1)
397
398min_swig_version = '1.3.28'
399if compare_versions(swig_version[2], min_swig_version) < 0:

--- 63 unchanged lines hidden (view full) ---

463# way so don't need to check the return code.
464conf.CheckLeading()
465
466# Check if we should compile a 64 bit binary on Mac OS X/Darwin
467try:
468 import platform
469 uname = platform.uname()
470 if uname[0] == 'Darwin' and compare_versions(uname[2], '9.0.0') >= 0:
473 if int(subprocess.Popen('sysctl -n hw.cpu64bit_capable', shell=True,
474 stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
475 close_fds=True).communicate()[0][0]):
471 if int(read_command('sysctl -n hw.cpu64bit_capable')[0]):
476 env.Append(CCFLAGS='-arch x86_64')
477 env.Append(CFLAGS='-arch x86_64')
478 env.Append(LINKFLAGS='-arch x86_64')
479 env.Append(ASFLAGS='-arch x86_64')
480except:
481 pass
482
483# Recent versions of scons substitute a "Null" object for Configure()

--- 15 unchanged lines hidden (view full) ---

499
500 conf = NullConf(env)
501
502# Find Python include and library directories for embedding the
503# interpreter. For consistency, we will use the same Python
504# installation used to run scons (and thus this script). If you want
505# to link in an alternate version, see above for instructions on how
506# to invoke scons with a different copy of the Python interpreter.
472 env.Append(CCFLAGS='-arch x86_64')
473 env.Append(CFLAGS='-arch x86_64')
474 env.Append(LINKFLAGS='-arch x86_64')
475 env.Append(ASFLAGS='-arch x86_64')
476except:
477 pass
478
479# Recent versions of scons substitute a "Null" object for Configure()

--- 15 unchanged lines hidden (view full) ---

495
496 conf = NullConf(env)
497
498# Find Python include and library directories for embedding the
499# interpreter. For consistency, we will use the same Python
500# installation used to run scons (and thus this script). If you want
501# to link in an alternate version, see above for instructions on how
502# to invoke scons with a different copy of the Python interpreter.
503from distutils import sysconfig
507
504
508# Get brief Python version name (e.g., "python2.4") for locating
509# include & library files
510py_version_name = 'python' + sys.version[:3]
505py_getvar = sysconfig.get_config_var
511
506
512# include path, e.g. /usr/local/include/python2.4
513py_header_path = joinpath(sys.exec_prefix, 'include', py_version_name)
514env.Append(CPPPATH = py_header_path)
515# verify that it works
507py_version = 'python' + py_getvar('VERSION')
508
509py_general_include = sysconfig.get_python_inc()
510py_platform_include = sysconfig.get_python_inc(plat_specific=True)
511py_includes = [ py_general_include ]
512if py_platform_include != py_general_include:
513 py_includes.append(py_platform_include)
514
515py_lib_path = []
516# add the prefix/lib/pythonX.Y/config dir, but only if there is no
517# shared library in prefix/lib/.
518if not py_getvar('Py_ENABLE_SHARED'):
519 py_lib_path.append('-L' + py_getvar('LIBPL'))
520
521py_libs = []
522for lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split():
523 if lib not in py_libs:
524 py_libs.append(lib)
525py_libs.append('-l' + py_version)
526
527env.Append(CPPPATH=py_includes)
528env.Append(LIBPATH=py_lib_path)
529#env.Append(LIBS=py_libs)
530
531# verify that this stuff works
516if not conf.CheckHeader('Python.h', '<>'):
532if not conf.CheckHeader('Python.h', '<>'):
517 print "Error: can't find Python.h header in", py_header_path
533 print "Error: can't find Python.h header in", py_includes
518 Exit(1)
519
534 Exit(1)
535
520# add library path too if it's not in the default place
521py_lib_path = None
522if sys.exec_prefix != '/usr':
523 py_lib_path = joinpath(sys.exec_prefix, 'lib')
524elif sys.platform == 'cygwin':
525 # cygwin puts the .dll in /bin for some reason
526 py_lib_path = '/bin'
527if py_lib_path:
528 env.Append(LIBPATH = py_lib_path)
529 print 'Adding', py_lib_path, 'to LIBPATH for', py_version_name
530if not conf.CheckLib(py_version_name):
531 print "Error: can't find Python library", py_version_name
532 Exit(1)
536for lib in py_libs:
537 assert lib.startswith('-l')
538 lib = lib[2:]
539 if not conf.CheckLib(lib):
540 print "Error: can't find library %s required by python" % lib
541 Exit(1)
533
534# On Solaris you need to use libsocket for socket ops
535if not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'):
536 if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'):
537 print "Can't find library with socket calls (e.g. accept())"
538 Exit(1)
539
540# Check for zlib. If the check passes, libz will be automatically

--- 5 unchanged lines hidden (view full) ---

546 Exit(1)
547
548# Check for <fenv.h> (C99 FP environment control)
549have_fenv = conf.CheckHeader('fenv.h', '<>')
550if not have_fenv:
551 print "Warning: Header file <fenv.h> not found."
552 print " This host has no IEEE FP rounding mode control."
553
542
543# On Solaris you need to use libsocket for socket ops
544if not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'):
545 if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'):
546 print "Can't find library with socket calls (e.g. accept())"
547 Exit(1)
548
549# Check for zlib. If the check passes, libz will be automatically

--- 5 unchanged lines hidden (view full) ---

555 Exit(1)
556
557# Check for <fenv.h> (C99 FP environment control)
558have_fenv = conf.CheckHeader('fenv.h', '<>')
559if not have_fenv:
560 print "Warning: Header file <fenv.h> not found."
561 print " This host has no IEEE FP rounding mode control."
562
563######################################################################
564#
554# Check for mysql.
565# Check for mysql.
566#
555mysql_config = WhereIs('mysql_config')
567mysql_config = WhereIs('mysql_config')
556have_mysql = mysql_config != None
568have_mysql = bool(mysql_config)
557
558# Check MySQL version.
559if have_mysql:
569
570# Check MySQL version.
571if have_mysql:
560 mysql_version = os.popen(mysql_config + ' --version').read()
572 mysql_version = read_command(mysql_config + ' --version')
561 min_mysql_version = '4.1'
562 if compare_versions(mysql_version, min_mysql_version) < 0:
563 print 'Warning: MySQL', min_mysql_version, 'or newer required.'
564 print ' Version', mysql_version, 'detected.'
565 have_mysql = False
566
567# Set up mysql_config commands.
568if have_mysql:
569 mysql_config_include = mysql_config + ' --include'
570 if os.system(mysql_config_include + ' > /dev/null') != 0:
571 # older mysql_config versions don't support --include, use
572 # --cflags instead
573 mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g'
574 # This seems to work in all versions
575 mysql_config_libs = mysql_config + ' --libs'
576
573 min_mysql_version = '4.1'
574 if compare_versions(mysql_version, min_mysql_version) < 0:
575 print 'Warning: MySQL', min_mysql_version, 'or newer required.'
576 print ' Version', mysql_version, 'detected.'
577 have_mysql = False
578
579# Set up mysql_config commands.
580if have_mysql:
581 mysql_config_include = mysql_config + ' --include'
582 if os.system(mysql_config_include + ' > /dev/null') != 0:
583 # older mysql_config versions don't support --include, use
584 # --cflags instead
585 mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g'
586 # This seems to work in all versions
587 mysql_config_libs = mysql_config + ' --libs'
588
589######################################################################
590#
591# Finish the configuration
592#
577env = conf.Finish()
578
593env = conf.Finish()
594
595######################################################################
596#
597# Collect all non-global variables
598#
599
579# Define the universe of supported ISAs
580all_isa_list = [ ]
581Export('all_isa_list')
582
583# Define the universe of supported CPU models
584all_cpu_list = [ ]
585default_cpus = [ ]
586Export('all_cpu_list', 'default_cpus')
587
600# Define the universe of supported ISAs
601all_isa_list = [ ]
602Export('all_isa_list')
603
604# Define the universe of supported CPU models
605all_cpu_list = [ ]
606default_cpus = [ ]
607Export('all_cpu_list', 'default_cpus')
608
588# Sticky options get saved in the options file so they persist from
609# Sticky variables get saved in the variables file so they persist from
589# one invocation to the next (unless overridden, in which case the new
590# value becomes sticky).
610# one invocation to the next (unless overridden, in which case the new
611# value becomes sticky).
591sticky_opts = Options(args=ARGUMENTS)
592Export('sticky_opts')
612sticky_vars = Variables(args=ARGUMENTS)
613Export('sticky_vars')
593
614
594# Non-sticky options only apply to the current build.
595nonsticky_opts = Options(args=ARGUMENTS)
596Export('nonsticky_opts')
615# Non-sticky variables only apply to the current build.
616nonsticky_vars = Variables(args=ARGUMENTS)
617Export('nonsticky_vars')
597
598# Walk the tree and execute all SConsopts scripts that wil add to the
618
619# Walk the tree and execute all SConsopts scripts that wil add to the
599# above options
620# above variables
600for bdir in [ base_dir ] + extras_dir_list:
601 for root, dirs, files in os.walk(bdir):
602 if 'SConsopts' in files:
603 print "Reading", joinpath(root, 'SConsopts')
604 SConscript(joinpath(root, 'SConsopts'))
605
606all_isa_list.sort()
607all_cpu_list.sort()
608default_cpus.sort()
609
621for bdir in [ base_dir ] + extras_dir_list:
622 for root, dirs, files in os.walk(bdir):
623 if 'SConsopts' in files:
624 print "Reading", joinpath(root, 'SConsopts')
625 SConscript(joinpath(root, 'SConsopts'))
626
627all_isa_list.sort()
628all_cpu_list.sort()
629default_cpus.sort()
630
610sticky_opts.AddOptions(
611 EnumOption('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
612 BoolOption('FULL_SYSTEM', 'Full-system support', False),
613 # There's a bug in scons 0.96.1 that causes ListOptions with list
614 # values (more than one value) not to be able to be restored from
615 # a saved option file. If this causes trouble then upgrade to
616 # scons 0.96.90 or later.
617 ListOption('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list),
618 BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
619 BoolOption('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
620 False),
621 BoolOption('FAST_ALLOC_STATS', 'Enable fast object allocator statistics',
622 False),
623 BoolOption('EFENCE', 'Link with Electric Fence malloc debugger',
624 False),
625 BoolOption('SS_COMPATIBLE_FP',
626 'Make floating-point results compatible with SimpleScalar',
627 False),
628 BoolOption('USE_SSE2',
629 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
630 False),
631 BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
632 BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
633 BoolOption('USE_CHECKER', 'Use checker for detailed CPU models', False),
631sticky_vars.AddVariables(
632 EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
633 BoolVariable('FULL_SYSTEM', 'Full-system support', False),
634 ListVariable('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list),
635 BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False),
636 BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
637 False),
638 BoolVariable('FAST_ALLOC_STATS', 'Enable fast object allocator statistics',
639 False),
640 BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger',
641 False),
642 BoolVariable('SS_COMPATIBLE_FP',
643 'Make floating-point results compatible with SimpleScalar',
644 False),
645 BoolVariable('USE_SSE2',
646 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
647 False),
648 BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
649 BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
650 BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
634 )
635
651 )
652
636nonsticky_opts.AddOptions(
637 BoolOption('update_ref', 'Update test reference outputs', False)
653nonsticky_vars.AddVariables(
654 BoolVariable('update_ref', 'Update test reference outputs', False)
638 )
639
655 )
656
640# These options get exported to #defines in config/*.hh (see src/SConscript).
641env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
642 'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
643 'FAST_ALLOC_STATS', 'SS_COMPATIBLE_FP', \
644 'USE_CHECKER', 'TARGET_ISA']
657# These variables get exported to #defines in config/*.hh (see src/SConscript).
658env.ExportVariables = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
659 'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
660 'FAST_ALLOC_STATS', 'SS_COMPATIBLE_FP', \
661 'USE_CHECKER', 'TARGET_ISA']
645
662
646# Define a handy 'no-op' action
647def no_action(target, source, env):
648 return 0
649
650env.NoAction = Action(no_action, None)
651
652###################################################
653#
654# Define a SCons builder for configuration flag headers.
655#
656###################################################
657
658# This function generates a config header file that #defines the
663###################################################
664#
665# Define a SCons builder for configuration flag headers.
666#
667###################################################
668
669# This function generates a config header file that #defines the
659# option symbol to the current option setting (0 or 1). The source
660# operands are the name of the option and a Value node containing the
661# value of the option.
670# variable symbol to the current variable setting (0 or 1). The source
671# operands are the name of the variable and a Value node containing the
672# value of the variable.
662def build_config_file(target, source, env):
673def build_config_file(target, source, env):
663 (option, value) = [s.get_contents() for s in source]
674 (variable, value) = [s.get_contents() for s in source]
664 f = file(str(target[0]), 'w')
675 f = file(str(target[0]), 'w')
665 print >> f, '#define', option, value
676 print >> f, '#define', variable, value
666 f.close()
667 return None
668
669# Generate the message to be printed when building the config file.
670def build_config_file_string(target, source, env):
677 f.close()
678 return None
679
680# Generate the message to be printed when building the config file.
681def build_config_file_string(target, source, env):
671 (option, value) = [s.get_contents() for s in source]
672 return "Defining %s as %s in %s." % (option, value, target[0])
682 (variable, value) = [s.get_contents() for s in source]
683 return "Defining %s as %s in %s." % (variable, value, target[0])
673
674# Combine the two functions into a scons Action object.
675config_action = Action(build_config_file, build_config_file_string)
676
677# The emitter munges the source & target node lists to reflect what
678# we're really doing.
679def config_emitter(target, source, env):
684
685# Combine the two functions into a scons Action object.
686config_action = Action(build_config_file, build_config_file_string)
687
688# The emitter munges the source & target node lists to reflect what
689# we're really doing.
690def config_emitter(target, source, env):
680 # extract option name from Builder arg
681 option = str(target[0])
691 # extract variable name from Builder arg
692 variable = str(target[0])
682 # True target is config header file
693 # True target is config header file
683 target = joinpath('config', option.lower() + '.hh')
684 val = env[option]
694 target = joinpath('config', variable.lower() + '.hh')
695 val = env[variable]
685 if isinstance(val, bool):
686 # Force value to 0/1
687 val = int(val)
688 elif isinstance(val, str):
689 val = '"' + val + '"'
690
696 if isinstance(val, bool):
697 # Force value to 0/1
698 val = int(val)
699 elif isinstance(val, str):
700 val = '"' + val + '"'
701
691 # Sources are option name & value (packaged in SCons Value nodes)
692 return ([target], [Value(option), Value(val)])
702 # Sources are variable name & value (packaged in SCons Value nodes)
703 return ([target], [Value(variable), Value(val)])
693
694config_builder = Builder(emitter = config_emitter, action = config_action)
695
696env.Append(BUILDERS = { 'ConfigFile' : config_builder })
697
704
705config_builder = Builder(emitter = config_emitter, action = config_action)
706
707env.Append(BUILDERS = { 'ConfigFile' : config_builder })
708
698###################################################
699#
700# Define a SCons builder for copying files. This is used by the
701# Python zipfile code in src/python/SConscript, but is placed up here
702# since it's potentially more generally applicable.
703#
704###################################################
705
706copy_builder = Builder(action = Copy("$TARGET", "$SOURCE"))
707
708env.Append(BUILDERS = { 'CopyFile' : copy_builder })
709
710###################################################
711#
712# Define a simple SCons builder to concatenate files.
713#
714# Used to append the Python zip archive to the executable.
715#
716###################################################
717
718concat_builder = Builder(action = Action(['cat $SOURCES > $TARGET',
719 'chmod +x $TARGET']))
720
721env.Append(BUILDERS = { 'Concat' : concat_builder })
722
723
724# libelf build is shared across all configs in the build root.
725env.SConscript('ext/libelf/SConscript',
709# libelf build is shared across all configs in the build root.
710env.SConscript('ext/libelf/SConscript',
726 build_dir = joinpath(build_root, 'libelf'),
711 variant_dir = joinpath(build_root, 'libelf'),
727 exports = 'env')
728
729# gzstream build is shared across all configs in the build root.
730env.SConscript('ext/gzstream/SConscript',
712 exports = 'env')
713
714# gzstream build is shared across all configs in the build root.
715env.SConscript('ext/gzstream/SConscript',
731 build_dir = joinpath(build_root, 'gzstream'),
716 variant_dir = joinpath(build_root, 'gzstream'),
732 exports = 'env')
733
734###################################################
735#
736# This function is used to set up a directory with switching headers
737#
738###################################################
739
740env['ALL_ISA_LIST'] = all_isa_list
717 exports = 'env')
718
719###################################################
720#
721# This function is used to set up a directory with switching headers
722#
723###################################################
724
725env['ALL_ISA_LIST'] = all_isa_list
741def make_switching_dir(dirname, switch_headers, env):
726def make_switching_dir(dname, switch_headers, env):
742 # Generate the header. target[0] is the full path of the output
743 # header to generate. 'source' is a dummy variable, since we get the
744 # list of ISAs from env['ALL_ISA_LIST'].
745 def gen_switch_hdr(target, source, env):
746 fname = str(target[0])
727 # Generate the header. target[0] is the full path of the output
728 # header to generate. 'source' is a dummy variable, since we get the
729 # list of ISAs from env['ALL_ISA_LIST'].
730 def gen_switch_hdr(target, source, env):
731 fname = str(target[0])
747 basename = os.path.basename(fname)
732 bname = basename(fname)
748 f = open(fname, 'w')
749 f.write('#include "arch/isa_specific.hh"\n')
750 cond = '#if'
751 for isa in all_isa_list:
752 f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n'
733 f = open(fname, 'w')
734 f.write('#include "arch/isa_specific.hh"\n')
735 cond = '#if'
736 for isa in all_isa_list:
737 f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n'
753 % (cond, isa.upper(), dirname, isa, basename))
738 % (cond, isa.upper(), dname, isa, bname))
754 cond = '#elif'
755 f.write('#else\n#error "THE_ISA not set"\n#endif\n')
756 f.close()
757 return 0
758
759 # String to print when generating header
760 def gen_switch_hdr_string(target, source, env):
761 return "Generating switch header " + str(target[0])

--- 13 unchanged lines hidden (view full) ---

775#
776# Define build environments for selected configurations.
777#
778###################################################
779
780# rename base env
781base_env = env
782
739 cond = '#elif'
740 f.write('#else\n#error "THE_ISA not set"\n#endif\n')
741 f.close()
742 return 0
743
744 # String to print when generating header
745 def gen_switch_hdr_string(target, source, env):
746 return "Generating switch header " + str(target[0])

--- 13 unchanged lines hidden (view full) ---

760#
761# Define build environments for selected configurations.
762#
763###################################################
764
765# rename base env
766base_env = env
767
783for build_path in build_paths:
784 print "Building in", build_path
768for variant_path in variant_paths:
769 print "Building in", variant_path
785
786 # Make a copy of the build-root environment to use for this config.
770
771 # Make a copy of the build-root environment to use for this config.
787 env = base_env.Copy()
788 env['BUILDDIR'] = build_path
772 env = base_env.Clone()
773 env['BUILDDIR'] = variant_path
789
774
790 # build_dir is the tail component of build path, and is used to
775 # variant_dir is the tail component of build path, and is used to
791 # determine the build parameters (e.g., 'ALPHA_SE')
776 # determine the build parameters (e.g., 'ALPHA_SE')
792 (build_root, build_dir) = os.path.split(build_path)
777 (build_root, variant_dir) = splitpath(variant_path)
793
778
794 # Set env options according to the build directory config.
795 sticky_opts.files = []
796 # Options for $BUILD_ROOT/$BUILD_DIR are stored in
797 # $BUILD_ROOT/options/$BUILD_DIR so you can nuke
798 # $BUILD_ROOT/$BUILD_DIR without losing your options settings.
799 current_opts_file = joinpath(build_root, 'options', build_dir)
800 if isfile(current_opts_file):
801 sticky_opts.files.append(current_opts_file)
802 print "Using saved options file %s" % current_opts_file
779 # Set env variables according to the build directory config.
780 sticky_vars.files = []
781 # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in
782 # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke
783 # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings.
784 current_vars_file = joinpath(build_root, 'variables', variant_dir)
785 if isfile(current_vars_file):
786 sticky_vars.files.append(current_vars_file)
787 print "Using saved variables file %s" % current_vars_file
803 else:
788 else:
804 # Build dir-specific options file doesn't exist.
789 # Build dir-specific variables file doesn't exist.
805
806 # Make sure the directory is there so we can create it later
790
791 # Make sure the directory is there so we can create it later
807 opt_dir = os.path.dirname(current_opts_file)
792 opt_dir = dirname(current_vars_file)
808 if not isdir(opt_dir):
793 if not isdir(opt_dir):
809 os.mkdir(opt_dir)
794 mkdir(opt_dir)
810
795
811 # Get default build options from source tree. Options are
812 # normally determined by name of $BUILD_DIR, but can be
796 # Get default build variables from source tree. Variables are
797 # normally determined by name of $VARIANT_DIR, but can be
813 # overriden by 'default=' arg on command line.
798 # overriden by 'default=' arg on command line.
814 default_opts_file = joinpath('build_opts',
815 ARGUMENTS.get('default', build_dir))
816 if isfile(default_opts_file):
817 sticky_opts.files.append(default_opts_file)
818 print "Options file %s not found,\n using defaults in %s" \
819 % (current_opts_file, default_opts_file)
799 default_vars_file = joinpath('build_opts',
800 ARGUMENTS.get('default', variant_dir))
801 if isfile(default_vars_file):
802 sticky_vars.files.append(default_vars_file)
803 print "Variables file %s not found,\n using defaults in %s" \
804 % (current_vars_file, default_vars_file)
820 else:
805 else:
821 print "Error: cannot find options file %s or %s" \
822 % (current_opts_file, default_opts_file)
806 print "Error: cannot find variables file %s or %s" \
807 % (current_vars_file, default_vars_file)
823 Exit(1)
824
808 Exit(1)
809
825 # Apply current option settings to env
826 sticky_opts.Update(env)
827 nonsticky_opts.Update(env)
810 # Apply current variable settings to env
811 sticky_vars.Update(env)
812 nonsticky_vars.Update(env)
828
813
829 help_text += "\nSticky options for %s:\n" % build_dir \
830 + sticky_opts.GenerateHelpText(env) \
831 + "\nNon-sticky options for %s:\n" % build_dir \
832 + nonsticky_opts.GenerateHelpText(env)
814 help_text += "\nSticky variables for %s:\n" % variant_dir \
815 + sticky_vars.GenerateHelpText(env) \
816 + "\nNon-sticky variables for %s:\n" % variant_dir \
817 + nonsticky_vars.GenerateHelpText(env)
833
818
834 # Process option settings.
819 # Process variable settings.
835
836 if not have_fenv and env['USE_FENV']:
837 print "Warning: <fenv.h> not available; " \
820
821 if not have_fenv and env['USE_FENV']:
822 print "Warning: <fenv.h> not available; " \
838 "forcing USE_FENV to False in", build_dir + "."
823 "forcing USE_FENV to False in", variant_dir + "."
839 env['USE_FENV'] = False
840
841 if not env['USE_FENV']:
824 env['USE_FENV'] = False
825
826 if not env['USE_FENV']:
842 print "Warning: No IEEE FP rounding mode control in", build_dir + "."
827 print "Warning: No IEEE FP rounding mode control in", variant_dir + "."
843 print " FP results may deviate slightly from other platforms."
844
845 if env['EFENCE']:
846 env.Append(LIBS=['efence'])
847
848 if env['USE_MYSQL']:
849 if not have_mysql:
850 print "Warning: MySQL not available; " \
828 print " FP results may deviate slightly from other platforms."
829
830 if env['EFENCE']:
831 env.Append(LIBS=['efence'])
832
833 if env['USE_MYSQL']:
834 if not have_mysql:
835 print "Warning: MySQL not available; " \
851 "forcing USE_MYSQL to False in", build_dir + "."
836 "forcing USE_MYSQL to False in", variant_dir + "."
852 env['USE_MYSQL'] = False
853 else:
837 env['USE_MYSQL'] = False
838 else:
854 print "Compiling in", build_dir, "with MySQL support."
839 print "Compiling in", variant_dir, "with MySQL support."
855 env.ParseConfig(mysql_config_libs)
856 env.ParseConfig(mysql_config_include)
857
840 env.ParseConfig(mysql_config_libs)
841 env.ParseConfig(mysql_config_include)
842
858 # Save sticky option settings back to current options file
859 sticky_opts.Save(current_opts_file, env)
843 # Save sticky variable settings back to current variables file
844 sticky_vars.Save(current_vars_file, env)
860
861 if env['USE_SSE2']:
862 env.Append(CCFLAGS='-msse2')
863
864 # The src/SConscript file sets up the build rules in 'env' according
845
846 if env['USE_SSE2']:
847 env.Append(CCFLAGS='-msse2')
848
849 # The src/SConscript file sets up the build rules in 'env' according
865 # to the configured options. It returns a list of environments,
850 # to the configured variables. It returns a list of environments,
866 # one for each variant build (debug, opt, etc.)
851 # one for each variant build (debug, opt, etc.)
867 envList = SConscript('src/SConscript', build_dir = build_path,
852 envList = SConscript('src/SConscript', variant_dir = variant_path,
868 exports = 'env')
869
870 # Set up the regression tests for each build.
871 for e in envList:
872 SConscript('tests/SConscript',
853 exports = 'env')
854
855 # Set up the regression tests for each build.
856 for e in envList:
857 SConscript('tests/SConscript',
873 build_dir = joinpath(build_path, 'tests', e.Label),
858 variant_dir = joinpath(variant_path, 'tests', e.Label),
874 exports = { 'env' : e }, duplicate = False)
875
876Help(help_text)
877
878
879###################################################
880#
881# Let SCons do its thing. At this point SCons will use the defined
882# build environments to build the requested targets.
883#
884###################################################
885
859 exports = { 'env' : e }, duplicate = False)
860
861Help(help_text)
862
863
864###################################################
865#
866# Let SCons do its thing. At this point SCons will use the defined
867# build environments to build the requested targets.
868#
869###################################################
870