# -*- mode:python -*-
-# Copyright (c) 2013 ARM Limited
+# Copyright (c) 2013, 2015 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
'PYTHONPATH', 'RANLIB', 'SWIG', 'TERM' ])
use_prefixes = [
- "M5", # M5 configuration (e.g., path to kernels)
- "DISTCC_", # distcc (distributed compiler wrapper) configuration
- "CCACHE_", # ccache (caching compiler wrapper) configuration
- "CCC_", # clang static analyzer configuration
+ "CCACHE_", # ccache (caching compiler wrapper) configuration
+ "CCC_", # clang static analyzer configuration
+ "DISTCC_", # distcc (distributed compiler wrapper) configuration
+ "INCLUDE_SERVER_", # distcc pump server settings
+ "M5", # M5 configuration (e.g., path to kernels)
]
use_env = {}
any([key.startswith(prefix) for prefix in use_prefixes]):
use_env[key] = val
-main = Environment(ENV=use_env)
+# Tell scons to avoid implicit command dependencies to avoid issues
+# with the param wrappes being compiled twice (see
+# http://scons.tigris.org/issues/show_bug.cgi?id=2811)
+main = Environment(ENV=use_env, IMPLICIT_COMMAND_DEPENDENCIES=0)
main.Decider('MD5-timestamp')
main.root = Dir(".") # The current directory (where this file lives).
main.srcdir = Dir("src") # The source directory
# As gcc and clang share many flags, do the common parts here
main.Append(CCFLAGS=['-pipe'])
main.Append(CCFLAGS=['-fno-strict-aliasing'])
- # Enable -Wall and then disable the few warnings that we
- # consistently violate
- main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
- # We always compile using C++11, but only gcc >= 4.7 and clang 3.1
- # actually use that name, so we stick with c++0x
- main.Append(CXXFLAGS=['-std=c++0x'])
- # Add selected sanity checks from -Wextra
- main.Append(CXXFLAGS=['-Wmissing-field-initializers',
- '-Woverloaded-virtual'])
+ # Enable -Wall and -Wextra and then disable the few warnings that
+ # we consistently violate
+ main.Append(CCFLAGS=['-Wall', '-Wundef', '-Wextra',
+ '-Wno-sign-compare', '-Wno-unused-parameter'])
+ # We always compile using C++11
+ main.Append(CXXFLAGS=['-std=c++11'])
else:
print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal,
print "Don't know what compiler options to use for your compiler."
Exit(1)
if main['GCC']:
- # Check for a supported version of gcc. >= 4.6 is chosen for its
+ # Check for a supported version of gcc. >= 4.7 is chosen for its
# level of c++11 support. See
- # http://gcc.gnu.org/projects/cxx0x.html for details. 4.6 is also
- # the first version with proper LTO support.
+ # http://gcc.gnu.org/projects/cxx0x.html for details.
gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False)
- if compareVersions(gcc_version, "4.6") < 0:
- print 'Error: gcc version 4.6 or newer required.'
+ if compareVersions(gcc_version, "4.7") < 0:
+ print 'Error: gcc version 4.7 or newer required.'
print ' Installed version:', gcc_version
Exit(1)
# assemblers detect this as an error, "Error: expecting string
# instruction after `rep'"
if compareVersions(gcc_version, "4.8") > 0:
- as_version = readCommand([main['AS'], '-v', '/dev/null'],
- exception=False).split()
+ as_version_raw = readCommand([main['AS'], '-v', '/dev/null'],
+ exception=False).split()
- if not as_version or compareVersions(as_version[-1], "2.23") < 0:
+ # version strings may contain extra distro-specific
+ # qualifiers, so play it safe and keep only what comes before
+ # the first hyphen
+ as_version = as_version_raw[-1].split('-')[0] if as_version_raw \
+ else None
+
+ if not as_version or compareVersions(as_version, "2.23") < 0:
print termcap.Yellow + termcap.Bold + \
'Warning: This combination of gcc and binutils have' + \
' known incompatibilities.\n' + \
'-fno-builtin-realloc', '-fno-builtin-free'])
elif main['CLANG']:
- # Check for a supported version of clang, >= 3.0 is needed to
- # support similar features as gcc 4.6. See
+ # Check for a supported version of clang, >= 3.1 is needed to
+ # support similar features as gcc 4.7. See
# http://clang.llvm.org/cxx_status.html for details
clang_version_re = re.compile(".* version (\d+\.\d+)")
clang_version_match = clang_version_re.search(CXX_version)
if (clang_version_match):
clang_version = clang_version_match.groups()[0]
- if compareVersions(clang_version, "3.0") < 0:
- print 'Error: clang version 3.0 or newer required.'
+ if compareVersions(clang_version, "3.1") < 0:
+ print 'Error: clang version 3.1 or newer required.'
print ' Installed version:', clang_version
Exit(1)
else:
print 'Error: Unable to determine clang version.'
Exit(1)
- # clang has a few additional warnings that we disable,
- # tautological comparisons are allowed due to unsigned integers
- # being compared to constants that happen to be 0, and extraneous
+ # clang has a few additional warnings that we disable, extraneous
# parantheses are allowed due to Ruby's printing of the AST,
# finally self assignments are allowed as the generated CPU code
# is relying on this
- main.Append(CCFLAGS=['-Wno-tautological-compare',
- '-Wno-parentheses',
+ main.Append(CCFLAGS=['-Wno-parentheses',
'-Wno-self-assign',
# Some versions of libstdc++ (4.8?) seem to
# use struct hash and class hash
swig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS')
main.Append(SWIGFLAGS=swig_flags)
-# Check for 'timeout' from GNU coreutils. If present, regressions
-# will be run with a time limit.
-TIMEOUT_version = readCommand(['timeout', '--version'], exception=False)
-main['TIMEOUT'] = TIMEOUT_version and TIMEOUT_version.find('timeout') == 0
+# Check for 'timeout' from GNU coreutils. If present, regressions will
+# be run with a time limit. We require version 8.13 since we rely on
+# support for the '--foreground' option.
+timeout_lines = readCommand(['timeout', '--version'],
+ exception='').splitlines()
+# Get the first line and tokenize it
+timeout_version = timeout_lines[0].split() if timeout_lines else []
+main['TIMEOUT'] = timeout_version and \
+ compareVersions(timeout_version[-1], '8.13') >= 0
# filter out all existing swig scanners, they mess up the dependency
# stuff for some reason
# replace the scanners list that has what we want
main['SCANNERS'] = scanners
-# Add a custom Check function to the Configure context so that we can
-# figure out if the compiler adds leading underscores to global
-# variables. This is needed for the autogenerated asm files that we
-# use for embedding the python code.
-def CheckLeading(context):
- context.Message("Checking for leading underscore in global variables...")
- # 1) Define a global variable called x from asm so the C compiler
- # won't change the symbol at all.
- # 2) Declare that variable.
- # 3) Use the variable
- #
- # If the compiler prepends an underscore, this will successfully
- # link because the external symbol 'x' will be called '_x' which
- # was defined by the asm statement. If the compiler does not
- # prepend an underscore, this will not successfully link because
- # '_x' will have been defined by assembly, while the C portion of
- # the code will be trying to use 'x'
- ret = context.TryLink('''
- asm(".globl _x; _x: .byte 0");
- extern int x;
- int main() { return x; }
- ''', extension=".c")
- context.env.Append(LEADING_UNDERSCORE=ret)
- context.Result(ret)
- return ret
-
# Add a custom Check function to test for structure members.
def CheckMember(context, include, decl, member, include_quotes="<>"):
context.Message("Checking for member %s in %s..." %
conf_dir = joinpath(build_root, '.scons_config'),
log_file = joinpath(build_root, 'scons_config.log'),
custom_tests = {
- 'CheckLeading' : CheckLeading,
'CheckMember' : CheckMember,
})
-# Check for leading underscores. Don't really need to worry either
-# way so don't need to check the return code.
-conf.CheckLeading()
-
# Check if we should compile a 64 bit binary on Mac OS X/Darwin
try:
import platform
"installing tcmalloc (libgoogle-perftools-dev package "\
"on Ubuntu or RedHat)." + termcap.Normal
+
+# Detect back trace implementations. The last implementation in the
+# list will be used by default.
+backtrace_impls = [ "none" ]
+
+if conf.CheckLibWithHeader(None, 'execinfo.h', 'C',
+ 'backtrace_symbols_fd((void*)0, 0, 0);'):
+ backtrace_impls.append("glibc")
+
+if backtrace_impls[-1] == "none":
+ default_backtrace_impl = "none"
+ print termcap.Yellow + termcap.Bold + \
+ "No suitable back trace implementation found." + \
+ termcap.Normal
+
if not have_posix_clock:
print "Can't find library for POSIX clocks."
# we rely on exists since version 2.6.36 of the kernel, but somehow
# the KVM_API_VERSION does not reflect the change. We test for one of
# the types as a fall back.
-have_kvm = conf.CheckHeader('linux/kvm.h', '<>') and \
- conf.CheckTypeSize('struct kvm_xsave', '#include <linux/kvm.h>') != 0
+have_kvm = conf.CheckHeader('linux/kvm.h', '<>')
if not have_kvm:
print "Info: Compatible header file <linux/kvm.h> not found, " \
"disabling KVM support."
+# x86 needs support for xsave. We test for the structure here since we
+# won't be able to run new tests by the time we know which ISA we're
+# targeting.
+have_kvm_xsave = conf.CheckTypeSize('struct kvm_xsave',
+ '#include <linux/kvm.h>') != 0
+
# Check if the requested target ISA is compatible with the host
def is_isa_kvm_compatible(isa):
- isa_comp_table = {
- "arm" : ( "armv7l" ),
- "x86" : ( "x86_64" ),
- }
try:
import platform
host_isa = platform.machine()
print "Warning: Failed to determine host ISA."
return False
- return host_isa in isa_comp_table.get(isa, [])
+ if not have_posix_timers:
+ print "Warning: Can not enable KVM, host seems to lack support " \
+ "for POSIX timers"
+ return False
+
+ if isa == "arm":
+ return host_isa in ( "armv7l", "aarch64" )
+ elif isa == "x86":
+ if host_isa != "x86_64":
+ return False
+
+ if not have_kvm_xsave:
+ print "KVM on x86 requires xsave support in kernel headers."
+ return False
+
+ return True
+ else:
+ return False
# Check if the exclude_host attribute is available. We want this to
# Define the universe of supported ISAs
all_isa_list = [ ]
+all_gpu_isa_list = [ ]
Export('all_isa_list')
+Export('all_gpu_isa_list')
class CpuModel(object):
'''The CpuModel class encapsulates everything the ISA parser needs to
SConscript(joinpath(root, 'SConsopts'))
all_isa_list.sort()
+all_gpu_isa_list.sort()
sticky_vars.AddVariables(
EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
+ EnumVariable('TARGET_GPU_ISA', 'Target GPU ISA', 'hsail', all_gpu_isa_list),
ListVariable('CPU_MODELS', 'CPU models',
sorted(n for n,m in CpuModel.dict.iteritems() if m.default),
sorted(CpuModel.dict.keys())),
BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
BoolVariable('USE_KVM', 'Enable hardware virtualized (KVM) CPU models', have_kvm),
+ BoolVariable('BUILD_GPU', 'Build the compute-GPU model', False),
EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None',
all_protocols),
+ EnumVariable('BACKTRACE_IMPL', 'Post-mortem dump implementation',
+ backtrace_impls[-1], backtrace_impls)
)
# These variables get exported to #defines in config/*.hh (see src/SConscript).
-export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'CP_ANNOTATE',
- 'USE_POSIX_CLOCK', 'USE_KVM', 'PROTOCOL', 'HAVE_PROTOBUF',
- 'HAVE_PERF_ATTR_EXCLUDE_HOST']
+export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'TARGET_GPU_ISA',
+ 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'PROTOCOL',
+ 'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST']
###################################################
#
main.SConscript('ext/libelf/SConscript',
variant_dir = joinpath(build_root, 'libelf'))
-# gzstream build is shared across all configs in the build root.
-main.SConscript('ext/gzstream/SConscript',
- variant_dir = joinpath(build_root, 'gzstream'))
+# iostream3 build is shared across all configs in the build root.
+main.SConscript('ext/iostream3/SConscript',
+ variant_dir = joinpath(build_root, 'iostream3'))
# libfdt build is shared across all configs in the build root.
main.SConscript('ext/libfdt/SConscript',
main.SConscript('ext/drampower/SConscript',
variant_dir = joinpath(build_root, 'drampower'))
+# nomali build is shared across all configs in the build root.
+main.SConscript('ext/nomali/SConscript',
+ variant_dir = joinpath(build_root, 'nomali'))
+
###################################################
#
# This function is used to set up a directory with switching headers
###################################################
main['ALL_ISA_LIST'] = all_isa_list
+main['ALL_GPU_ISA_LIST'] = all_gpu_isa_list
all_isa_deps = {}
def make_switching_dir(dname, switch_headers, env):
# Generate the header. target[0] is the full path of the output
Export('make_switching_dir')
+def make_gpu_switching_dir(dname, switch_headers, env):
+ # Generate the header. target[0] is the full path of the output
+ # header to generate. 'source' is a dummy variable, since we get the
+ # list of ISAs from env['ALL_ISA_LIST'].
+ def gen_switch_hdr(target, source, env):
+ fname = str(target[0])
+
+ isa = env['TARGET_GPU_ISA'].lower()
+
+ try:
+ f = open(fname, 'w')
+ print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname))
+ f.close()
+ except IOError:
+ print "Failed to create %s" % fname
+ raise
+
+ # Build SCons Action object. 'varlist' specifies env vars that this
+ # action depends on; when env['ALL_ISA_LIST'] changes these actions
+ # should get re-executed.
+ switch_hdr_action = MakeAction(gen_switch_hdr,
+ Transform("GENERATE"), varlist=['ALL_ISA_GPU_LIST'])
+
+ # Instantiate actions for each header
+ for hdr in switch_headers:
+ env.Command(hdr, [], switch_hdr_action)
+
+Export('make_gpu_switching_dir')
+
# all-isas -> all-deps -> all-environs -> all_targets
main.Alias('#all-isas', [])
main.Alias('#all-deps', '#all-isas')
if not have_kvm:
print "Warning: Can not enable KVM, host seems to lack KVM support"
env['USE_KVM'] = False
- elif not have_posix_timers:
- print "Warning: Can not enable KVM, host seems to lack support " \
- "for POSIX timers"
- env['USE_KVM'] = False
elif not is_isa_kvm_compatible(env['TARGET_ISA']):
print "Info: KVM support disabled due to unsupported host and " \
"target ISA combination"