base: Use system libelf instead of ext
[gem5.git] / SConstruct
index 110f9c896f7810b8fdc8d0021be6c6e8255754e1..bbfa37ad5e10f4f2a6e76576de1fd2ec316223a1 100755 (executable)
@@ -78,6 +78,7 @@
 from __future__ import print_function
 
 # Global Python includes
+import atexit
 import itertools
 import os
 import re
@@ -96,7 +97,7 @@ import SCons
 import SCons.Node
 import SCons.Node.FS
 
-from m5.util import compareVersions, readCommand
+from m5.util import compareVersions, readCommand, readCommandWithReturn
 
 help_texts = {
     "options" : "",
@@ -113,8 +114,8 @@ Export("help_texts")
 # 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
+#     https://github.com/SCons/scons/issues/2356
+#     https://github.com/SCons/scons/issues/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.
@@ -137,38 +138,33 @@ 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',
+AddLocalOption('--with-cxx-config', action='store_true',
                help="Build with support for C++-based configuration")
-AddLocalOption('--default', dest='default', type='string', action='store',
+AddLocalOption('--default',
                help='Override which build_opts file to use for defaults')
-AddLocalOption('--ignore-style', dest='ignore_style', action='store_true',
+AddLocalOption('--ignore-style', action='store_true',
                help='Disable style checking hooks')
-AddLocalOption('--gold-linker', dest='gold_linker', action='store_true',
+AddLocalOption('--gold-linker', action='store_true',
                help='Use the gold linker')
-AddLocalOption('--no-lto', dest='no_lto', action='store_true',
+AddLocalOption('--no-lto', action='store_true',
                help='Disable Link-Time Optimization for fast')
-AddLocalOption('--force-lto', dest='force_lto', action='store_true',
+AddLocalOption('--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',
+AddLocalOption('--verbose', action='store_true',
                help='Print full tool command lines')
-AddLocalOption('--without-python', dest='without_python',
-               action='store_true',
+AddLocalOption('--without-python', action='store_true',
                help='Build without Python configuration support')
-AddLocalOption('--without-tcmalloc', dest='without_tcmalloc',
-               action='store_true',
+AddLocalOption('--without-tcmalloc', action='store_true',
                help='Disable linking against tcmalloc')
-AddLocalOption('--with-ubsan', dest='with_ubsan', action='store_true',
+AddLocalOption('--with-ubsan', action='store_true',
                help='Build with Undefined Behavior Sanitizer if available')
-AddLocalOption('--with-asan', dest='with_asan', action='store_true',
+AddLocalOption('--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')
+AddLocalOption('--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')
@@ -214,19 +210,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 +271,10 @@ 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' ]),
+     [ 'python2.7-config', 'python-config', 'python3-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'),
@@ -371,7 +356,10 @@ if main['GCC'] or main['CLANG']:
         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'):
@@ -438,9 +426,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
 
@@ -485,6 +473,11 @@ elif main['CLANG']:
                          # interchangeably.
                          '-Wno-mismatched-tags',
                          ])
+    if 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'])
 
@@ -510,6 +503,16 @@ 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']:
@@ -669,7 +672,7 @@ 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'])
@@ -687,8 +690,21 @@ if main['USE_PYTHON']:
 
     # 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'):
@@ -713,6 +729,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',
@@ -726,6 +748,10 @@ if not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'):
           'and/or zlib.h header file.\n'
           'Please install zlib and try again.')
 
+if not conf.CheckLibWithHeader('elf', 'gelf.h', 'C++',
+                               'elf_version(EV_CURRENT);'):
+    error('Did not find ELF access library libelf')
+
 # If we have the protobuf compiler, also make sure we have the
 # development libraries. If the check passes, libprotobuf will be
 # automatically added to the LIBS environment variable. After
@@ -965,8 +991,8 @@ 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.items() if m.default),
                  sorted(CpuModel.dict.keys())),
@@ -978,8 +1004,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',
@@ -996,7 +1020,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',
@@ -1013,10 +1037,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.
@@ -1105,8 +1128,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
@@ -1264,7 +1285,8 @@ 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')
+    SConscript('src/SConscript', variant_dir=variant_path,
+               exports=['env', 'marshal_env'])
 
 # base help text
 Help('''
@@ -1278,3 +1300,5 @@ Global build variables:
 
 %(local_vars)s
 ''' % help_texts)
+
+atexit.register(summarize_warnings)