stats: update stats for ARMv8 changes
[gem5.git] / SConstruct
index 12819adcd4c300c17809fd1b9eb6b6375e8aa1f5..cdd44a871d382c94c91471627a9eb2ba6a9e9cf8 100755 (executable)
@@ -190,9 +190,11 @@ termcap = get_termcap(GetOption('use_colors'))
 # Set up the main build environment.
 #
 ########################################################################
+
+# export TERM so that clang reports errors in color
 use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH',
                  'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PYTHONPATH',
-                 'RANLIB', 'SWIG' ])
+                 'RANLIB', 'SWIG', 'TERM' ])
 
 use_prefixes = [
     "M5",           # M5 configuration (e.g., path to kernels)
@@ -630,15 +632,10 @@ elif main['CLANG']:
     main.Append(TCMALLOC_CCFLAGS=['-fno-builtin'])
 
     # On Mac OS X/Darwin we need to also use libc++ (part of XCode) as
-    # opposed to libstdc++ to make the transition from TR1 to
-    # C++11. See http://libcxx.llvm.org. However, clang has chosen a
-    # strict implementation of the C++11 standard, and does not allow
-    # incomplete types in template arguments (besides unique_ptr and
-    # shared_ptr), and the libc++ STL containers create problems in
-    # combination with the current gem5 code. For now, we stick with
-    # libstdc++ and use the TR1 namespace.
-    # if sys.platform == "darwin":
-    #     main.Append(CXXFLAGS=['-stdlib=libc++'])
+    # opposed to libstdc++, as the later is dated.
+    if sys.platform == "darwin":
+        main.Append(CXXFLAGS=['-stdlib=libc++'])
+        main.Append(LIBS=['c++'])
 
 else:
     print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal,
@@ -735,14 +732,16 @@ if compareVersions(swig_version[2], min_swig_version) < 0:
     print '       Installed version:', swig_version[2]
     Exit(1)
 
-if swig_version[2] in ["2.0.9", "2.0.10"]:
+# Older versions of swig do not play well with more recent versions of
+# gcc due to assumptions on implicit includes (cstddef) and use of
+# namespaces
+if main['GCC'] and compareVersions(gcc_version, '4.6') > 0 and \
+        compareVersions(swig_version[2], '2') < 0:
     print '\n' + termcap.Yellow + termcap.Bold + \
-        'Warning: SWIG version 2.0.9/10 sometimes generates broken code.\n' + \
+        'Warning: SWIG 1.x cause issues with gcc 4.6 and later.\n' + \
         termcap.Normal + \
-        'This problem only affects some platforms and some Python\n' + \
-        'versions. See the following SWIG bug report for details:\n' + \
-        'http://sourceforge.net/p/swig/bugs/1297/\n'
-
+        'Use SWIG 2.x to avoid assumptions on implicit includes\n' + \
+        'and use of namespaces\n'
 
 # Set up SWIG flags & scanner
 swig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS')
@@ -795,12 +794,35 @@ def CheckLeading(context):
     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..." %
+                    (member, decl))
+    text = """
+#include %(header)s
+int main(){
+  %(decl)s test;
+  (void)test.%(member)s;
+  return 0;
+};
+""" % { "header" : include_quotes[0] + include + include_quotes[1],
+        "decl" : decl,
+        "member" : member,
+        }
+
+    ret = context.TryCompile(text, extension=".cc")
+    context.Result(ret)
+    return ret
+
 # Platform-specific configuration.  Note again that we assume that all
 # builds under a given build root run on the same host platform.
 conf = Configure(main,
                  conf_dir = joinpath(build_root, '.scons_config'),
                  log_file = joinpath(build_root, 'scons_config.log'),
-                 custom_tests = { 'CheckLeading' : CheckLeading })
+                 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.
@@ -916,6 +938,10 @@ have_posix_clock = \
     conf.CheckLibWithHeader('rt', 'time.h', 'C',
                             'clock_nanosleep(0,0,NULL,NULL);')
 
+have_posix_timers = \
+    conf.CheckLibWithHeader([None, 'rt'], [ 'time.h', 'signal.h' ], 'C',
+                            'timer_create(CLOCK_MONOTONIC, NULL, NULL);')
+
 if conf.CheckLib('tcmalloc'):
     main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS'])
 elif conf.CheckLib('tcmalloc_minimal'):
@@ -935,16 +961,21 @@ if not have_fenv:
     print "Warning: Header file <fenv.h> not found."
     print "         This host has no IEEE FP rounding mode control."
 
-# Check if we should enable KVM-based hardware virtualization
-have_kvm = conf.CheckHeader('linux/kvm.h', '<>')
+# Check if we should enable KVM-based hardware virtualization. The API
+# 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
 if not have_kvm:
-    print "Info: Header file <linux/kvm.h> not found, " \
+    print "Info: Compatible header file <linux/kvm.h> not found, " \
         "disabling KVM support."
 
 # 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
@@ -956,6 +987,12 @@ def is_isa_kvm_compatible(isa):
     return host_isa in isa_comp_table.get(isa, [])
 
 
+# Check if the exclude_host attribute is available. We want this to
+# get accurate instruction counts in KVM.
+main['HAVE_PERF_ATTR_EXCLUDE_HOST'] = conf.CheckMember(
+    'linux/perf_event.h', 'struct perf_event_attr', 'exclude_host')
+
+
 ######################################################################
 #
 # Finish the configuration
@@ -1057,7 +1094,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', 'CP_ANNOTATE',
-                'USE_POSIX_CLOCK', 'PROTOCOL', 'HAVE_PROTOBUF']
+                'USE_POSIX_CLOCK', 'PROTOCOL', 'HAVE_PROTOBUF',
+                'HAVE_PERF_ATTR_EXCLUDE_HOST']
 
 ###################################################
 #
@@ -1112,6 +1150,10 @@ main.SConscript('ext/gzstream/SConscript',
 main.SConscript('ext/libfdt/SConscript',
                 variant_dir = joinpath(build_root, 'libfdt'))
 
+# fputils build is shared across all configs in the build root.
+main.SConscript('ext/fputils/SConscript',
+                variant_dir = joinpath(build_root, 'fputils'))
+
 ###################################################
 #
 # This function is used to set up a directory with switching headers
@@ -1222,11 +1264,22 @@ for variant_path in variant_paths:
         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"
             env['USE_KVM'] = False
 
+    # Warn about missing optional functionality
+    if env['USE_KVM']:
+        if not main['HAVE_PERF_ATTR_EXCLUDE_HOST']:
+            print "Warning: perf_event headers lack support for the " \
+                "exclude_host attribute. KVM instruction counts will " \
+                "be inaccurate."
+
     # Save sticky variable settings back to current variables file
     sticky_vars.Save(current_vars_file, env)