sim: Updated ClockedObject power state warning
[gem5.git] / SConstruct
index ff6de944c49c3716a1d2a1f322a774ea50c2471b..146b156d183937e15965cf264748fb58e9e88fd9 100755 (executable)
@@ -183,6 +183,9 @@ AddLocalOption('--ignore-style', dest='ignore_style', action='store_true',
                help='Disable style checking hooks')
 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',
@@ -198,6 +201,10 @@ AddLocalOption('--with-ubsan', dest='with_ubsan', action='store_true',
 AddLocalOption('--with-asan', dest='with_asan', action='store_true',
                help='Build with Address Sanitizer if available')
 
+if GetOption('no_lto') and GetOption('force_lto'):
+    print '--no-lto and --force-lto are mutually exclusive'
+    Exit(1)
+
 termcap = get_termcap(GetOption('use_colors'))
 
 ########################################################################
@@ -685,7 +692,7 @@ if main['GCC'] or main['CLANG']:
     main['FILTER_PSHLINKFLAGS'] = lambda x: str(x).replace(' -shared', '')
     main['PSHLINKFLAGS'] = main.subst('${FILTER_PSHLINKFLAGS(SHLINKFLAGS)}')
     main['PLINKFLAGS'] = main.subst('${LINKFLAGS}')
-    shared_partial_flags = ['-Wl,--relocatable', '-nostdlib']
+    shared_partial_flags = ['-r', '-nostdlib']
     main.Append(PSHLINKFLAGS=shared_partial_flags)
     main.Append(PLINKFLAGS=shared_partial_flags)
 else:
@@ -719,6 +726,28 @@ if main['GCC']:
 
     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
+    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.
+        #
+        # 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')
+
     # gcc from version 4.8 and above generates "rep; ret" instructions
     # to avoid performance penalties on certain AMD chips. Older
     # assemblers detect this as an error, "Error: expecting string
@@ -749,10 +778,21 @@ if main['GCC']:
             'Warning: UBSan is only supported using gcc 4.9 and later.' + \
             termcap.Normal
 
+    disable_lto = GetOption('no_lto')
+    if not disable_lto and main.get('BROKEN_INCREMENTAL_LTO', False) and \
+            not GetOption('force_lto'):
+        print termcap.Yellow + termcap.Bold + \
+            '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.' + \
+            termcap.Normal
+        disable_lto = True
+
     # Add the appropriate Link-Time Optimization (LTO) flags
     # unless LTO is explicitly turned off. Note that these flags
     # are only used by the fast target.
-    if not GetOption('no_lto'):
+    if not disable_lto:
         # Pass the LTO flag when compiling to produce GIMPLE
         # output, we merely create the flags here and only append
         # them later
@@ -1101,6 +1141,11 @@ if not have_kvm:
     print "Info: Compatible header file <linux/kvm.h> not found, " \
         "disabling KVM support."
 
+# Check if the TUN/TAP driver is available.
+have_tuntap = conf.CheckHeader('linux/if_tun.h', '<>')
+if not have_tuntap:
+    print "Info: Compatible header file <linux/if_tun.h> not found."
+
 # 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.
@@ -1233,6 +1278,9 @@ sticky_vars.AddVariables(
     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('USE_TUNTAP',
+                 'Enable using a tap device to bridge to the host network',
+                 have_tuntap),
     BoolVariable('BUILD_GPU', 'Build the compute-GPU model', False),
     EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None',
                   all_protocols),
@@ -1242,8 +1290,8 @@ sticky_vars.AddVariables(
 
 # 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', 'PROTOCOL',
-                'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST']
+                'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'USE_TUNTAP',
+                'PROTOCOL', 'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST']
 
 ###################################################
 #
@@ -1314,9 +1362,11 @@ main.Append(BUILDERS = { 'PartialShared' : partial_shared_builder,
 
 # builds in ext are shared across all configs in the build root.
 ext_dir = abspath(joinpath(str(main.root), 'ext'))
+ext_build_dirs = []
 for root, dirs, files in os.walk(ext_dir):
     if 'SConscript' in files:
         build_dir = os.path.relpath(root, ext_dir)
+        ext_build_dirs.append(build_dir)
         main.SConscript(joinpath(root, 'SConscript'),
                         variant_dir=joinpath(build_root, build_dir))
 
@@ -1324,72 +1374,36 @@ main.Prepend(CPPPATH=Dir('ext/pybind11/include/'))
 
 ###################################################
 #
-# This function is used to set up a directory with switching headers
+# This builder and wrapper method are used to set up a directory with
+# switching headers. Those are headers which are in a generic location and
+# that include more specific headers from a directory chosen at build time
+# based on the current build settings.
 #
 ###################################################
 
-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
-    # 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_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_LIST'])
+def build_switching_header(target, source, env):
+    path = str(target[0])
+    subdir = str(source[0])
+    dp, fp = os.path.split(path)
+    dp = os.path.relpath(os.path.realpath(dp),
+                         os.path.realpath(env['BUILDDIR']))
+    with open(path, 'w') as hdr:
+        print >>hdr, '#include "%s/%s/%s"' % (dp, subdir, fp)
 
-    # Instantiate actions for each header
-    for hdr in switch_headers:
-        env.Command(hdr, [], switch_hdr_action)
+switching_header_action = MakeAction(build_switching_header,
+                                     Transform('GENERATE'))
 
-    isa_target = Dir('.').up().name.lower().replace('_', '-')
-    env['PHONY_BASE'] = '#'+isa_target
-    all_isa_deps[isa_target] = None
+switching_header_builder = Builder(action=switching_header_action,
+                                   source_factory=Value,
+                                   single_source=True)
 
-Export('make_switching_dir')
+main.Append(BUILDERS = { 'SwitchingHeader': switching_header_builder })
 
-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])
+def switching_headers(self, headers, source):
+    for header in headers:
+        self.SwitchingHeader(header, source)
 
-        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')
+main.AddMethod(switching_headers, 'SwitchingHeaders')
 
 # all-isas -> all-deps -> all-environs -> all_targets
 main.Alias('#all-isas', [])
@@ -1421,6 +1435,11 @@ BUILD_TARGETS[:] = ['#all-targets']
 #
 ###################################################
 
+def variant_name(path):
+    return os.path.basename(path).lower().replace('_', '-')
+main['variant_name'] = variant_name
+main['VARIANT_NAME'] = '${variant_name(BUILDDIR)}'
+
 for variant_path in variant_paths:
     if not GetOption('silent'):
         print "Building in", variant_path
@@ -1443,6 +1462,9 @@ for variant_path in variant_paths:
         sticky_vars.files.append(current_vars_file)
         if not GetOption('silent'):
             print "Using saved variables file %s" % current_vars_file
+    elif variant_dir in ext_build_dirs:
+        # Things in ext are built without a variant directory.
+        continue
     else:
         # Build dir-specific variables file doesn't exist.
 
@@ -1503,6 +1525,11 @@ for variant_path in variant_paths:
                 "target ISA combination"
             env['USE_KVM'] = False
 
+    if env['USE_TUNTAP']:
+        if not have_tuntap:
+            print "Warning: Can't connect EtherTap with a tap device."
+            env['USE_TUNTAP'] = False
+
     if env['BUILD_GPU']:
         env.Append(CPPDEFINES=['BUILD_GPU'])
 
@@ -1530,6 +1557,8 @@ def pairwise(iterable):
     b.next()
     return itertools.izip(a, b)
 
+variant_names = [variant_name(path) for path in variant_paths]
+
 # Create false dependencies so SCons will parse ISAs, establish
 # dependencies, and setup the build Environments serially. Either
 # SCons (likely) and/or our SConscripts (possibly) cannot cope with -j
@@ -1538,7 +1567,7 @@ def pairwise(iterable):
 # Every time I tried to remove this, builds would fail in some
 # creative new way. So, don't do that. You'll want to, though, because
 # tests/SConscript takes a long time to make its Environments.
-for t1, t2 in pairwise(sorted(all_isa_deps.iterkeys())):
+for t1, t2 in pairwise(sorted(variant_names)):
     main.Depends('#%s-deps'     % t2, '#%s-deps'     % t1)
     main.Depends('#%s-environs' % t2, '#%s-environs' % t1)