# -*- mode:python -*-
+# Copyright (c) 2009 The Hewlett-Packard Development Company
# Copyright (c) 2004-2005 The Regents of The University of Michigan
# All rights reserved.
#
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.
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
-
-def check_style_hook(ui):
- ui.readconfig(joinpath(ROOT, '.hg', 'hgrc'))
- style_hook = ui.config('hooks', 'pretxncommit.style', None)
-
- if not style_hook:
- print """\
+hgdir = env.root.Dir(".hg")
+
+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.
[hooks]
pretxncommit.style = python:style.check_whitespace
-""" % (ROOT)
- sys.exit(1)
+""" % (env.root)
+
+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:
+ 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
-if ARGUMENTS.get('IGNORE_STYLE') != 'True' and isdir(joinpath(ROOT, '.hg')):
+ # 2) Ensure that the style hook is in place.
try:
- from mercurial import ui
- check_style_hook(ui.ui())
+ ui = None
+ if ARGUMENTS.get('IGNORE_STYLE') != 'True':
+ from mercurial import ui
+ ui = ui.ui()
except ImportError:
- pass
+ 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"
###################################################
#
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"))
# 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:
# 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)
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.'
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':
# Collect all non-global variables
#
+Export('env')
+
# Define the universe of supported ISAs
all_isa_list = [ ]
Export('all_isa_list')
# 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'))
###################################################
#
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.
-#
-###################################################
-