#
# SCons top-level build description (SConstruct) file.
#
-# While in this directory ('m5'), just type 'scons' to build the default
+# 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_FS/m5.opt' for
+# to build some other configuration (e.g., 'build/ALPHA/gem5.opt' for
# the optimized full-system version).
#
-# You can build M5 in a different directory as long as there is a
+# You can build gem5 in a different directory as long as there is a
# 'build/<CONFIG>' somewhere along the target path. The build system
# expects that all configs under the same build directory are being
# built for the same host system.
#
# 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>/m5 ; scons build/ALPHA_FS/m5.debug
-# % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug
+# % cd <path-to-src>/gem5 ; scons build/ALPHA/gem5.debug
+# % cd <path-to-src>/gem5/build/ALPHA; 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>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug
-# % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug
+# % 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
#
# You can use 'scons -H' to print scons options. If you're in this
-# 'm5' directory (or use -u or -C to tell scons where to find this
-# file), you can use 'scons -h' to print all the M5-specific build
+# 'gem5' directory (or use -u or -C to tell scons where to find this
+# file), you can use 'scons -h' to print all the gem5-specific build
# options as well.
#
###################################################
except SystemExit, e:
print """
For more details, see:
- http://m5sim.org/wiki/index.php/Compiling_M5
+ http://gem5.org/Dependencies
"""
raise
on the scons script.
For more details, see:
- http://m5sim.org/wiki/index.php/Using_a_non-default_Python_installation
+ http://gem5.org/wiki/index.php/Using_a_non-default_Python_installation
"""
raise
import SCons.Node
extra_python_paths = [
- Dir('src/python').srcnode().abspath, # M5 includes
+ Dir('src/python').srcnode().abspath, # gem5 includes
Dir('ext/ply').srcnode().abspath, # ply is used by several files
]
-
+
sys.path[1:1] = extra_python_paths
from m5.util import compareVersions, readCommand
+from m5.util.terminal import get_termcap
help_texts = {
"options" : "",
Export("help_texts")
-def AddM5Option(*args, **kwargs):
+
+# 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)
AddOption(*args, **kwargs)
-AddM5Option('--colors', dest='use_colors', action='store_true',
- help="Add color to abbreviated scons output")
-AddM5Option('--no-colors', dest='use_colors', action='store_false',
- help="Don't add color to abbreviated scons output")
-AddM5Option('--default', dest='default', type='string', action='store',
- help='Override which build_opts file to use for defaults')
-AddM5Option('--ignore-style', dest='ignore_style', action='store_true',
- help='Disable style checking hooks')
-AddM5Option('--update-ref', dest='update_ref', action='store_true',
- help='Update test reference outputs')
-AddM5Option('--verbose', dest='verbose', action='store_true',
- help='Print full tool command lines')
-
-use_colors = GetOption('use_colors')
-if use_colors:
- from m5.util.terminal import termcap
-elif use_colors is None:
- # option unspecified; default behavior is to use colors iff isatty
- from m5.util.terminal import tty_termcap as termcap
-else:
- from m5.util.terminal import no_termcap as termcap
+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('--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('--no-lto', dest='no_lto', action='store_true',
+ help='Disable Link-Time Optimization for fast')
+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')
+
+termcap = get_termcap(GetOption('use_colors'))
########################################################################
#
# Set up the main build environment.
#
########################################################################
-use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH',
- 'PYTHONPATH', 'RANLIB' ])
+use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH',
+ 'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PYTHONPATH',
+ 'RANLIB', 'SWIG' ])
+
+use_prefixes = [
+ "M5", # M5 configuration (e.g., path to kernels)
+ "DISTCC_", # distcc (distributed compiler wrapper) configuration
+ "CCACHE_", # ccache (caching compiler wrapper) configuration
+ "CCC_", # clang static analyzer configuration
+ ]
use_env = {}
for key,val in os.environ.iteritems():
- if key in use_vars or key.startswith("M5"):
+ if key in use_vars or \
+ any([key.startswith(prefix) for prefix in use_prefixes]):
use_env[key] = val
main = Environment(ENV=use_env)
+main.Decider('MD5-timestamp')
main.root = Dir(".") # The current directory (where this file lives).
main.srcdir = Dir("src") # The source directory
+main_dict_keys = main.Dictionary().keys()
+
+# Check that we have a C/C++ compiler
+if not ('CC' in main_dict_keys and 'CXX' in main_dict_keys):
+ print "No C++ compiler installed (package g++ on Ubuntu and RedHat)"
+ Exit(1)
+
+# Check that swig is present
+if not 'SWIG' in main_dict_keys:
+ print "swig is not installed (package swig on Ubuntu and RedHat)"
+ Exit(1)
+
# add useful python code PYTHONPATH so it can be used by subprocesses
# as well
main.AppendENVPath('PYTHONPATH', extra_python_paths)
#
# Mercurial Stuff.
#
-# If the M5 directory is a mercurial repository, we should do some
+# If the gem5 directory is a mercurial repository, we should do some
# extra things.
#
########################################################################
###################################################
# Find default configuration & binary.
-Default(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
+Default(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA/gem5.debug'))
# helper function: find last occurrence of element in list
def rfind(l, elt, offs = -1):
global_vars.AddVariables(
('CC', 'C compiler', environ.get('CC', main['CC'])),
('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])),
+ ('SWIG', 'SWIG tool', environ.get('SWIG', main['SWIG'])),
+ ('PROTOC', 'protoc tool', environ.get('PROTOC', 'protoc')),
('BATCH', 'Use batch pool for build and tests', False),
('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
('M5_BUILD_CACHE', 'Cache built objects in this directory', False),
Export('Transform')
+# enable the regression script to use the termcap
+main['TERMCAP'] = termcap
if GetOption('verbose'):
def MakeAction(action, string, *args, **kwargs):
main['SHCXXCOMSTR'] = Transform("SHCXX")
Export('MakeAction')
+# Initialize the Link-Time Optimization (LTO) flags
+main['LTO_CCFLAGS'] = []
+main['LTO_LDFLAGS'] = []
+
CXX_version = readCommand([main['CXX'],'--version'], exception=False)
CXX_V = readCommand([main['CXX'],'-V'], exception=False)
main['GCC'] = CXX_version and CXX_version.find('g++') >= 0
-main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
-main['ICC'] = CXX_V and CXX_V.find('Intel') >= 0
-if main['GCC'] + main['SUNCC'] + main['ICC'] > 1:
+main['CLANG'] = CXX_version and CXX_version.find('clang') >= 0
+if main['GCC'] + main['CLANG'] > 1:
print 'Error: How can we have two at the same time?'
Exit(1)
# Set up default C++ compiler flags
if main['GCC']:
+ # Check for a supported version of gcc, >= 4.4 is needed for c++0x
+ # support. See http://gcc.gnu.org/projects/cxx0x.html for details
+ gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False)
+ if compareVersions(gcc_version, "4.4") < 0:
+ print 'Error: gcc version 4.4 or newer required.'
+ print ' Installed version:', gcc_version
+ Exit(1)
+
+ main['GCC_VERSION'] = gcc_version
main.Append(CCFLAGS=['-pipe'])
main.Append(CCFLAGS=['-fno-strict-aliasing'])
main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
- main.Append(CXXFLAGS=['-Wno-deprecated'])
- # Read the GCC version to check for versions with bugs
- # Note CCVERSION doesn't work here because it is run with the CC
- # before we override it from the command line
- gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False)
+ main.Append(CXXFLAGS=['-std=c++0x'])
+
+ # Check for versions with bugs
if not compareVersions(gcc_version, '4.4.1') or \
not compareVersions(gcc_version, '4.4.2'):
print 'Info: Tree vectorizer in GCC 4.4.1 & 4.4.2 is buggy, disabling.'
main.Append(CCFLAGS=['-fno-tree-vectorize'])
-elif main['ICC']:
- pass #Fix me... add warning flags once we clean up icc warnings
-elif main['SUNCC']:
- main.Append(CCFLAGS=['-Qoption ccfe'])
- main.Append(CCFLAGS=['-features=gcc'])
- main.Append(CCFLAGS=['-features=extensions'])
- main.Append(CCFLAGS=['-library=stlport4'])
- main.Append(CCFLAGS=['-xar'])
- #main.Append(CCFLAGS=['-instances=semiexplicit'])
+
+ # LTO support is only really working properly from 4.6 and beyond
+ if compareVersions(gcc_version, '4.6') >= 0:
+ # 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'):
+ # Pass the LTO flag when compiling to produce GIMPLE
+ # output, we merely create the flags here and only append
+ # them later/
+ main['LTO_CCFLAGS'] = ['-flto=%d' % GetOption('num_jobs')]
+
+ # Use the same amount of jobs for LTO as we are running
+ # scons with, we hardcode the use of the linker plugin
+ # which requires either gold or GNU ld >= 2.21
+ main['LTO_LDFLAGS'] = ['-flto=%d' % GetOption('num_jobs'),
+ '-fuse-linker-plugin']
+
+elif main['CLANG']:
+ # Check for a supported version of clang, >= 2.9 is needed to
+ # support similar features as gcc 4.4. See
+ # http://clang.llvm.org/cxx_status.html for details
+ clang_version_re = re.compile(".* version (\d+\.\d+)")
+ clang_version_match = clang_version_re.match(CXX_version)
+ if (clang_version_match):
+ clang_version = clang_version_match.groups()[0]
+ if compareVersions(clang_version, "2.9") < 0:
+ print 'Error: clang version 2.9 or newer required.'
+ print ' Installed version:', clang_version
+ Exit(1)
+ else:
+ print 'Error: Unable to determine clang version.'
+ Exit(1)
+
+ main.Append(CCFLAGS=['-pipe'])
+ main.Append(CCFLAGS=['-fno-strict-aliasing'])
+ main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
+ main.Append(CCFLAGS=['-Wno-tautological-compare'])
+ main.Append(CCFLAGS=['-Wno-self-assign'])
+ # Ruby makes frequent use of extraneous parantheses in the printing
+ # of if-statements
+ main.Append(CCFLAGS=['-Wno-parentheses'])
+ main.Append(CXXFLAGS=['-std=c++0x'])
+ # 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++'])
+
else:
- print 'Error: Don\'t know what compiler options to use for your compiler.'
- print ' Please fix SConstruct and src/SConscript and try again.'
+ print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal,
+ print "Don't know what compiler options to use for your compiler."
+ print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX']
+ print termcap.Yellow + ' version:' + termcap.Normal,
+ if not CXX_version:
+ print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\
+ termcap.Normal
+ else:
+ print CXX_version.replace('\n', '<nl>')
+ print " If you're trying to use a compiler other than GCC"
+ print " or clang, there appears to be something wrong with your"
+ print " environment."
+ print " "
+ print " If you are trying to use a compiler other than those listed"
+ print " above you will need to ease fix SConstruct and "
+ print " src/SConscript to support that compiler."
Exit(1)
# Set up common yacc/bison flags (needed for Ruby)
# cygwin has some header file issues...
main.Append(CCFLAGS=["-Wno-uninitialized"])
+# Check for the protobuf compiler
+protoc_version = readCommand([main['PROTOC'], '--version'],
+ exception='').split()
+
+# First two words should be "libprotoc x.y.z"
+if len(protoc_version) < 2 or protoc_version[0] != 'libprotoc':
+ print termcap.Yellow + termcap.Bold + \
+ 'Warning: Protocol buffer compiler (protoc) not found.\n' + \
+ ' Please install protobuf-compiler for tracing support.' + \
+ termcap.Normal
+ main['PROTOC'] = False
+else:
+ # Based on the availability of the compress stream wrappers,
+ # require 2.1.0
+ min_protoc_version = '2.1.0'
+ if compareVersions(protoc_version[1], min_protoc_version) < 0:
+ print termcap.Yellow + termcap.Bold + \
+ 'Warning: protoc version', min_protoc_version, \
+ 'or newer required.\n' + \
+ ' Installed version:', protoc_version[1], \
+ termcap.Normal
+ main['PROTOC'] = False
+ else:
+ # Attempt to determine the appropriate include path and
+ # library path using pkg-config, that means we also need to
+ # check for pkg-config. Note that it is possible to use
+ # protobuf without the involvement of pkg-config. Later on we
+ # check go a library config check and at that point the test
+ # will fail if libprotobuf cannot be found.
+ if readCommand(['pkg-config', '--version'], exception=''):
+ try:
+ # Attempt to establish what linking flags to add for protobuf
+ # using pkg-config
+ main.ParseConfig('pkg-config --cflags --libs-only-L protobuf')
+ except:
+ print termcap.Yellow + termcap.Bold + \
+ 'Warning: pkg-config could not get protobuf flags.' + \
+ termcap.Normal
+
# Check for SWIG
if not main.has_key('SWIG'):
print 'Error: SWIG utility not found.'
Exit(1)
# Check for appropriate SWIG version
-swig_version = readCommand(('swig', '-version'), exception='').split()
+swig_version = readCommand([main['SWIG'], '-version'], exception='').split()
# First 3 words should be "SWIG Version x.y.z"
if len(swig_version) < 3 or \
swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
print 'Error determining SWIG version.'
Exit(1)
-min_swig_version = '1.3.28'
+min_swig_version = '1.3.34'
if compareVersions(swig_version[2], min_swig_version) < 0:
print 'Error: SWIG version', min_swig_version, 'or newer required.'
print ' Installed version:', swig_version[2]
py_libs = []
for lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split():
- assert lib.startswith('-l')
- lib = lib[2:]
- if lib not in py_libs:
- py_libs.append(lib)
+ if not lib.startswith('-l'):
+ # Python requires some special flags to link (e.g. -framework
+ # common on OS X systems), assume appending preserves order
+ main.Append(LINKFLAGS=[lib])
+ else:
+ lib = lib[2:]
+ if lib not in py_libs:
+ py_libs.append(lib)
py_libs.append(py_version)
main.Append(CPPPATH=py_includes)
# verify that this stuff works
if not conf.CheckHeader('Python.h', '<>'):
print "Error: can't find Python.h header in", py_includes
+ print "Install Python headers (package python-dev on Ubuntu and RedHat)"
Exit(1)
for lib in py_libs:
print ' Please install zlib and try again.'
Exit(1)
+# 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
+# this, we can use the HAVE_PROTOBUF flag to determine if we have
+# got both protoc and libprotobuf available.
+main['HAVE_PROTOBUF'] = main['PROTOC'] and \
+ conf.CheckLibWithHeader('protobuf', 'google/protobuf/message.h',
+ 'C++', 'GOOGLE_PROTOBUF_VERIFY_VERSION;')
+
+# If we have the compiler but not the library, print another warning.
+if main['PROTOC'] and not main['HAVE_PROTOBUF']:
+ print termcap.Yellow + termcap.Bold + \
+ 'Warning: did not find protocol buffer library and/or headers.\n' + \
+ ' Please install libprotobuf-dev for tracing support.' + \
+ termcap.Normal
+
# Check for librt.
have_posix_clock = \
conf.CheckLibWithHeader(None, 'time.h', 'C',
conf.CheckLibWithHeader('rt', 'time.h', 'C',
'clock_nanosleep(0,0,NULL,NULL);')
+if conf.CheckLib('tcmalloc_minimal'):
+ have_tcmalloc = True
+else:
+ have_tcmalloc = False
+ print termcap.Yellow + termcap.Bold + \
+ "You can get a 12% performance improvement by installing tcmalloc "\
+ "(libgoogle-perftools-dev package on Ubuntu or RedHat)." + \
+ termcap.Normal
+
if not have_posix_clock:
print "Can't find library for POSIX clocks."
export_vars = []
Export('export_vars')
+# For Ruby
+all_protocols = []
+Export('all_protocols')
+protocol_dirs = []
+Export('protocol_dirs')
+slicc_includes = []
+Export('slicc_includes')
+
# Walk the tree and execute all SConsopts scripts that wil add to the
# above variables
if not GetOption('verbose'):
sticky_vars.AddVariables(
EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
- BoolVariable('FULL_SYSTEM', 'Full-system support', False),
ListVariable('CPU_MODELS', 'CPU models',
sorted(n for n,m in CpuModel.dict.iteritems() if m.default),
sorted(CpuModel.list)),
- BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False),
- BoolVariable('FORCE_FAST_ALLOC',
- 'Enable fast object allocator, even for m5.debug', False),
- BoolVariable('FAST_ALLOC_STATS', 'Enable fast object allocator statistics',
- False),
BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger',
False),
BoolVariable('SS_COMPATIBLE_FP',
False),
BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock),
BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
- BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
+ EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None',
+ all_protocols),
)
# These variables get exported to #defines in config/*.hh (see src/SConscript).
-export_vars += ['FULL_SYSTEM', 'USE_FENV',
- 'NO_FAST_ALLOC', 'FORCE_FAST_ALLOC', 'FAST_ALLOC_STATS',
- 'SS_COMPATIBLE_FP', 'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE',
- 'USE_POSIX_CLOCK' ]
+export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'CP_ANNOTATE',
+ 'USE_POSIX_CLOCK', 'PROTOCOL', 'HAVE_PROTOBUF']
###################################################
#
if env['USE_SSE2']:
env.Append(CCFLAGS=['-msse2'])
- if env['PROTOCOL'] != 'None':
- env['RUBY'] = True
- else:
- env['RUBY'] = False
+ if have_tcmalloc:
+ env.Append(LIBS=['tcmalloc_minimal'])
# The src/SConscript file sets up the build rules in 'env' according
# to the configured variables. It returns a list of environments,