scons: clean up the main SConstruct file more.
Add some features to read_command so it works a little bit better Clean up the mercurial checks. Filter the user environment and only pick out the useful stuff.
This commit is contained in:
parent
f255957b90
commit
312fbb1b48
1 changed files with 95 additions and 68 deletions
163
SConstruct
163
SConstruct
|
@ -1,5 +1,6 @@
|
|||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2009 The Hewlett-Packard Development Company
|
||||
# Copyright (c) 2004-2005 The Regents of The University of Michigan
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -106,12 +107,27 @@ from os.path import exists, isdir, isfile
|
|||
from os.path import join as joinpath, split as splitpath
|
||||
|
||||
import SCons
|
||||
import SCons.Node
|
||||
|
||||
def read_command(cmd):
|
||||
def read_command(cmd, **kwargs):
|
||||
"""run the command cmd, read the results and return them
|
||||
this is sorta like `cmd` in shell"""
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
subp = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, close_fds=True)
|
||||
|
||||
no_exception = 'exception' in kwargs
|
||||
exception = kwargs.pop('exception', None)
|
||||
|
||||
kwargs.setdefault('shell', False)
|
||||
kwargs.setdefault('stdout', PIPE)
|
||||
kwargs.setdefault('stderr', STDOUT)
|
||||
kwargs.setdefault('close_fds', True)
|
||||
try:
|
||||
subp = Popen(cmd, **kwargs)
|
||||
except Exception, e:
|
||||
if no_exception:
|
||||
return exception
|
||||
raise
|
||||
|
||||
return subp.communicate()[0]
|
||||
|
||||
# helper function: compare arrays or strings of version numbers.
|
||||
|
@ -137,40 +153,34 @@ def compare_versions(v1, v2):
|
|||
if len(v1) > len(v2): return 1
|
||||
return 0
|
||||
|
||||
# The absolute path to the current directory (where this file lives).
|
||||
ROOT = Dir('.').abspath
|
||||
########################################################################
|
||||
#
|
||||
# Set up the base build environment.
|
||||
#
|
||||
########################################################################
|
||||
use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'PATH', 'RANLIB' ])
|
||||
|
||||
# Path to the M5 source tree.
|
||||
SRCDIR = joinpath(ROOT, 'src')
|
||||
use_env = {}
|
||||
for key,val in os.environ.iteritems():
|
||||
if key in use_vars or key.startswith("M5"):
|
||||
use_env[key] = val
|
||||
|
||||
# tell python where to find m5 python code
|
||||
sys.path.append(joinpath(ROOT, 'src/python'))
|
||||
env = Environment(ENV=use_env)
|
||||
env.root = Dir(".") # The current directory (where this file lives).
|
||||
env.srcdir = Dir("src") # The source directory
|
||||
|
||||
###################################################
|
||||
########################################################################
|
||||
#
|
||||
# Mercurial Stuff.
|
||||
# 1) Grab repository revision if we know it.
|
||||
# 2) Ensure that the style hook is in place.
|
||||
###################################################
|
||||
#
|
||||
# If the M5 directory is a mercurial repository, we should do some
|
||||
# extra things.
|
||||
#
|
||||
########################################################################
|
||||
|
||||
hg_info = "Unknown"
|
||||
try:
|
||||
if not exists(ROOT) or not isdir(ROOT) or \
|
||||
not exists(joinpath(ROOT, ".hg")):
|
||||
raise ValueError(".hg directory not found")
|
||||
hg_info = read_command("cd %s; hg id -n -i -t -b" % ROOT).strip()
|
||||
except ImportError, e:
|
||||
print "Mercurial not found"
|
||||
except ValueError, e:
|
||||
print e
|
||||
except Exception, e:
|
||||
print "Other mercurial exception: %s" % e
|
||||
hgdir = env.root.Dir(".hg")
|
||||
|
||||
def check_style_hook(ui):
|
||||
ui.readconfig(joinpath(ROOT, '.hg', 'hgrc'))
|
||||
style_hook = ui.config('hooks', 'pretxncommit.style', None)
|
||||
|
||||
if not style_hook:
|
||||
print """\
|
||||
mercurial_style_message = """
|
||||
You're missing the M5 style hook.
|
||||
Please install the hook so we can ensure that all code fits a common style.
|
||||
|
||||
|
@ -183,16 +193,50 @@ style = %s/util/style.py
|
|||
|
||||
[hooks]
|
||||
pretxncommit.style = python:style.check_whitespace
|
||||
""" % (ROOT)
|
||||
sys.exit(1)
|
||||
""" % (env.root)
|
||||
|
||||
if ARGUMENTS.get('IGNORE_STYLE') != 'True' and isdir(joinpath(ROOT, '.hg')):
|
||||
mercurial_bin_not_found = """
|
||||
Mercurial binary cannot be found, unfortunately this means that we
|
||||
cannot easily determine the version of M5 that you are running and
|
||||
this makes error messages more difficult to collect. Please consider
|
||||
installing mercurial if you choose to post an error message
|
||||
"""
|
||||
|
||||
mercurial_lib_not_found = """
|
||||
Mercurial libraries cannot be found, ignoring style hook
|
||||
If you are actually a M5 developer, please fix this and
|
||||
run the style hook. It is important.
|
||||
"""
|
||||
|
||||
if hgdir.exists():
|
||||
# 1) Grab repository revision if we know it.
|
||||
cmd = "hg id -n -i -t -b"
|
||||
try:
|
||||
from mercurial import ui
|
||||
check_style_hook(ui.ui())
|
||||
except ImportError:
|
||||
pass
|
||||
hg_info = read_command(cmd, cwd=env.root.abspath).strip()
|
||||
except OSError:
|
||||
hg_info = "Unknown"
|
||||
print mercurial_bin_not_found
|
||||
|
||||
env['HG_INFO'] = hg_info
|
||||
|
||||
# 2) Ensure that the style hook is in place.
|
||||
try:
|
||||
ui = None
|
||||
if ARGUMENTS.get('IGNORE_STYLE') != 'True':
|
||||
from mercurial import ui
|
||||
ui = ui.ui()
|
||||
except ImportError:
|
||||
print mercurial_lib_not_found
|
||||
|
||||
if ui is not None:
|
||||
ui.readconfig(hgdir.File('hgrc').abspath)
|
||||
style_hook = ui.config('hooks', 'pretxncommit.style', None)
|
||||
|
||||
if not style_hook:
|
||||
print mercurial_style_message
|
||||
sys.exit(1)
|
||||
else:
|
||||
print ".hg directory not found"
|
||||
|
||||
###################################################
|
||||
#
|
||||
|
@ -257,18 +301,6 @@ for t in abs_targets:
|
|||
if not isdir(build_root):
|
||||
mkdir(build_root)
|
||||
|
||||
###################################################
|
||||
#
|
||||
# Set up the default build environment. This environment is copied
|
||||
# and modified according to each selected configuration.
|
||||
#
|
||||
###################################################
|
||||
|
||||
env = Environment(ENV = environ, # inherit user's environment vars
|
||||
ROOT = ROOT,
|
||||
SRCDIR = SRCDIR,
|
||||
HG_INFO = hg_info)
|
||||
|
||||
Export('env')
|
||||
|
||||
env.SConsignFile(joinpath(build_root, "sconsign"))
|
||||
|
@ -329,7 +361,7 @@ global_sticky_vars.Save(global_sticky_vars_file, env)
|
|||
|
||||
# Parse EXTRAS variable to build list of all directories where we're
|
||||
# look for sources etc. This list is exported as base_dir_list.
|
||||
base_dir = joinpath(ROOT, 'src')
|
||||
base_dir = env.srcdir.abspath
|
||||
if env['EXTRAS']:
|
||||
extras_dir_list = env['EXTRAS'].split(':')
|
||||
else:
|
||||
|
@ -340,9 +372,13 @@ Export('extras_dir_list')
|
|||
|
||||
# M5_PLY is used by isa_parser.py to find the PLY package.
|
||||
env.Append(ENV = { 'M5_PLY' : str(Dir('ext/ply')) })
|
||||
env['GCC'] = read_command(env['CXX'] + ' --version').find('g++') >= 0
|
||||
env['SUNCC'] = read_command(env['CXX'] + ' -V').find('Sun C++') >= 0
|
||||
env['ICC'] = read_command(env['CXX'] + ' -V').find('Intel') >= 0
|
||||
|
||||
CXX_version = read_command([env['CXX'],'--version'], exception=False)
|
||||
CXX_V = read_command([env['CXX'],'-V'], exception=False)
|
||||
|
||||
env['GCC'] = CXX_version and CXX_version.find('g++') >= 0
|
||||
env['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
|
||||
env['ICC'] = CXX_V and CXX_V.find('Intel') >= 0
|
||||
if env['GCC'] + env['SUNCC'] + env['ICC'] > 1:
|
||||
print 'Error: How can we have two at the same time?'
|
||||
Exit(1)
|
||||
|
@ -361,7 +397,7 @@ elif env['SUNCC']:
|
|||
env.Append(CCFLAGS='-features=extensions')
|
||||
env.Append(CCFLAGS='-library=stlport4')
|
||||
env.Append(CCFLAGS='-xar')
|
||||
# env.Append(CCFLAGS='-instances=semiexplicit')
|
||||
#env.Append(CCFLAGS='-instances=semiexplicit')
|
||||
else:
|
||||
print 'Error: Don\'t know what compiler options to use for your compiler.'
|
||||
print ' Please fix SConstruct and src/SConscript and try again.'
|
||||
|
@ -388,7 +424,7 @@ if not env.has_key('SWIG'):
|
|||
Exit(1)
|
||||
|
||||
# Check for appropriate SWIG version
|
||||
swig_version = read_command('swig -version').split()
|
||||
swig_version = read_command(('swig', '-version'), exception='').split()
|
||||
# First 3 words should be "SWIG Version x.y.z"
|
||||
if len(swig_version) < 3 or \
|
||||
swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
|
||||
|
@ -597,6 +633,8 @@ env = conf.Finish()
|
|||
# Collect all non-global variables
|
||||
#
|
||||
|
||||
Export('env')
|
||||
|
||||
# Define the universe of supported ISAs
|
||||
all_isa_list = [ ]
|
||||
Export('all_isa_list')
|
||||
|
@ -708,13 +746,11 @@ env.Append(BUILDERS = { 'ConfigFile' : config_builder })
|
|||
|
||||
# libelf build is shared across all configs in the build root.
|
||||
env.SConscript('ext/libelf/SConscript',
|
||||
variant_dir = joinpath(build_root, 'libelf'),
|
||||
exports = 'env')
|
||||
variant_dir = joinpath(build_root, 'libelf'))
|
||||
|
||||
# gzstream build is shared across all configs in the build root.
|
||||
env.SConscript('ext/gzstream/SConscript',
|
||||
variant_dir = joinpath(build_root, 'gzstream'),
|
||||
exports = 'env')
|
||||
variant_dir = joinpath(build_root, 'gzstream'))
|
||||
|
||||
###################################################
|
||||
#
|
||||
|
@ -859,12 +895,3 @@ for variant_path in variant_paths:
|
|||
exports = { 'env' : e }, duplicate = False)
|
||||
|
||||
Help(help_text)
|
||||
|
||||
|
||||
###################################################
|
||||
#
|
||||
# Let SCons do its thing. At this point SCons will use the defined
|
||||
# build environments to build the requested targets.
|
||||
#
|
||||
###################################################
|
||||
|
||||
|
|
Loading…
Reference in a new issue