arch-arm: Add recursion for DTB entry generation inside ArmISA
[gem5.git] / SConstruct
index eb6b089848452e0cd00cc5ac067a70a911f76c8a..8e7ec3481ec138eeff17b86f91ecce4e466c6a4d 100755 (executable)
@@ -78,6 +78,7 @@
 from __future__ import print_function
 
 # Global Python includes
+import atexit
 import itertools
 import os
 import re
@@ -96,79 +97,38 @@ import SCons
 import SCons.Node
 import SCons.Node.FS
 
-from m5.util import compareVersions, readCommand
-
-help_texts = {
-    "options" : "",
-    "global_vars" : "",
-    "local_vars" : ""
-}
-
-Export("help_texts")
-
-
-# There's a bug in scons in that (1) by default, the help texts from
-# AddOption() are supposed to be displayed when you type 'scons -h'
-# and (2) you can override the help displayed by 'scons -h' using the
-# Help() function, but these two features are incompatible: once
-# you've overridden the help text using Help(), there's no way to get
-# at the help texts from AddOptions.  See:
-#     http://scons.tigris.org/issues/show_bug.cgi?id=2356
-#     http://scons.tigris.org/issues/show_bug.cgi?id=2611
-# This hack lets us extract the help text from AddOptions and
-# re-inject it via Help().  Ideally someday this bug will be fixed and
-# we can just use AddOption directly.
-def AddLocalOption(*args, **kwargs):
-    col_width = 30
-
-    help = "  " + ", ".join(args)
-    if "help" in kwargs:
-        length = len(help)
-        if length >= col_width:
-            help += "\n" + " " * col_width
-        else:
-            help += " " * (col_width - length)
-        help += kwargs["help"]
-    help_texts["options"] += help + "\n"
-
-    AddOption(*args, **kwargs)
-
-AddLocalOption('--colors', dest='use_colors', action='store_true',
-               help="Add color to abbreviated scons output")
-AddLocalOption('--no-colors', dest='use_colors', action='store_false',
-               help="Don't add color to abbreviated scons output")
-AddLocalOption('--with-cxx-config', dest='with_cxx_config',
-               action='store_true',
-               help="Build with support for C++-based configuration")
-AddLocalOption('--default', dest='default', type='string', action='store',
-               help='Override which build_opts file to use for defaults')
-AddLocalOption('--ignore-style', dest='ignore_style', action='store_true',
-               help='Disable style checking hooks')
-AddLocalOption('--gold-linker', dest='gold_linker', action='store_true',
-               help='Use the gold linker')
-AddLocalOption('--no-lto', dest='no_lto', action='store_true',
-               help='Disable Link-Time Optimization for fast')
-AddLocalOption('--force-lto', dest='force_lto', action='store_true',
-               help='Use Link-Time Optimization instead of partial linking' +
-                    ' when the compiler doesn\'t support using them together.')
-AddLocalOption('--update-ref', dest='update_ref', action='store_true',
-               help='Update test reference outputs')
-AddLocalOption('--verbose', dest='verbose', action='store_true',
-               help='Print full tool command lines')
-AddLocalOption('--without-python', dest='without_python',
-               action='store_true',
-               help='Build without Python configuration support')
-AddLocalOption('--without-tcmalloc', dest='without_tcmalloc',
-               action='store_true',
-               help='Disable linking against tcmalloc')
-AddLocalOption('--with-ubsan', dest='with_ubsan', action='store_true',
-               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 m5.util import compareVersions, readCommand, readCommandWithReturn
+
+AddOption('--colors', dest='use_colors', action='store_true',
+          help="Add color to abbreviated scons output")
+AddOption('--no-colors', dest='use_colors', action='store_false',
+          help="Don't add color to abbreviated scons output")
+AddOption('--with-cxx-config', action='store_true',
+          help="Build with support for C++-based configuration")
+AddOption('--default',
+          help='Override which build_opts file to use for defaults')
+AddOption('--ignore-style', action='store_true',
+          help='Disable style checking hooks')
+AddOption('--gold-linker', action='store_true', help='Use the gold linker')
+AddOption('--no-lto', action='store_true',
+          help='Disable Link-Time Optimization for fast')
+AddOption('--force-lto', action='store_true',
+          help='Use Link-Time Optimization instead of partial linking' +
+               ' when the compiler doesn\'t support using them together.')
+AddOption('--verbose', action='store_true',
+          help='Print full tool command lines')
+AddOption('--without-python', action='store_true',
+          help='Build without Python configuration support')
+AddOption('--without-tcmalloc', action='store_true',
+          help='Disable linking against tcmalloc')
+AddOption('--with-ubsan', action='store_true',
+          help='Build with Undefined Behavior Sanitizer if available')
+AddOption('--with-asan', action='store_true',
+          help='Build with Address Sanitizer if available')
+AddOption('--with-systemc-tests', action='store_true',
+          help='Build systemc tests')
+
+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')
@@ -214,19 +174,6 @@ def makePathListAbsolute(path_list, root=GetLaunchDir()):
     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/X86/arch/x86/blah.do' we
@@ -288,8 +235,11 @@ global_vars.AddVariables(
     ('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])),
     ('CCFLAGS_EXTRA', 'Extra C and C++ compiler flags', ''),
     ('LDFLAGS_EXTRA', 'Extra linker flags', ''),
+    ('MARSHAL_CCFLAGS_EXTRA', 'Extra C and C++ marshal compiler flags', ''),
+    ('MARSHAL_LDFLAGS_EXTRA', 'Extra marshal linker flags', ''),
     ('PYTHON_CONFIG', 'Python config binary to use',
-     [ 'python2.7-config', 'python-config' ]),
+     [ 'python3-config', 'python-config', 'python2.7-config', 'python2-config']
+    ),
     ('PROTOC', 'protoc tool', environ.get('PROTOC', 'protoc')),
     ('BATCH', 'Use batch pool for build and tests', False),
     ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
@@ -299,7 +249,10 @@ global_vars.AddVariables(
 
 # Update main environment with values from ARGUMENTS & global_vars_file
 global_vars.Update(main)
-help_texts["global_vars"] += global_vars.GenerateHelpText(main)
+Help('''
+Global build variables:
+{help}
+'''.format(help=global_vars.GenerateHelpText(main)), append=True)
 
 # Save sticky variable settings back to current variables file
 global_vars.Save(global_vars_file, main)
@@ -365,13 +318,16 @@ if main['GCC'] or main['CLANG']:
     # 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'])
+    # We always compile using C++14
+    main.Append(CXXFLAGS=['-std=c++14'])
     if sys.platform.startswith('freebsd'):
         main.Append(CCFLAGS=['-I/usr/local/include'])
         main.Append(CXXFLAGS=['-I/usr/local/include'])
 
-    main.Append(LINKFLAGS='-Wl,--as-needed')
+    # 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'):
@@ -402,24 +358,21 @@ else:
           "src/SConscript to support that compiler.")))
 
 if main['GCC']:
-    # Check for a supported version of gcc. >= 4.8 is chosen for its
-    # level of c++11 support. See
-    # http://gcc.gnu.org/projects/cxx0x.html for details.
     gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False)
-    if compareVersions(gcc_version, "4.8") < 0:
-        error('gcc version 4.8 or newer required.\n'
+    if compareVersions(gcc_version, "5") < 0:
+        error('gcc version 5 or newer required.\n'
               'Installed version:', gcc_version)
         Exit(1)
 
     main['GCC_VERSION'] = gcc_version
 
-    if compareVersions(gcc_version, '4.9') >= 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.
-        #
-        # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67548
-        main['BROKEN_INCREMENTAL_LTO'] = True
+    # 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.
+    #
+    # 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
@@ -438,9 +391,9 @@ if main['GCC']:
     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
 
@@ -461,15 +414,12 @@ if main['GCC']:
                                   '-fno-builtin-realloc', '-fno-builtin-free'])
 
 elif main['CLANG']:
-    # Check for a supported version of clang, >= 3.1 is needed to
-    # support similar features as gcc 4.8. 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.1") < 0:
-            error('clang version 3.1 or newer required.\n'
+        if compareVersions(clang_version, "3.9") < 0:
+            error('clang version 3.9 or newer required.\n'
                   'Installed version:', clang_version)
     else:
         error('Unable to determine clang version.')
@@ -485,6 +435,12 @@ elif main['CLANG']:
                          # interchangeably.
                          '-Wno-mismatched-tags',
                          ])
+    if sys.platform != "darwin" and \
+       compareVersions(clang_version, "10.0") >= 0:
+        main.Append(CCFLAGS=['-Wno-c99-designator'])
+
+    if compareVersions(clang_version, "8.0") >= 0:
+        main.Append(CCFLAGS=['-Wno-defaulted-function-deleted'])
 
     main.Append(TCMALLOC_CCFLAGS=['-fno-builtin'])
 
@@ -501,15 +457,21 @@ elif main['CLANG']:
 # 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')
+    sanitizers.append('undefined')
 if GetOption('with_asan'):
-    # Available for gcc >= 4.8 or llvm >= 3.1 both a requirement
+    # Available for gcc >= 5 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']:
@@ -669,24 +631,43 @@ if main['USE_PYTHON']:
     # 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, ))
+    if python_config != 'python3-config':
+        warning('python3-config could not be found.\n'
+                'Future releases of gem5 will drop support for python2.')
+
     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
     # flags. The libraries are added later through the call the CheckLib.
-    py_ld_flags = readCommand([python_config, '--ldflags'],
-        exception='').split()
+    # Note: starting in Python 3.8 the --embed flag is required to get the
+    # -lpython3.8 linker flag
+    retcode, cmd_stdout = readCommandWithReturn(
+        [python_config, '--ldflags', '--embed'], exception='')
+    if retcode != 0:
+        # If --embed isn't detected then we're running python <3.8
+        retcode, cmd_stdout = readCommandWithReturn(
+            [python_config, '--ldflags'], exception='')
+
+    # Checking retcode again
+    if retcode != 0:
+        error("Failing on python-config --ldflags command")
+
+    py_ld_flags = cmd_stdout.split()
+
     py_libs = []
     for lib in py_ld_flags:
          if not lib.startswith('-l'):
@@ -711,6 +692,12 @@ if main['USE_PYTHON']:
         if not conf.CheckLib(lib):
             error("Can't find library %s required by python." % lib)
 
+main.Prepend(CPPPATH=Dir('ext/pybind11/include/'))
+# Bare minimum environment that only includes python
+marshal_env = main.Clone()
+marshal_env.Append(CCFLAGS='$MARSHAL_CCFLAGS_EXTRA')
+marshal_env.Append(LINKFLAGS='$MARSHAL_LDFLAGS_EXTRA')
+
 # On Solaris you need to use libsocket for socket ops
 if not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'):
    if not conf.CheckLibWithHeader('socket', 'sys/socket.h',
@@ -963,10 +950,10 @@ 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),
+    EnumVariable('TARGET_ISA', 'Target ISA', 'null', all_isa_list),
+    EnumVariable('TARGET_GPU_ISA', 'Target GPU ISA', 'gcn3', 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),
@@ -976,8 +963,6 @@ sticky_vars.AddVariables(
     BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock),
     BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
     BoolVariable('USE_PNG',  'Enable support for PNG images', have_png),
-    BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability',
-                 False),
     BoolVariable('USE_KVM', 'Enable hardware virtualized (KVM) CPU models',
                  have_kvm),
     BoolVariable('USE_TUNTAP',
@@ -994,7 +979,7 @@ sticky_vars.AddVariables(
     )
 
 # These variables get exported to #defines in config/*.hh (see src/SConscript).
-export_vars += ['USE_FENV', 'TARGET_ISA', 'TARGET_GPU_ISA', 'CP_ANNOTATE',
+export_vars += ['USE_FENV', 'TARGET_ISA', 'TARGET_GPU_ISA',
                 'USE_POSIX_CLOCK', 'USE_KVM', 'USE_TUNTAP', 'PROTOCOL',
                 'HAVE_PROTOBUF', 'HAVE_VALGRIND',
                 'HAVE_PERF_ATTR_EXCLUDE_HOST', 'USE_PNG',
@@ -1011,10 +996,9 @@ export_vars += ['USE_FENV', 'TARGET_ISA', 'TARGET_GPU_ISA', 'CP_ANNOTATE',
 # 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.
@@ -1103,8 +1087,6 @@ for root, dirs, files in os.walk(ext_dir):
 gdb_xml_dir = joinpath(ext_dir, 'gdb-xml')
 Export('gdb_xml_dir')
 
-main.Prepend(CPPPATH=Dir('ext/pybind11/include/'))
-
 ###################################################
 #
 # This builder and wrapper method are used to set up a directory with
@@ -1187,7 +1169,7 @@ for variant_path in variant_paths:
                                   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)
@@ -1201,9 +1183,11 @@ for variant_path in variant_paths:
     # Apply current variable settings to env
     sticky_vars.Update(env)
 
-    help_texts["local_vars"] += \
-        "Build variables for %s:\n" % variant_dir \
-                 + sticky_vars.GenerateHelpText(env)
+    Help('''
+Build variables for {dir}:
+{help}
+'''.format(dir=variant_dir, help=sticky_vars.GenerateHelpText(env)),
+         append=True)
 
     # Process variable settings.
 
@@ -1262,17 +1246,7 @@ for variant_path in variant_paths:
     # The src/SConscript file sets up the build rules in 'env' according
     # to the configured variables.  It returns a list of environments,
     # one for each variant build (debug, opt, etc.)
-    SConscript('src/SConscript', variant_dir = variant_path, exports = 'env')
-
-# base help text
-Help('''
-Usage: scons [scons options] [build variables] [target(s)]
-
-Extra scons options:
-%(options)s
-
-Global build variables:
-%(global_vars)s
+    SConscript('src/SConscript', variant_dir=variant_path,
+               exports=['env', 'marshal_env'])
 
-%(local_vars)s
-''' % help_texts)
+atexit.register(summarize_warnings)