# -*- mode:python -*-
-# Copyright (c) 2013, 2015-2019 ARM Limited
+# Copyright (c) 2013, 2015-2020 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Authors: Steve Reinhardt
-# Nathan Binkert
###################################################
#
#
# While in this directory ('gem5'), just type 'scons' to build the default
# configuration (see below), or type 'scons build/<CONFIG>/<binary>'
-# to build some other configuration (e.g., 'build/ALPHA/gem5.opt' for
+# to build some other configuration (e.g., 'build/X86/gem5.opt' for
# the optimized full-system version).
#
# You can build gem5 in a different directory as long as there is a
#
# The following two commands are equivalent. The '-u' option tells
# scons to search up the directory tree for this SConstruct file.
-# % cd <path-to-src>/gem5 ; scons build/ALPHA/gem5.debug
-# % cd <path-to-src>/gem5/build/ALPHA; scons -u gem5.debug
+# % cd <path-to-src>/gem5 ; scons build/X86/gem5.debug
+# % cd <path-to-src>/gem5/build/X86; scons -u gem5.debug
#
# The following two commands are equivalent and demonstrate building
# in a directory outside of the source tree. The '-C' option tells
# scons to chdir to the specified directory to find this SConstruct
# file.
-# % cd <path-to-src>/gem5 ; scons /local/foo/build/ALPHA/gem5.debug
-# % cd /local/foo/build/ALPHA; scons -C <path-to-src>/gem5 gem5.debug
+# % cd <path-to-src>/gem5 ; scons /local/foo/build/X86/gem5.debug
+# % cd /local/foo/build/X86; scons -C <path-to-src>/gem5 gem5.debug
#
# You can use 'scons -H' to print scons options. If you're in this
# 'gem5' directory (or use -u or -C to tell scons where to find this
from __future__ import print_function
# Global Python includes
+import atexit
import itertools
import os
import re
help='Build with Undefined Behavior Sanitizer if available')
AddLocalOption('--with-asan', dest='with_asan', action='store_true',
help='Build with Address Sanitizer if available')
+AddLocalOption('--with-systemc-tests', dest='with_systemc_tests',
+ action='store_true', help='Build systemc tests')
-from gem5_scons import Transform, error, warning
+from gem5_scons import Transform, error, warning, summarize_warnings
if GetOption('no_lto') and GetOption('force_lto'):
error('--no-lto and --force-lto are mutually exclusive')
###################################################
# Find default configuration & binary.
-Default(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA/gem5.debug'))
+Default(environ.get('M5_DEFAULT_BINARY', 'build/ARM/gem5.debug'))
# helper function: find last occurrence of element in list
def rfind(l, elt, offs = -1):
for i in range(len(l)+offs, 0, -1):
if l[i] == elt:
return i
- raise ValueError, "element not found"
+ raise ValueError("element not found")
# Take a list of paths (or SCons Nodes) and return a list with all
# paths made absolute and ~-expanded. Paths will be interpreted
return [abspath(joinpath(root, expanduser(str(p))))
for p in path_list]
-def find_first_prog(prog_names):
- """Find the absolute path to the first existing binary in prog_names"""
-
- if not isinstance(prog_names, (list, tuple)):
- prog_names = [ prog_names ]
-
- for p in prog_names:
- p = main.WhereIs(p)
- if p is not None:
- return p
-
- return None
-
# Each target must have 'build' in the interior of the path; the
# directory below this will determine the build parameters. For
-# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we
-# recognize that ALPHA_SE specifies the configuration because it
+# example, for target 'foo/bar/build/X86/arch/x86/blah.do' we
+# recognize that X86 specifies the configuration because it
# follow 'build' in the build path.
# The funky assignment to "[:]" is needed to replace the list contents
#
# Set up global sticky variables... these are common to an entire build
-# tree (not specific to a particular build like ALPHA_SE)
+# tree (not specific to a particular build like X86)
#
global_vars_file = joinpath(build_root, 'variables.global')
main.Append(CCFLAGS=['-I/usr/local/include'])
main.Append(CXXFLAGS=['-I/usr/local/include'])
+ # On Mac OS X/Darwin the default linker doesn't support the
+ # option --as-needed
+ if sys.platform != "darwin":
+ main.Append(LINKFLAGS='-Wl,--as-needed')
main['FILTER_PSHLINKFLAGS'] = lambda x: str(x).replace(' -shared', '')
main['PSHLINKFLAGS'] = main.subst('${FILTER_PSHLINKFLAGS(SHLINKFLAGS)}')
if GetOption('gold_linker'):
main.Append(LINKFLAGS='-fuse-ld=gold')
- main['PLINKFLAGS'] = main.subst('${LINKFLAGS}')
+ main['PLINKFLAGS'] = main.get('LINKFLAGS')
shared_partial_flags = ['-r', '-nostdlib']
main.Append(PSHLINKFLAGS=shared_partial_flags)
main.Append(PLINKFLAGS=shared_partial_flags)
'-Wno-error=deprecated',
])
else:
- error('\n'.join(
+ error('\n'.join((
"Don't know what compiler options to use for your compiler.",
"compiler: " + main['CXX'],
"version: " + CXX_version.replace('\n', '<nl>') if
"",
"If you are trying to use a compiler other than those listed",
"above you will need to ease fix SConstruct and ",
- "src/SConscript to support that compiler."))
+ "src/SConscript to support that compiler.")))
if main['GCC']:
# Check for a supported version of gcc. >= 4.8 is chosen for its
main['GCC_VERSION'] = gcc_version
- if compareVersions(gcc_version, '4.9') >= 0:
+ if compareVersions(gcc_version, '4.9') >= 0 and \
+ compareVersions(gcc_version, '8.1') < 0:
# Incremental linking with LTO is currently broken in gcc versions
- # 4.9 and above. A version where everything works completely hasn't
- # yet been identified.
+ # 4.9 to 8.1.
#
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67548
- main['BROKEN_INCREMENTAL_LTO'] = True
- if compareVersions(gcc_version, '6.0') >= 0:
+ #
# gcc versions 6.0 and greater accept an -flinker-output flag which
# selects what type of output the linker should generate. This is
# necessary for incremental lto to work, but is also broken in
- # current versions of gcc. It may not be necessary in future
- # versions. We add it here since it might be, and as a reminder that
- # it exists. It's excluded if lto is being forced.
+ # versions of gcc up to 8.1.
#
# https://gcc.gnu.org/gcc-6/changes.html
# https://gcc.gnu.org/ml/gcc-patches/2015-11/msg03161.html
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69866
- if not GetOption('force_lto'):
- main.Append(PSHLINKFLAGS='-flinker-output=rel')
- main.Append(PLINKFLAGS='-flinker-output=rel')
-
- # Make sure we warn if the user has requested to compile with the
- # Undefined Benahvior Sanitizer and this version of gcc does not
- # support it.
- if GetOption('with_ubsan') and compareVersions(gcc_version, '4.9') < 0:
- warning('UBSan is only supported using gcc 4.9 and later.')
+ main['BROKEN_INCREMENTAL_LTO'] = True
disable_lto = GetOption('no_lto')
if not disable_lto and main.get('BROKEN_INCREMENTAL_LTO', False) and \
not GetOption('force_lto'):
- warning('Warning: Your compiler doesn\'t support incremental linking '
- 'and lto at the same time, so lto is being disabled. To force '
- 'lto on anyway, use the --force-lto option. That will disable '
+ warning('Your compiler doesn\'t support incremental linking and lto '
+ 'at the same time, so lto is being disabled. To force lto on '
+ 'anyway, use the --force-lto option. That will disable '
'partial linking.')
disable_lto = True
main.Append(TCMALLOC_CCFLAGS=['-fno-builtin-malloc', '-fno-builtin-calloc',
'-fno-builtin-realloc', '-fno-builtin-free'])
- # The address sanitizer is available for gcc >= 4.8
- if GetOption('with_asan'):
- if GetOption('with_ubsan') and \
- compareVersions(main['GCC_VERSION'], '4.9') >= 0:
- main.Append(CCFLAGS=['-fsanitize=address,undefined',
- '-fno-omit-frame-pointer'],
- LINKFLAGS='-fsanitize=address,undefined')
- else:
- main.Append(CCFLAGS=['-fsanitize=address',
- '-fno-omit-frame-pointer'],
- LINKFLAGS='-fsanitize=address')
- # Only gcc >= 4.9 supports UBSan, so check both the version
- # and the command-line option before adding the compiler and
- # linker flags.
- elif GetOption('with_ubsan') and \
- compareVersions(main['GCC_VERSION'], '4.9') >= 0:
- main.Append(CCFLAGS='-fsanitize=undefined')
- main.Append(LINKFLAGS='-fsanitize=undefined')
-
elif main['CLANG']:
# Check for a supported version of clang, >= 3.1 is needed to
# support similar features as gcc 4.8. See
if sys.platform.startswith('freebsd'):
main.Append(LIBS=['thr'])
- # We require clang >= 3.1, so there is no need to check any
- # versions here.
- if GetOption('with_ubsan'):
- if GetOption('with_asan'):
- main.Append(CCFLAGS=['-fsanitize=address,undefined',
- '-fno-omit-frame-pointer'],
- LINKFLAGS='-fsanitize=address,undefined')
- else:
- main.Append(CCFLAGS='-fsanitize=undefined',
- LINKFLAGS='-fsanitize=undefined')
-
- elif GetOption('with_asan'):
- main.Append(CCFLAGS=['-fsanitize=address',
+# Add sanitizers flags
+sanitizers=[]
+if GetOption('with_ubsan'):
+ # Only gcc >= 4.9 supports UBSan, so check both the version
+ # and the command-line option before adding the compiler and
+ # linker flags.
+ if not main['GCC'] or compareVersions(main['GCC_VERSION'], '4.9') >= 0:
+ sanitizers.append('undefined')
+if GetOption('with_asan'):
+ # Available for gcc >= 4.8 or llvm >= 3.1 both a requirement
+ # by the build system
+ sanitizers.append('address')
+ suppressions_file = Dir('util').File('lsan-suppressions').get_abspath()
+ suppressions_opt = 'suppressions=%s' % suppressions_file
+ main['ENV']['LSAN_OPTIONS'] = ':'.join([suppressions_opt,
+ 'print_suppressions=0'])
+ print()
+ warning('To suppress false positive leaks, set the LSAN_OPTIONS '
+ 'environment variable to "%s" when running gem5' %
+ suppressions_opt)
+ warning('LSAN_OPTIONS=suppressions=%s' % suppressions_opt)
+ print()
+if sanitizers:
+ sanitizers = ','.join(sanitizers)
+ if main['GCC'] or main['CLANG']:
+ main.Append(CCFLAGS=['-fsanitize=%s' % sanitizers,
'-fno-omit-frame-pointer'],
- LINKFLAGS='-fsanitize=address')
+ LINKFLAGS='-fsanitize=%s' % sanitizers)
+ else:
+ warning("Don't know how to enable %s sanitizer(s) for your "
+ "compiler." % sanitizers)
# Set up common yacc/bison flags (needed for Ruby)
main['YACCFLAGS'] = '-d'
# version of python, see above for instructions on how to invoke
# scons with the appropriate PATH set.
- python_config = find_first_prog(main['PYTHON_CONFIG'])
+ python_config = main.Detect(main['PYTHON_CONFIG'])
if python_config is None:
error("Can't find a suitable python-config, tried %s" % \
main['PYTHON_CONFIG'])
print("Info: Using Python config: %s" % (python_config, ))
py_includes = readCommand([python_config, '--includes'],
exception='').split()
- py_includes = filter(lambda s: match(r'.*\/include\/.*',s), py_includes)
+ py_includes = list(filter(
+ lambda s: match(r'.*\/include\/.*',s), py_includes))
# Strip the -I from the include folders before adding them to the
# CPPPATH
- py_includes = map(lambda s: s[2:] if s.startswith('-I') else s, py_includes)
+ py_includes = list(map(
+ lambda s: s[2:] if s.startswith('-I') else s, py_includes))
main.Append(CPPPATH=py_includes)
# Read the linker flags and split them into libraries and other link
# verify that this stuff works
if not conf.CheckHeader('Python.h', '<>'):
- error("Check failed for Python.h header in", py_includes, "\n"
+ error("Check failed for Python.h header in",
+ ' '.join(py_includes), "\n"
"Two possible reasons:\n"
"1. Python headers are not installed (You can install the "
"package python-dev on Ubuntu and RedHat)\n"
# Add self to dict
if name in CpuModel.dict:
- raise AttributeError, "CpuModel '%s' already registered" % name
+ raise AttributeError("CpuModel '%s' already registered" % name)
CpuModel.dict[name] = self
Export('CpuModel')
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(n for n,m in CpuModel.dict.items() if m.default),
sorted(CpuModel.dict.keys())),
BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger',
False),
- BoolVariable('SS_COMPATIBLE_FP',
- 'Make floating-point results compatible with SimpleScalar',
- False),
BoolVariable('USE_SSE2',
'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
False),
)
# These variables get exported to #defines in config/*.hh (see src/SConscript).
-export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'TARGET_GPU_ISA',
- 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'USE_TUNTAP',
- 'PROTOCOL', 'HAVE_PROTOBUF', 'HAVE_VALGRIND',
+export_vars += ['USE_FENV', 'TARGET_ISA', 'TARGET_GPU_ISA', 'CP_ANNOTATE',
+ 'USE_POSIX_CLOCK', 'USE_KVM', 'USE_TUNTAP', 'PROTOCOL',
+ 'HAVE_PROTOBUF', 'HAVE_VALGRIND',
'HAVE_PERF_ATTR_EXCLUDE_HOST', 'USE_PNG',
'NUMBER_BITS_PER_SET', 'USE_HDF5']
# operands are the name of the variable and a Value node containing the
# value of the variable.
def build_config_file(target, source, env):
- (variable, value) = [s.get_contents() for s in source]
- f = file(str(target[0]), 'w')
- print('#define', variable, value, file=f)
- f.close()
+ (variable, value) = [s.get_contents().decode('utf-8') for s in source]
+ with open(str(target[0]), 'w') as f:
+ print('#define', variable, value, file=f)
return None
# Combine the two functions into a scons Action object.
env['BUILDDIR'] = variant_path
# variant_dir is the tail component of build path, and is used to
- # determine the build parameters (e.g., 'ALPHA_SE')
+ # determine the build parameters (e.g., 'X86')
(build_root, variant_dir) = splitpath(variant_path)
# Set env variables according to the build directory config.
joinpath(opts_dir, default)]
else:
default_vars_files = [joinpath(opts_dir, variant_dir)]
- existing_files = filter(isfile, default_vars_files)
+ existing_files = list(filter(isfile, default_vars_files))
if existing_files:
default_vars_file = existing_files[0]
sticky_vars.files.append(default_vars_file)
%(local_vars)s
''' % help_texts)
+
+atexit.register(summarize_warnings)