SConstruct (5863:f73e06bc8765) SConstruct (5871:8007803be77a)
1# -*- mode:python -*-
2
1# -*- mode:python -*-
2
3# Copyright (c) 2009 The Hewlett-Packard Development Company
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
9# notice, this list of conditions and the following disclaimer;
10# redistributions in binary form must reproduce the above copyright

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

101import sys
102
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
107
108import SCons
4# Copyright (c) 2004-2005 The Regents of The University of Michigan
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are
9# met: redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer;
11# redistributions in binary form must reproduce the above copyright

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

102import sys
103
104from os import mkdir, environ
105from os.path import abspath, basename, dirname, expanduser, normpath
106from os.path import exists, isdir, isfile
107from os.path import join as joinpath, split as splitpath
108
109import SCons
110import SCons.Node
109
111
110def read_command(cmd):
112def read_command(cmd, **kwargs):
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
113 """run the command cmd, read the results and return them
114 this is sorta like `cmd` in shell"""
115 from subprocess import Popen, PIPE, STDOUT
114 subp = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, close_fds=True)
116
117 no_exception = 'exception' in kwargs
118 exception = kwargs.pop('exception', None)
119
120 kwargs.setdefault('shell', False)
121 kwargs.setdefault('stdout', PIPE)
122 kwargs.setdefault('stderr', STDOUT)
123 kwargs.setdefault('close_fds', True)
124 try:
125 subp = Popen(cmd, **kwargs)
126 except Exception, e:
127 if no_exception:
128 return exception
129 raise
130
115 return subp.communicate()[0]
116
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)):

--- 9 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
131 return subp.communicate()[0]
132
133# helper function: compare arrays or strings of version numbers.
134# E.g., compare_version((1,3,25), (1,4,1)')
135# returns -1, 0, 1 if v1 is <, ==, > v2
136def compare_versions(v1, v2):
137 def make_version_list(v):
138 if isinstance(v, (list,tuple)):

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

148 for n1,n2 in zip(v1, v2):
149 if n1 < n2: return -1
150 if n1 > n2: return 1
151 # all corresponding values are equal... see if one has extra values
152 if len(v1) < len(v2): return -1
153 if len(v1) > len(v2): return 1
154 return 0
155
140# The absolute path to the current directory (where this file lives).
141ROOT = Dir('.').abspath
156########################################################################
157#
158# Set up the base build environment.
159#
160########################################################################
161use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'PATH', 'RANLIB' ])
142
162
143# Path to the M5 source tree.
144SRCDIR = joinpath(ROOT, 'src')
163use_env = {}
164for key,val in os.environ.iteritems():
165 if key in use_vars or key.startswith("M5"):
166 use_env[key] = val
145
167
146# tell python where to find m5 python code
147sys.path.append(joinpath(ROOT, 'src/python'))
168env = Environment(ENV=use_env)
169env.root = Dir(".") # The current directory (where this file lives).
170env.srcdir = Dir("src") # The source directory
148
171
149###################################################
172########################################################################
173#
150# Mercurial Stuff.
174# Mercurial Stuff.
151# 1) Grab repository revision if we know it.
152# 2) Ensure that the style hook is in place.
153###################################################
175#
176# If the M5 directory is a mercurial repository, we should do some
177# extra things.
178#
179########################################################################
154
180
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
181hgdir = env.root.Dir(".hg")
167
182
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 """\
183mercurial_style_message = """
174You're missing the M5 style hook.
175Please install the hook so we can ensure that all code fits a common style.
176
177All you'd need to do is add the following lines to your repository .hg/hgrc
178or your personal .hgrc
179----------------
180
181[extensions]
182style = %s/util/style.py
183
184[hooks]
185pretxncommit.style = python:style.check_whitespace
184You're missing the M5 style hook.
185Please install the hook so we can ensure that all code fits a common style.
186
187All you'd need to do is add the following lines to your repository .hg/hgrc
188or your personal .hgrc
189----------------
190
191[extensions]
192style = %s/util/style.py
193
194[hooks]
195pretxncommit.style = python:style.check_whitespace
186""" % (ROOT)
187 sys.exit(1)
196""" % (env.root)
188
197
189if ARGUMENTS.get('IGNORE_STYLE') != 'True' and isdir(joinpath(ROOT, '.hg')):
198mercurial_bin_not_found = """
199Mercurial binary cannot be found, unfortunately this means that we
200cannot easily determine the version of M5 that you are running and
201this makes error messages more difficult to collect. Please consider
202installing mercurial if you choose to post an error message
203"""
204
205mercurial_lib_not_found = """
206Mercurial libraries cannot be found, ignoring style hook
207If you are actually a M5 developer, please fix this and
208run the style hook. It is important.
209"""
210
211if hgdir.exists():
212 # 1) Grab repository revision if we know it.
213 cmd = "hg id -n -i -t -b"
190 try:
214 try:
191 from mercurial import ui
192 check_style_hook(ui.ui())
215 hg_info = read_command(cmd, cwd=env.root.abspath).strip()
216 except OSError:
217 hg_info = "Unknown"
218 print mercurial_bin_not_found
219
220 env['HG_INFO'] = hg_info
221
222 # 2) Ensure that the style hook is in place.
223 try:
224 ui = None
225 if ARGUMENTS.get('IGNORE_STYLE') != 'True':
226 from mercurial import ui
227 ui = ui.ui()
193 except ImportError:
228 except ImportError:
194 pass
229 print mercurial_lib_not_found
195
230
231 if ui is not None:
232 ui.readconfig(hgdir.File('hgrc').abspath)
233 style_hook = ui.config('hooks', 'pretxncommit.style', None)
196
234
235 if not style_hook:
236 print mercurial_style_message
237 sys.exit(1)
238else:
239 print ".hg directory not found"
240
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.

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

252 variant_path = joinpath('/',*path_dirs[:build_top+2])
253 if variant_path not in variant_paths:
254 variant_paths.append(variant_path)
255
256# Make sure build_root exists (might not if this is the first build there)
257if not isdir(build_root):
258 mkdir(build_root)
259
241###################################################
242#
243# Figure out which configurations to set up based on the path(s) of
244# the target(s).
245#
246###################################################
247
248# Find default configuration & binary.

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

296 variant_path = joinpath('/',*path_dirs[:build_top+2])
297 if variant_path not in variant_paths:
298 variant_paths.append(variant_path)
299
300# Make sure build_root exists (might not if this is the first build there)
301if not isdir(build_root):
302 mkdir(build_root)
303
260###################################################
261#
262# Set up the default build environment. This environment is copied
263# and modified according to each selected configuration.
264#
265###################################################
266
267env = Environment(ENV = environ, # inherit user's environment vars
268 ROOT = ROOT,
269 SRCDIR = SRCDIR,
270 HG_INFO = hg_info)
271
272Export('env')
273
274env.SConsignFile(joinpath(build_root, "sconsign"))
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.

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

324# Update env with values from ARGUMENTS & file global_sticky_vars_file
325global_sticky_vars.Update(env)
326
327# Save sticky variable settings back to current variables file
328global_sticky_vars.Save(global_sticky_vars_file, env)
329
330# Parse EXTRAS variable to build list of all directories where we're
331# look for sources etc. This list is exported as base_dir_list.
304Export('env')
305
306env.SConsignFile(joinpath(build_root, "sconsign"))
307
308# Default duplicate option is to use hard links, but this messes up
309# when you use emacs to edit a file in the target dir, as emacs moves
310# file to file~ then copies to file, breaking the link. Symbolic
311# (soft) links work better.

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

356# Update env with values from ARGUMENTS & file global_sticky_vars_file
357global_sticky_vars.Update(env)
358
359# Save sticky variable settings back to current variables file
360global_sticky_vars.Save(global_sticky_vars_file, env)
361
362# Parse EXTRAS variable to build list of all directories where we're
363# look for sources etc. This list is exported as base_dir_list.
332base_dir = joinpath(ROOT, 'src')
364base_dir = env.srcdir.abspath
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')) })
365if env['EXTRAS']:
366 extras_dir_list = env['EXTRAS'].split(':')
367else:
368 extras_dir_list = []
369
370Export('base_dir')
371Export('extras_dir_list')
372
373# M5_PLY is used by isa_parser.py to find the PLY package.
374env.Append(ENV = { 'M5_PLY' : str(Dir('ext/ply')) })
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
375
376CXX_version = read_command([env['CXX'],'--version'], exception=False)
377CXX_V = read_command([env['CXX'],'-V'], exception=False)
378
379env['GCC'] = CXX_version and CXX_version.find('g++') >= 0
380env['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
381env['ICC'] = CXX_V and CXX_V.find('Intel') >= 0
346if env['GCC'] + env['SUNCC'] + env['ICC'] > 1:
347 print 'Error: How can we have two at the same time?'
348 Exit(1)
349
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
358elif env['SUNCC']:
359 env.Append(CCFLAGS='-Qoption ccfe')
360 env.Append(CCFLAGS='-features=gcc')
361 env.Append(CCFLAGS='-features=extensions')
362 env.Append(CCFLAGS='-library=stlport4')
363 env.Append(CCFLAGS='-xar')
382if env['GCC'] + env['SUNCC'] + env['ICC'] > 1:
383 print 'Error: How can we have two at the same time?'
384 Exit(1)
385
386# Set up default C++ compiler flags
387if env['GCC']:
388 env.Append(CCFLAGS='-pipe')
389 env.Append(CCFLAGS='-fno-strict-aliasing')
390 env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
391 env.Append(CXXFLAGS='-Wno-deprecated')
392elif env['ICC']:
393 pass #Fix me... add warning flags once we clean up icc warnings
394elif env['SUNCC']:
395 env.Append(CCFLAGS='-Qoption ccfe')
396 env.Append(CCFLAGS='-features=gcc')
397 env.Append(CCFLAGS='-features=extensions')
398 env.Append(CCFLAGS='-library=stlport4')
399 env.Append(CCFLAGS='-xar')
364# env.Append(CCFLAGS='-instances=semiexplicit')
400 #env.Append(CCFLAGS='-instances=semiexplicit')
365else:
366 print 'Error: Don\'t know what compiler options to use for your compiler.'
367 print ' Please fix SConstruct and src/SConscript and try again.'
368 Exit(1)
369
370# Do this after we save setting back, or else we'll tack on an
371# extra 'qdo' every time we run scons.
372if env['BATCH']:

--- 10 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
401else:
402 print 'Error: Don\'t know what compiler options to use for your compiler.'
403 print ' Please fix SConstruct and src/SConscript and try again.'
404 Exit(1)
405
406# Do this after we save setting back, or else we'll tack on an
407# extra 'qdo' every time we run scons.
408if env['BATCH']:

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

419
420# Check for SWIG
421if not env.has_key('SWIG'):
422 print 'Error: SWIG utility not found.'
423 print ' Please install (see http://www.swig.org) and retry.'
424 Exit(1)
425
426# Check for appropriate SWIG version
391swig_version = read_command('swig -version').split()
427swig_version = read_command(('swig', '-version'), exception='').split()
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:

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

592#
593env = conf.Finish()
594
595######################################################################
596#
597# Collect all non-global variables
598#
599
428# First 3 words should be "SWIG Version x.y.z"
429if len(swig_version) < 3 or \
430 swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
431 print 'Error determining SWIG version.'
432 Exit(1)
433
434min_swig_version = '1.3.28'
435if compare_versions(swig_version[2], min_swig_version) < 0:

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

628#
629env = conf.Finish()
630
631######################################################################
632#
633# Collect all non-global variables
634#
635
636Export('env')
637
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')

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

703 return ([target], [Value(variable), Value(val)])
704
705config_builder = Builder(emitter = config_emitter, action = config_action)
706
707env.Append(BUILDERS = { 'ConfigFile' : config_builder })
708
709# libelf build is shared across all configs in the build root.
710env.SConscript('ext/libelf/SConscript',
638# Define the universe of supported ISAs
639all_isa_list = [ ]
640Export('all_isa_list')
641
642# Define the universe of supported CPU models
643all_cpu_list = [ ]
644default_cpus = [ ]
645Export('all_cpu_list', 'default_cpus')

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

741 return ([target], [Value(variable), Value(val)])
742
743config_builder = Builder(emitter = config_emitter, action = config_action)
744
745env.Append(BUILDERS = { 'ConfigFile' : config_builder })
746
747# libelf build is shared across all configs in the build root.
748env.SConscript('ext/libelf/SConscript',
711 variant_dir = joinpath(build_root, 'libelf'),
712 exports = 'env')
749 variant_dir = joinpath(build_root, 'libelf'))
713
714# gzstream build is shared across all configs in the build root.
715env.SConscript('ext/gzstream/SConscript',
750
751# gzstream build is shared across all configs in the build root.
752env.SConscript('ext/gzstream/SConscript',
716 variant_dir = joinpath(build_root, 'gzstream'),
717 exports = 'env')
753 variant_dir = joinpath(build_root, 'gzstream'))
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

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

854
855 # Set up the regression tests for each build.
856 for e in envList:
857 SConscript('tests/SConscript',
858 variant_dir = joinpath(variant_path, 'tests', e.Label),
859 exports = { 'env' : e }, duplicate = False)
860
861Help(help_text)
754
755###################################################
756#
757# This function is used to set up a directory with switching headers
758#
759###################################################
760
761env['ALL_ISA_LIST'] = all_isa_list

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

890
891 # Set up the regression tests for each build.
892 for e in envList:
893 SConscript('tests/SConscript',
894 variant_dir = joinpath(variant_path, 'tests', e.Label),
895 exports = { 'env' : e }, duplicate = False)
896
897Help(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