SConstruct revision 11308
17094Sgblack@eecs.umich.edu# -*- mode:python -*- 212497Sgiacomo.travaglini@arm.com 39913Ssteve.reinhardt@amd.com# Copyright (c) 2013, 2015 ARM Limited 47094Sgblack@eecs.umich.edu# All rights reserved. 57094Sgblack@eecs.umich.edu# 67094Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall 77094Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual 87094Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating 97094Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software 107094Sgblack@eecs.umich.edu# licensed hereunder. You may use the software subject to the license 117094Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated 127094Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software, 137094Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form. 147094Sgblack@eecs.umich.edu# 157094Sgblack@eecs.umich.edu# Copyright (c) 2011 Advanced Micro Devices, Inc. 166253Sgblack@eecs.umich.edu# Copyright (c) 2009 The Hewlett-Packard Development Company 176253Sgblack@eecs.umich.edu# Copyright (c) 2004-2005 The Regents of The University of Michigan 186253Sgblack@eecs.umich.edu# All rights reserved. 196253Sgblack@eecs.umich.edu# 206253Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 216253Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 226253Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 236253Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 246253Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 256253Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 266253Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 276253Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 286253Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 296253Sgblack@eecs.umich.edu# this software without specific prior written permission. 306253Sgblack@eecs.umich.edu# 316253Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 326253Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 336253Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 346253Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 356253Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 366253Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 376253Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 386253Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 396253Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 406253Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 416253Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 426253Sgblack@eecs.umich.edu# 436253Sgblack@eecs.umich.edu# Authors: Steve Reinhardt 448229Snate@binkert.org# Nathan Binkert 4511793Sbrandon.potter@amd.com 466759SAli.Saidi@ARM.com################################################### 476255Sgblack@eecs.umich.edu# 486712Snate@binkert.org# SCons top-level build description (SConstruct) file. 4911793Sbrandon.potter@amd.com# 509913Ssteve.reinhardt@amd.com# While in this directory ('gem5'), just type 'scons' to build the default 516253Sgblack@eecs.umich.edu# configuration (see below), or type 'scons build/<CONFIG>/<binary>' 526253Sgblack@eecs.umich.edu# to build some other configuration (e.g., 'build/ALPHA/gem5.opt' for 536253Sgblack@eecs.umich.edu# the optimized full-system version). 546254Sgblack@eecs.umich.edu# 556254Sgblack@eecs.umich.edu# You can build gem5 in a different directory as long as there is a 567148Sgblack@eecs.umich.edu# 'build/<CONFIG>' somewhere along the target path. The build system 577094Sgblack@eecs.umich.edu# expects that all configs under the same build directory are being 586254Sgblack@eecs.umich.edu# built for the same host system. 596255Sgblack@eecs.umich.edu# 606255Sgblack@eecs.umich.edu# Examples: 616255Sgblack@eecs.umich.edu# 626254Sgblack@eecs.umich.edu# The following two commands are equivalent. The '-u' option tells 636254Sgblack@eecs.umich.edu# scons to search up the directory tree for this SConstruct file. 646254Sgblack@eecs.umich.edu# % cd <path-to-src>/gem5 ; scons build/ALPHA/gem5.debug 656255Sgblack@eecs.umich.edu# % cd <path-to-src>/gem5/build/ALPHA; scons -u gem5.debug 666255Sgblack@eecs.umich.edu# 676255Sgblack@eecs.umich.edu# The following two commands are equivalent and demonstrate building 686255Sgblack@eecs.umich.edu# in a directory outside of the source tree. The '-C' option tells 696255Sgblack@eecs.umich.edu# scons to chdir to the specified directory to find this SConstruct 706255Sgblack@eecs.umich.edu# file. 716255Sgblack@eecs.umich.edu# % cd <path-to-src>/gem5 ; scons /local/foo/build/ALPHA/gem5.debug 726255Sgblack@eecs.umich.edu# % cd /local/foo/build/ALPHA; scons -C <path-to-src>/gem5 gem5.debug 736255Sgblack@eecs.umich.edu# 747182Sgblack@eecs.umich.edu# You can use 'scons -H' to print scons options. If you're in this 756255Sgblack@eecs.umich.edu# 'gem5' directory (or use -u or -C to tell scons where to find this 767182Sgblack@eecs.umich.edu# file), you can use 'scons -h' to print all the gem5-specific build 776255Sgblack@eecs.umich.edu# options as well. 786255Sgblack@eecs.umich.edu# 796255Sgblack@eecs.umich.edu################################################### 806255Sgblack@eecs.umich.edu 816255Sgblack@eecs.umich.edu# Check for recent-enough Python and SCons versions. 826255Sgblack@eecs.umich.edutry: 836712Snate@binkert.org # Really old versions of scons only take two options for the 846255Sgblack@eecs.umich.edu # function, so check once without the revision and once with the 856255Sgblack@eecs.umich.edu # revision, the first instance will fail for stuff other than 866254Sgblack@eecs.umich.edu # 0.98, and the second will fail for 0.98.0 876254Sgblack@eecs.umich.edu EnsureSConsVersion(0, 98) 886254Sgblack@eecs.umich.edu EnsureSConsVersion(0, 98, 1) 896254Sgblack@eecs.umich.eduexcept SystemExit, e: 9010037SARM gem5 Developers print """ 9110037SARM gem5 DevelopersFor more details, see: 9210037SARM gem5 Developers http://gem5.org/Dependencies 9310037SARM gem5 Developers""" 9410037SARM gem5 Developers raise 9510037SARM gem5 Developers 9610037SARM gem5 Developers# We ensure the python version early because because python-config 9710037SARM gem5 Developers# requires python 2.5 9810037SARM gem5 Developerstry: 9910037SARM gem5 Developers EnsurePythonVersion(2, 5) 10010037SARM gem5 Developersexcept SystemExit, e: 10110037SARM gem5 Developers print """ 10210037SARM gem5 DevelopersYou can use a non-default installation of the Python interpreter by 10310037SARM gem5 Developersrearranging your PATH so that scons finds the non-default 'python' and 10410037SARM gem5 Developers'python-config' first. 10510037SARM gem5 Developers 10610037SARM gem5 DevelopersFor more details, see: 10710037SARM gem5 Developers http://gem5.org/wiki/index.php/Using_a_non-default_Python_installation 10810037SARM gem5 Developers""" 10910037SARM gem5 Developers raise 11010037SARM gem5 Developers 11110037SARM gem5 Developers# Global Python includes 11210037SARM gem5 Developersimport itertools 11310037SARM gem5 Developersimport os 11410037SARM gem5 Developersimport re 11510037SARM gem5 Developersimport subprocess 11610037SARM gem5 Developersimport sys 11710037SARM gem5 Developers 11810037SARM gem5 Developersfrom os import mkdir, environ 11910037SARM gem5 Developersfrom os.path import abspath, basename, dirname, expanduser, normpath 12010037SARM gem5 Developersfrom os.path import exists, isdir, isfile 12110037SARM gem5 Developersfrom os.path import join as joinpath, split as splitpath 12210037SARM gem5 Developers 12310037SARM gem5 Developers# SCons includes 12410037SARM gem5 Developersimport SCons 12510037SARM gem5 Developersimport SCons.Node 12610037SARM gem5 Developers 12710037SARM gem5 Developersextra_python_paths = [ 12810037SARM gem5 Developers Dir('src/python').srcnode().abspath, # gem5 includes 12910037SARM gem5 Developers Dir('ext/ply').srcnode().abspath, # ply is used by several files 13010037SARM gem5 Developers ] 13110037SARM gem5 Developers 13210037SARM gem5 Developerssys.path[1:1] = extra_python_paths 13310037SARM gem5 Developers 13410037SARM gem5 Developersfrom m5.util import compareVersions, readCommand 13510037SARM gem5 Developersfrom m5.util.terminal import get_termcap 13610037SARM gem5 Developers 13710037SARM gem5 Developershelp_texts = { 13810037SARM gem5 Developers "options" : "", 13910037SARM gem5 Developers "global_vars" : "", 14010037SARM gem5 Developers "local_vars" : "" 14110037SARM gem5 Developers} 14210037SARM gem5 Developers 14310037SARM gem5 DevelopersExport("help_texts") 14410037SARM gem5 Developers 14510037SARM gem5 Developers 14610037SARM gem5 Developers# There's a bug in scons in that (1) by default, the help texts from 14710037SARM gem5 Developers# AddOption() are supposed to be displayed when you type 'scons -h' 14810037SARM gem5 Developers# and (2) you can override the help displayed by 'scons -h' using the 14910037SARM gem5 Developers# Help() function, but these two features are incompatible: once 15010037SARM gem5 Developers# you've overridden the help text using Help(), there's no way to get 15110037SARM gem5 Developers# at the help texts from AddOptions. See: 15210037SARM gem5 Developers# http://scons.tigris.org/issues/show_bug.cgi?id=2356 15310037SARM gem5 Developers# http://scons.tigris.org/issues/show_bug.cgi?id=2611 15410037SARM gem5 Developers# This hack lets us extract the help text from AddOptions and 15510037SARM gem5 Developers# re-inject it via Help(). Ideally someday this bug will be fixed and 15610037SARM gem5 Developers# we can just use AddOption directly. 15710037SARM gem5 Developersdef AddLocalOption(*args, **kwargs): 15810037SARM gem5 Developers col_width = 30 15910037SARM gem5 Developers 16010037SARM gem5 Developers help = " " + ", ".join(args) 16110037SARM gem5 Developers if "help" in kwargs: 16210037SARM gem5 Developers length = len(help) 16310037SARM gem5 Developers if length >= col_width: 16410037SARM gem5 Developers help += "\n" + " " * col_width 16510037SARM gem5 Developers else: 16610037SARM gem5 Developers help += " " * (col_width - length) 16710037SARM gem5 Developers help += kwargs["help"] 16810037SARM gem5 Developers help_texts["options"] += help + "\n" 16910037SARM gem5 Developers 17010037SARM gem5 Developers AddOption(*args, **kwargs) 17110037SARM gem5 Developers 17210037SARM gem5 DevelopersAddLocalOption('--colors', dest='use_colors', action='store_true', 17310037SARM gem5 Developers help="Add color to abbreviated scons output") 1746254Sgblack@eecs.umich.eduAddLocalOption('--no-colors', dest='use_colors', action='store_false', 1756254Sgblack@eecs.umich.edu help="Don't add color to abbreviated scons output") 1767148Sgblack@eecs.umich.eduAddLocalOption('--with-cxx-config', dest='with_cxx_config', 1777094Sgblack@eecs.umich.edu action='store_true', 1786254Sgblack@eecs.umich.edu help="Build with support for C++-based configuration") 1796254Sgblack@eecs.umich.eduAddLocalOption('--default', dest='default', type='string', action='store', 1806254Sgblack@eecs.umich.edu help='Override which build_opts file to use for defaults') 1816254Sgblack@eecs.umich.eduAddLocalOption('--ignore-style', dest='ignore_style', action='store_true', 1826254Sgblack@eecs.umich.edu help='Disable style checking hooks') 1836254Sgblack@eecs.umich.eduAddLocalOption('--no-lto', dest='no_lto', action='store_true', 1846255Sgblack@eecs.umich.edu help='Disable Link-Time Optimization for fast') 1856255Sgblack@eecs.umich.eduAddLocalOption('--update-ref', dest='update_ref', action='store_true', 1866255Sgblack@eecs.umich.edu help='Update test reference outputs') 1876255Sgblack@eecs.umich.eduAddLocalOption('--verbose', dest='verbose', action='store_true', 1886255Sgblack@eecs.umich.edu help='Print full tool command lines') 1896255Sgblack@eecs.umich.eduAddLocalOption('--without-python', dest='without_python', 1906255Sgblack@eecs.umich.edu action='store_true', 1916255Sgblack@eecs.umich.edu help='Build without Python configuration support') 1926255Sgblack@eecs.umich.eduAddLocalOption('--without-tcmalloc', dest='without_tcmalloc', 1936255Sgblack@eecs.umich.edu action='store_true', 1946255Sgblack@eecs.umich.edu help='Disable linking against tcmalloc') 1956255Sgblack@eecs.umich.eduAddLocalOption('--with-ubsan', dest='with_ubsan', action='store_true', 1967182Sgblack@eecs.umich.edu help='Build with Undefined Behavior Sanitizer if available') 1976255Sgblack@eecs.umich.edu 1987182Sgblack@eecs.umich.edutermcap = get_termcap(GetOption('use_colors')) 1996255Sgblack@eecs.umich.edu 2006255Sgblack@eecs.umich.edu######################################################################## 2016255Sgblack@eecs.umich.edu# 2026255Sgblack@eecs.umich.edu# Set up the main build environment. 2036255Sgblack@eecs.umich.edu# 2046255Sgblack@eecs.umich.edu######################################################################## 2056255Sgblack@eecs.umich.edu 2066712Snate@binkert.org# export TERM so that clang reports errors in color 2076255Sgblack@eecs.umich.eduuse_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 2086255Sgblack@eecs.umich.edu 'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PROTOC', 2096254Sgblack@eecs.umich.edu 'PYTHONPATH', 'RANLIB', 'SWIG', 'TERM' ]) 2106254Sgblack@eecs.umich.edu 2116254Sgblack@eecs.umich.eduuse_prefixes = [ 2126254Sgblack@eecs.umich.edu "CCACHE_", # ccache (caching compiler wrapper) configuration 2136254Sgblack@eecs.umich.edu "CCC_", # clang static analyzer configuration 2146254Sgblack@eecs.umich.edu "DISTCC_", # distcc (distributed compiler wrapper) configuration 2156255Sgblack@eecs.umich.edu "INCLUDE_SERVER_", # distcc pump server settings 2167148Sgblack@eecs.umich.edu "M5", # M5 configuration (e.g., path to kernels) 2177094Sgblack@eecs.umich.edu ] 2186254Sgblack@eecs.umich.edu 2196254Sgblack@eecs.umich.eduuse_env = {} 2206254Sgblack@eecs.umich.edufor key,val in sorted(os.environ.iteritems()): 2216254Sgblack@eecs.umich.edu if key in use_vars or \ 2226254Sgblack@eecs.umich.edu any([key.startswith(prefix) for prefix in use_prefixes]): 2236254Sgblack@eecs.umich.edu use_env[key] = val 2246255Sgblack@eecs.umich.edu 2256255Sgblack@eecs.umich.edu# Tell scons to avoid implicit command dependencies to avoid issues 2266255Sgblack@eecs.umich.edu# with the param wrappes being compiled twice (see 2276255Sgblack@eecs.umich.edu# http://scons.tigris.org/issues/show_bug.cgi?id=2811) 2286254Sgblack@eecs.umich.edumain = Environment(ENV=use_env, IMPLICIT_COMMAND_DEPENDENCIES=0) 2296255Sgblack@eecs.umich.edumain.Decider('MD5-timestamp') 2306255Sgblack@eecs.umich.edumain.root = Dir(".") # The current directory (where this file lives). 2316255Sgblack@eecs.umich.edumain.srcdir = Dir("src") # The source directory 2326255Sgblack@eecs.umich.edu 2336255Sgblack@eecs.umich.edumain_dict_keys = main.Dictionary().keys() 2346255Sgblack@eecs.umich.edu 2356255Sgblack@eecs.umich.edu# Check that we have a C/C++ compiler 2366255Sgblack@eecs.umich.eduif not ('CC' in main_dict_keys and 'CXX' in main_dict_keys): 2376255Sgblack@eecs.umich.edu print "No C++ compiler installed (package g++ on Ubuntu and RedHat)" 2386255Sgblack@eecs.umich.edu Exit(1) 2396255Sgblack@eecs.umich.edu 2406255Sgblack@eecs.umich.edu# Check that swig is present 2416255Sgblack@eecs.umich.eduif not 'SWIG' in main_dict_keys: 2426255Sgblack@eecs.umich.edu print "swig is not installed (package swig on Ubuntu and RedHat)" 2436255Sgblack@eecs.umich.edu Exit(1) 2446255Sgblack@eecs.umich.edu 2456255Sgblack@eecs.umich.edu# add useful python code PYTHONPATH so it can be used by subprocesses 2466712Snate@binkert.org# as well 2476255Sgblack@eecs.umich.edumain.AppendENVPath('PYTHONPATH', extra_python_paths) 2486255Sgblack@eecs.umich.edu 2496254Sgblack@eecs.umich.edu######################################################################## 2506254Sgblack@eecs.umich.edu# 2516254Sgblack@eecs.umich.edu# Mercurial Stuff. 2526254Sgblack@eecs.umich.edu# 2536254Sgblack@eecs.umich.edu# If the gem5 directory is a mercurial repository, we should do some 2546254Sgblack@eecs.umich.edu# extra things. 2556255Sgblack@eecs.umich.edu# 2567148Sgblack@eecs.umich.edu######################################################################## 2577094Sgblack@eecs.umich.edu 2586254Sgblack@eecs.umich.eduhgdir = main.root.Dir(".hg") 2596254Sgblack@eecs.umich.edu 2606254Sgblack@eecs.umich.edumercurial_style_message = """ 2616254Sgblack@eecs.umich.eduYou're missing the gem5 style hook, which automatically checks your code 2626255Sgblack@eecs.umich.eduagainst the gem5 style rules on hg commit and qrefresh commands. This 2636255Sgblack@eecs.umich.eduscript will now install the hook in your .hg/hgrc file. 2646255Sgblack@eecs.umich.eduPress enter to continue, or ctrl-c to abort: """ 2656254Sgblack@eecs.umich.edu 2666254Sgblack@eecs.umich.edumercurial_style_hook = """ 2676255Sgblack@eecs.umich.edu# The following lines were automatically added by gem5/SConstruct 2686255Sgblack@eecs.umich.edu# to provide the gem5 style-checking hooks 2696255Sgblack@eecs.umich.edu[extensions] 2706255Sgblack@eecs.umich.edustyle = %s/util/style.py 2716255Sgblack@eecs.umich.edu 2726255Sgblack@eecs.umich.edu[hooks] 2736255Sgblack@eecs.umich.edupretxncommit.style = python:style.check_style 2746255Sgblack@eecs.umich.edupre-qrefresh.style = python:style.check_style 2756255Sgblack@eecs.umich.edu# End of SConstruct additions 2766255Sgblack@eecs.umich.edu 2776255Sgblack@eecs.umich.edu""" % (main.root.abspath) 2786255Sgblack@eecs.umich.edu 2796255Sgblack@eecs.umich.edumercurial_lib_not_found = """ 2806255Sgblack@eecs.umich.eduMercurial libraries cannot be found, ignoring style hook. If 2816255Sgblack@eecs.umich.eduyou are a gem5 developer, please fix this and run the style 2826255Sgblack@eecs.umich.eduhook. It is important. 2836255Sgblack@eecs.umich.edu""" 2846255Sgblack@eecs.umich.edu 2856255Sgblack@eecs.umich.edu# Check for style hook and prompt for installation if it's not there. 2866255Sgblack@eecs.umich.edu# Skip this if --ignore-style was specified, there's no .hg dir to 2876712Snate@binkert.org# install a hook in, or there's no interactive terminal to prompt. 2886255Sgblack@eecs.umich.eduif not GetOption('ignore_style') and hgdir.exists() and sys.stdin.isatty(): 2896255Sgblack@eecs.umich.edu style_hook = True 2906254Sgblack@eecs.umich.edu try: 2916254Sgblack@eecs.umich.edu from mercurial import ui 2926254Sgblack@eecs.umich.edu ui = ui.ui() 2936254Sgblack@eecs.umich.edu ui.readconfig(hgdir.File('hgrc').abspath) 29412104Snathanael.premillieu@arm.com style_hook = ui.config('hooks', 'pretxncommit.style', None) and \ 29512104Snathanael.premillieu@arm.com ui.config('hooks', 'pre-qrefresh.style', None) 29612104Snathanael.premillieu@arm.com except ImportError: 29712104Snathanael.premillieu@arm.com print mercurial_lib_not_found 29812104Snathanael.premillieu@arm.com 29912104Snathanael.premillieu@arm.com if not style_hook: 30012104Snathanael.premillieu@arm.com print mercurial_style_message, 30112104Snathanael.premillieu@arm.com # continue unless user does ctrl-c/ctrl-d etc. 30212104Snathanael.premillieu@arm.com try: 30312104Snathanael.premillieu@arm.com raw_input() 30412104Snathanael.premillieu@arm.com except: 30512104Snathanael.premillieu@arm.com print "Input exception, exiting scons.\n" 30612104Snathanael.premillieu@arm.com sys.exit(1) 30712104Snathanael.premillieu@arm.com hgrc_path = '%s/.hg/hgrc' % main.root.abspath 30812104Snathanael.premillieu@arm.com print "Adding style hook to", hgrc_path, "\n" 30912104Snathanael.premillieu@arm.com try: 31012104Snathanael.premillieu@arm.com hgrc = open(hgrc_path, 'a') 31112104Snathanael.premillieu@arm.com hgrc.write(mercurial_style_hook) 31212104Snathanael.premillieu@arm.com hgrc.close() 31312104Snathanael.premillieu@arm.com except: 31412104Snathanael.premillieu@arm.com print "Error updating", hgrc_path 31512104Snathanael.premillieu@arm.com sys.exit(1) 31612104Snathanael.premillieu@arm.com 31712104Snathanael.premillieu@arm.com 31812104Snathanael.premillieu@arm.com################################################### 31912104Snathanael.premillieu@arm.com# 32012104Snathanael.premillieu@arm.com# Figure out which configurations to set up based on the path(s) of 32112104Snathanael.premillieu@arm.com# the target(s). 32212104Snathanael.premillieu@arm.com# 32312104Snathanael.premillieu@arm.com################################################### 32412104Snathanael.premillieu@arm.com 32512104Snathanael.premillieu@arm.com# Find default configuration & binary. 3266254Sgblack@eecs.umich.eduDefault(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA/gem5.debug')) 3276254Sgblack@eecs.umich.edu 32812104Snathanael.premillieu@arm.com# helper function: find last occurrence of element in list 3296253Sgblack@eecs.umich.edudef rfind(l, elt, offs = -1): 33012104Snathanael.premillieu@arm.com for i in range(len(l)+offs, 0, -1): 33112104Snathanael.premillieu@arm.com if l[i] == elt: 3329913Ssteve.reinhardt@amd.com return i 33312104Snathanael.premillieu@arm.com raise ValueError, "element not found" 33412109SRekai.GonzalezAlberquilla@arm.com 33512109SRekai.GonzalezAlberquilla@arm.com# Take a list of paths (or SCons Nodes) and return a list with all 33612109SRekai.GonzalezAlberquilla@arm.com# paths made absolute and ~-expanded. Paths will be interpreted 33712109SRekai.GonzalezAlberquilla@arm.com# relative to the launch directory unless a different root is provided 33812109SRekai.GonzalezAlberquilla@arm.comdef makePathListAbsolute(path_list, root=GetLaunchDir()): 33912109SRekai.GonzalezAlberquilla@arm.com return [abspath(joinpath(root, expanduser(str(p)))) 34012104Snathanael.premillieu@arm.com for p in path_list] 34112104Snathanael.premillieu@arm.com 34212104Snathanael.premillieu@arm.com# Each target must have 'build' in the interior of the path; the 34312104Snathanael.premillieu@arm.com# directory below this will determine the build parameters. For 34412104Snathanael.premillieu@arm.com# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we 34512104Snathanael.premillieu@arm.com# recognize that ALPHA_SE specifies the configuration because it 34612104Snathanael.premillieu@arm.com# follow 'build' in the build path. 34712104Snathanael.premillieu@arm.com 34812104Snathanael.premillieu@arm.com# The funky assignment to "[:]" is needed to replace the list contents 34912104Snathanael.premillieu@arm.com# in place rather than reassign the symbol to a new list, which 3506253Sgblack@eecs.umich.edu# doesn't work (obviously!). 3516253Sgblack@eecs.umich.eduBUILD_TARGETS[:] = makePathListAbsolute(BUILD_TARGETS) 3526262Sgblack@eecs.umich.edu 3537148Sgblack@eecs.umich.edu# Generate a list of the unique build roots and configs that the 3546262Sgblack@eecs.umich.edu# collected targets reference. 35510037SARM gem5 Developersvariant_paths = [] 35610037SARM gem5 Developersbuild_root = None 35710037SARM gem5 Developersfor t in BUILD_TARGETS: 3586262Sgblack@eecs.umich.edu path_dirs = t.split('/') 3596262Sgblack@eecs.umich.edu try: 36010037SARM gem5 Developers build_top = rfind(path_dirs, 'build', -2) 36110037SARM gem5 Developers except: 3627122Sgblack@eecs.umich.edu print "Error: no non-leaf 'build' dir found on target path", t 36310037SARM gem5 Developers Exit(1) 36410037SARM gem5 Developers this_build_root = joinpath('/',*path_dirs[:build_top+1]) 36510037SARM gem5 Developers if not build_root: 36610037SARM gem5 Developers build_root = this_build_root 36710037SARM gem5 Developers else: 36810037SARM gem5 Developers if this_build_root != build_root: 36910037SARM gem5 Developers print "Error: build targets not under same build root\n"\ 37010037SARM gem5 Developers " %s\n %s" % (build_root, this_build_root) 37110037SARM gem5 Developers Exit(1) 37210037SARM gem5 Developers variant_path = joinpath('/',*path_dirs[:build_top+2]) 37310037SARM gem5 Developers if variant_path not in variant_paths: 37410037SARM gem5 Developers variant_paths.append(variant_path) 37510037SARM gem5 Developers 37610037SARM gem5 Developers# Make sure build_root exists (might not if this is the first build there) 37710037SARM gem5 Developersif not isdir(build_root): 37810037SARM gem5 Developers mkdir(build_root) 37910037SARM gem5 Developersmain['BUILDROOT'] = build_root 38010037SARM gem5 Developers 38110037SARM gem5 DevelopersExport('main') 38210037SARM gem5 Developers 38310037SARM gem5 Developersmain.SConsignFile(joinpath(build_root, "sconsign")) 38410037SARM gem5 Developers 38510037SARM gem5 Developers# Default duplicate option is to use hard links, but this messes up 38610037SARM gem5 Developers# when you use emacs to edit a file in the target dir, as emacs moves 38710037SARM gem5 Developers# file to file~ then copies to file, breaking the link. Symbolic 38810037SARM gem5 Developers# (soft) links work better. 38910037SARM gem5 Developersmain.SetOption('duplicate', 'soft-copy') 39010037SARM gem5 Developers 39110037SARM gem5 Developers# 39210037SARM gem5 Developers# Set up global sticky variables... these are common to an entire build 39310037SARM gem5 Developers# tree (not specific to a particular build like ALPHA_SE) 39410037SARM gem5 Developers# 39510037SARM gem5 Developers 39610037SARM gem5 Developersglobal_vars_file = joinpath(build_root, 'variables.global') 39710037SARM gem5 Developers 39810037SARM gem5 Developersglobal_vars = Variables(global_vars_file, args=ARGUMENTS) 39910037SARM gem5 Developers 40010037SARM gem5 Developersglobal_vars.AddVariables( 40110037SARM gem5 Developers ('CC', 'C compiler', environ.get('CC', main['CC'])), 40210037SARM gem5 Developers ('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])), 40310037SARM gem5 Developers ('SWIG', 'SWIG tool', environ.get('SWIG', main['SWIG'])), 40410037SARM gem5 Developers ('PROTOC', 'protoc tool', environ.get('PROTOC', 'protoc')), 40510037SARM gem5 Developers ('BATCH', 'Use batch pool for build and tests', False), 40610037SARM gem5 Developers ('BATCH_CMD', 'Batch pool submission command name', 'qdo'), 40710037SARM gem5 Developers ('M5_BUILD_CACHE', 'Cache built objects in this directory', False), 40810037SARM gem5 Developers ('EXTRAS', 'Add extra directories to the compilation', '') 40910037SARM gem5 Developers ) 41010037SARM gem5 Developers 41110037SARM gem5 Developers# Update main environment with values from ARGUMENTS & global_vars_file 41210037SARM gem5 Developersglobal_vars.Update(main) 41310037SARM gem5 Developershelp_texts["global_vars"] += global_vars.GenerateHelpText(main) 41410037SARM gem5 Developers 41510037SARM gem5 Developers# Save sticky variable settings back to current variables file 41610037SARM gem5 Developersglobal_vars.Save(global_vars_file, main) 41710037SARM gem5 Developers 41810037SARM gem5 Developers# Parse EXTRAS variable to build list of all directories where we're 41910037SARM gem5 Developers# look for sources etc. This list is exported as extras_dir_list. 42010037SARM gem5 Developersbase_dir = main.srcdir.abspath 42110037SARM gem5 Developersif main['EXTRAS']: 42210037SARM gem5 Developers extras_dir_list = makePathListAbsolute(main['EXTRAS'].split(':')) 42310037SARM gem5 Developerselse: 42410037SARM gem5 Developers extras_dir_list = [] 42510037SARM gem5 Developers 42610037SARM gem5 DevelopersExport('base_dir') 42710037SARM gem5 DevelopersExport('extras_dir_list') 42810037SARM gem5 Developers 42910037SARM gem5 Developers# the ext directory should be on the #includes path 43010037SARM gem5 Developersmain.Append(CPPPATH=[Dir('ext')]) 43110037SARM gem5 Developers 43210037SARM gem5 Developersdef strip_build_path(path, env): 43310037SARM gem5 Developers path = str(path) 43410037SARM gem5 Developers variant_base = env['BUILDROOT'] + os.path.sep 43510037SARM gem5 Developers if path.startswith(variant_base): 43610037SARM gem5 Developers path = path[len(variant_base):] 43710037SARM gem5 Developers elif path.startswith('build/'): 43810037SARM gem5 Developers path = path[6:] 43910037SARM gem5 Developers return path 44010037SARM gem5 Developers 44110037SARM gem5 Developers# Generate a string of the form: 44210037SARM gem5 Developers# common/path/prefix/src1, src2 -> tgt1, tgt2 44310037SARM gem5 Developers# to print while building. 44410037SARM gem5 Developersclass Transform(object): 44510037SARM gem5 Developers # all specific color settings should be here and nowhere else 44610037SARM gem5 Developers tool_color = termcap.Normal 44710037SARM gem5 Developers pfx_color = termcap.Yellow 44810037SARM gem5 Developers srcs_color = termcap.Yellow + termcap.Bold 44910037SARM gem5 Developers arrow_color = termcap.Blue + termcap.Bold 45010037SARM gem5 Developers tgts_color = termcap.Yellow + termcap.Bold 4516262Sgblack@eecs.umich.edu 4526262Sgblack@eecs.umich.edu def __init__(self, tool, max_sources=99): 4536262Sgblack@eecs.umich.edu self.format = self.tool_color + (" [%8s] " % tool) \ 4546263Sgblack@eecs.umich.edu + self.pfx_color + "%s" \ 4557148Sgblack@eecs.umich.edu + self.srcs_color + "%s" \ 4566263Sgblack@eecs.umich.edu + self.arrow_color + " -> " \ 4576263Sgblack@eecs.umich.edu + self.tgts_color + "%s" \ 4586263Sgblack@eecs.umich.edu + termcap.Normal 4596263Sgblack@eecs.umich.edu self.max_sources = max_sources 4606263Sgblack@eecs.umich.edu 4616263Sgblack@eecs.umich.edu def __call__(self, target, source, env, for_signature=None): 4626263Sgblack@eecs.umich.edu # truncate source list according to max_sources param 4636263Sgblack@eecs.umich.edu source = source[0:self.max_sources] 4646263Sgblack@eecs.umich.edu def strip(f): 4656263Sgblack@eecs.umich.edu return strip_build_path(str(f), env) 4666263Sgblack@eecs.umich.edu if len(source) > 0: 4676263Sgblack@eecs.umich.edu srcs = map(strip, source) 4686263Sgblack@eecs.umich.edu else: 4696263Sgblack@eecs.umich.edu srcs = [''] 4706263Sgblack@eecs.umich.edu tgts = map(strip, target) 4716264Sgblack@eecs.umich.edu # surprisingly, os.path.commonprefix is a dumb char-by-char string 4727148Sgblack@eecs.umich.edu # operation that has nothing to do with paths. 4737142Sgblack@eecs.umich.edu com_pfx = os.path.commonprefix(srcs + tgts) 4747142Sgblack@eecs.umich.edu com_pfx_len = len(com_pfx) 4757142Sgblack@eecs.umich.edu if com_pfx: 4767142Sgblack@eecs.umich.edu # do some cleanup and sanity checking on common prefix 4777142Sgblack@eecs.umich.edu if com_pfx[-1] == ".": 4786264Sgblack@eecs.umich.edu # prefix matches all but file extension: ok 4797142Sgblack@eecs.umich.edu # back up one to change 'foo.cc -> o' to 'foo.cc -> .o' 4806264Sgblack@eecs.umich.edu com_pfx = com_pfx[0:-1] 4817142Sgblack@eecs.umich.edu elif com_pfx[-1] == "/": 48212104Snathanael.premillieu@arm.com # common prefix is directory path: OK 4837142Sgblack@eecs.umich.edu pass 4847142Sgblack@eecs.umich.edu else: 4856306Sgblack@eecs.umich.edu src0_len = len(srcs[0]) 4866264Sgblack@eecs.umich.edu tgt0_len = len(tgts[0]) 4876306Sgblack@eecs.umich.edu if src0_len == com_pfx_len: 4886306Sgblack@eecs.umich.edu # source is a substring of target, OK 4896264Sgblack@eecs.umich.edu pass 4906306Sgblack@eecs.umich.edu elif tgt0_len == com_pfx_len: 4916306Sgblack@eecs.umich.edu # target is a substring of source, need to back up to 4926306Sgblack@eecs.umich.edu # avoid empty string on RHS of arrow 4936306Sgblack@eecs.umich.edu sep_idx = com_pfx.rfind(".") 4946264Sgblack@eecs.umich.edu if sep_idx != -1: 4956306Sgblack@eecs.umich.edu com_pfx = com_pfx[0:sep_idx] 4967142Sgblack@eecs.umich.edu else: 4977142Sgblack@eecs.umich.edu com_pfx = '' 4987142Sgblack@eecs.umich.edu elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".": 4996306Sgblack@eecs.umich.edu # still splitting at file extension: ok 5006306Sgblack@eecs.umich.edu pass 5017142Sgblack@eecs.umich.edu else: 5027142Sgblack@eecs.umich.edu # probably a fluke; ignore it 5037142Sgblack@eecs.umich.edu com_pfx = '' 5046306Sgblack@eecs.umich.edu # recalculate length in case com_pfx was modified 5056306Sgblack@eecs.umich.edu com_pfx_len = len(com_pfx) 5067142Sgblack@eecs.umich.edu def fmt(files): 5077142Sgblack@eecs.umich.edu f = map(lambda s: s[com_pfx_len:], files) 5087142Sgblack@eecs.umich.edu return ', '.join(f) 5096306Sgblack@eecs.umich.edu return self.format % (com_pfx, fmt(srcs), fmt(tgts)) 5106306Sgblack@eecs.umich.edu 5116306Sgblack@eecs.umich.eduExport('Transform') 5127142Sgblack@eecs.umich.edu 5137142Sgblack@eecs.umich.edu# enable the regression script to use the termcap 5147142Sgblack@eecs.umich.edumain['TERMCAP'] = termcap 5156306Sgblack@eecs.umich.edu 5166264Sgblack@eecs.umich.eduif GetOption('verbose'): 5176264Sgblack@eecs.umich.edu def MakeAction(action, string, *args, **kwargs): 5187142Sgblack@eecs.umich.edu return Action(action, *args, **kwargs) 5197142Sgblack@eecs.umich.eduelse: 5207142Sgblack@eecs.umich.edu MakeAction = Action 5216306Sgblack@eecs.umich.edu main['CCCOMSTR'] = Transform("CC") 5226306Sgblack@eecs.umich.edu main['CXXCOMSTR'] = Transform("CXX") 5236306Sgblack@eecs.umich.edu main['ASCOMSTR'] = Transform("AS") 5246306Sgblack@eecs.umich.edu main['SWIGCOMSTR'] = Transform("SWIG") 5256306Sgblack@eecs.umich.edu main['ARCOMSTR'] = Transform("AR", 0) 5267142Sgblack@eecs.umich.edu main['LINKCOMSTR'] = Transform("LINK", 0) 5277142Sgblack@eecs.umich.edu main['RANLIBCOMSTR'] = Transform("RANLIB", 0) 5286306Sgblack@eecs.umich.edu main['M4COMSTR'] = Transform("M4") 5296306Sgblack@eecs.umich.edu main['SHCCCOMSTR'] = Transform("SHCC") 5306306Sgblack@eecs.umich.edu main['SHCXXCOMSTR'] = Transform("SHCXX") 53112104Snathanael.premillieu@arm.comExport('MakeAction') 5326264Sgblack@eecs.umich.edu 5336264Sgblack@eecs.umich.edu# Initialize the Link-Time Optimization (LTO) flags 5346264Sgblack@eecs.umich.edumain['LTO_CCFLAGS'] = [] 5356264Sgblack@eecs.umich.edumain['LTO_LDFLAGS'] = [] 53610037SARM gem5 Developers 53710037SARM gem5 Developers# According to the readme, tcmalloc works best if the compiler doesn't 53810037SARM gem5 Developers# assume that we're using the builtin malloc and friends. These flags 53910037SARM gem5 Developers# are compiler-specific, so we need to set them after we detect which 54010037SARM gem5 Developers# compiler we're using. 54110037SARM gem5 Developersmain['TCMALLOC_CCFLAGS'] = [] 54212104Snathanael.premillieu@arm.com 54310037SARM gem5 DevelopersCXX_version = readCommand([main['CXX'],'--version'], exception=False) 54410037SARM gem5 DevelopersCXX_V = readCommand([main['CXX'],'-V'], exception=False) 54510037SARM gem5 Developers 54610037SARM gem5 Developersmain['GCC'] = CXX_version and CXX_version.find('g++') >= 0 54710037SARM gem5 Developersmain['CLANG'] = CXX_version and CXX_version.find('clang') >= 0 54810037SARM gem5 Developersif main['GCC'] + main['CLANG'] > 1: 54910037SARM gem5 Developers print 'Error: How can we have two at the same time?' 55010037SARM gem5 Developers Exit(1) 55110037SARM gem5 Developers 55210037SARM gem5 Developers# Set up default C++ compiler flags 55310037SARM gem5 Developersif main['GCC'] or main['CLANG']: 55410037SARM gem5 Developers # As gcc and clang share many flags, do the common parts here 55510037SARM gem5 Developers main.Append(CCFLAGS=['-pipe']) 55610037SARM gem5 Developers main.Append(CCFLAGS=['-fno-strict-aliasing']) 55710037SARM gem5 Developers # Enable -Wall and -Wextra and then disable the few warnings that 55810037SARM gem5 Developers # we consistently violate 55910037SARM gem5 Developers main.Append(CCFLAGS=['-Wall', '-Wundef', '-Wextra', 56010037SARM gem5 Developers '-Wno-sign-compare', '-Wno-unused-parameter']) 56110037SARM gem5 Developers # We always compile using C++11 56210037SARM gem5 Developers main.Append(CXXFLAGS=['-std=c++11']) 56310037SARM gem5 Developerselse: 56410037SARM gem5 Developers print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal, 56510037SARM gem5 Developers print "Don't know what compiler options to use for your compiler." 56610037SARM gem5 Developers print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX'] 56710037SARM gem5 Developers print termcap.Yellow + ' version:' + termcap.Normal, 5687148Sgblack@eecs.umich.edu if not CXX_version: 5697142Sgblack@eecs.umich.edu print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\ 5707142Sgblack@eecs.umich.edu termcap.Normal 57111371Snathanael.premillieu@arm.com else: 5726264Sgblack@eecs.umich.edu print CXX_version.replace('\n', '<nl>') 5737142Sgblack@eecs.umich.edu print " If you're trying to use a compiler other than GCC" 5746264Sgblack@eecs.umich.edu print " or clang, there appears to be something wrong with your" 5756264Sgblack@eecs.umich.edu print " environment." 5766264Sgblack@eecs.umich.edu print " " 5777142Sgblack@eecs.umich.edu print " If you are trying to use a compiler other than those listed" 5786264Sgblack@eecs.umich.edu print " above you will need to ease fix SConstruct and " 57912104Snathanael.premillieu@arm.com print " src/SConscript to support that compiler." 5806264Sgblack@eecs.umich.edu Exit(1) 5816264Sgblack@eecs.umich.edu 5826264Sgblack@eecs.umich.eduif main['GCC']: 5837142Sgblack@eecs.umich.edu # Check for a supported version of gcc. >= 4.7 is chosen for its 5846264Sgblack@eecs.umich.edu # level of c++11 support. See 5856264Sgblack@eecs.umich.edu # http://gcc.gnu.org/projects/cxx0x.html for details. 5866264Sgblack@eecs.umich.edu gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False) 58712104Snathanael.premillieu@arm.com if compareVersions(gcc_version, "4.7") < 0: 5886264Sgblack@eecs.umich.edu print 'Error: gcc version 4.7 or newer required.' 5896264Sgblack@eecs.umich.edu print ' Installed version:', gcc_version 5906264Sgblack@eecs.umich.edu Exit(1) 5916264Sgblack@eecs.umich.edu 5926306Sgblack@eecs.umich.edu main['GCC_VERSION'] = gcc_version 59311371Snathanael.premillieu@arm.com 5946306Sgblack@eecs.umich.edu # gcc from version 4.8 and above generates "rep; ret" instructions 5957142Sgblack@eecs.umich.edu # to avoid performance penalties on certain AMD chips. Older 5966306Sgblack@eecs.umich.edu # assemblers detect this as an error, "Error: expecting string 5976264Sgblack@eecs.umich.edu # instruction after `rep'" 5986264Sgblack@eecs.umich.edu if compareVersions(gcc_version, "4.8") > 0: 5996254Sgblack@eecs.umich.edu as_version_raw = readCommand([main['AS'], '-v', '/dev/null'], 6007148Sgblack@eecs.umich.edu exception=False).split() 6016254Sgblack@eecs.umich.edu 6026253Sgblack@eecs.umich.edu # version strings may contain extra distro-specific 6036253Sgblack@eecs.umich.edu # qualifiers, so play it safe and keep only what comes before 6046262Sgblack@eecs.umich.edu # the first hyphen 6056253Sgblack@eecs.umich.edu as_version = as_version_raw[-1].split('-')[0] if as_version_raw \ 6066253Sgblack@eecs.umich.edu else None 60711513Sandreas.sandberg@arm.com 60811513Sandreas.sandberg@arm.com if not as_version or compareVersions(as_version, "2.23") < 0: 60911513Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + \ 61011513Sandreas.sandberg@arm.com 'Warning: This combination of gcc and binutils have' + \ 61111513Sandreas.sandberg@arm.com ' known incompatibilities.\n' + \ 61211513Sandreas.sandberg@arm.com ' If you encounter build problems, please update ' + \ 61311513Sandreas.sandberg@arm.com 'binutils to 2.23.' + \ 61411513Sandreas.sandberg@arm.com termcap.Normal 61511513Sandreas.sandberg@arm.com 61611513Sandreas.sandberg@arm.com # Make sure we warn if the user has requested to compile with the 61711513Sandreas.sandberg@arm.com # Undefined Benahvior Sanitizer and this version of gcc does not 61811513Sandreas.sandberg@arm.com # support it. 61911513Sandreas.sandberg@arm.com if GetOption('with_ubsan') and \ 62011513Sandreas.sandberg@arm.com compareVersions(gcc_version, '4.9') < 0: 62111513Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + \ 62211513Sandreas.sandberg@arm.com 'Warning: UBSan is only supported using gcc 4.9 and later.' + \ 62311513Sandreas.sandberg@arm.com termcap.Normal 62411513Sandreas.sandberg@arm.com 62511513Sandreas.sandberg@arm.com # Add the appropriate Link-Time Optimization (LTO) flags 6266253Sgblack@eecs.umich.edu # unless LTO is explicitly turned off. Note that these flags 62711513Sandreas.sandberg@arm.com # are only used by the fast target. 62811513Sandreas.sandberg@arm.com if not GetOption('no_lto'): 62911513Sandreas.sandberg@arm.com # Pass the LTO flag when compiling to produce GIMPLE 63011513Sandreas.sandberg@arm.com # output, we merely create the flags here and only append 63111513Sandreas.sandberg@arm.com # them later 63211513Sandreas.sandberg@arm.com main['LTO_CCFLAGS'] = ['-flto=%d' % GetOption('num_jobs')] 63311513Sandreas.sandberg@arm.com 63411513Sandreas.sandberg@arm.com # Use the same amount of jobs for LTO as we are running 63511513Sandreas.sandberg@arm.com # scons with 63611513Sandreas.sandberg@arm.com main['LTO_LDFLAGS'] = ['-flto=%d' % GetOption('num_jobs')] 63711513Sandreas.sandberg@arm.com 63811513Sandreas.sandberg@arm.com main.Append(TCMALLOC_CCFLAGS=['-fno-builtin-malloc', '-fno-builtin-calloc', 63911513Sandreas.sandberg@arm.com '-fno-builtin-realloc', '-fno-builtin-free']) 64011513Sandreas.sandberg@arm.com 64111513Sandreas.sandberg@arm.comelif main['CLANG']: 64211513Sandreas.sandberg@arm.com # Check for a supported version of clang, >= 3.1 is needed to 64311513Sandreas.sandberg@arm.com # support similar features as gcc 4.7. See 64411513Sandreas.sandberg@arm.com # http://clang.llvm.org/cxx_status.html for details 64511513Sandreas.sandberg@arm.com clang_version_re = re.compile(".* version (\d+\.\d+)") 64611513Sandreas.sandberg@arm.com clang_version_match = clang_version_re.search(CXX_version) 64711513Sandreas.sandberg@arm.com if (clang_version_match): 64811513Sandreas.sandberg@arm.com clang_version = clang_version_match.groups()[0] 64911513Sandreas.sandberg@arm.com if compareVersions(clang_version, "3.1") < 0: 65011513Sandreas.sandberg@arm.com print 'Error: clang version 3.1 or newer required.' 65111513Sandreas.sandberg@arm.com print ' Installed version:', clang_version 65211513Sandreas.sandberg@arm.com Exit(1) 65311513Sandreas.sandberg@arm.com else: 65411513Sandreas.sandberg@arm.com print 'Error: Unable to determine clang version.' 65511513Sandreas.sandberg@arm.com Exit(1) 65611513Sandreas.sandberg@arm.com 65711513Sandreas.sandberg@arm.com # clang has a few additional warnings that we disable, extraneous 65811513Sandreas.sandberg@arm.com # parantheses are allowed due to Ruby's printing of the AST, 65911513Sandreas.sandberg@arm.com # finally self assignments are allowed as the generated CPU code 66011513Sandreas.sandberg@arm.com # is relying on this 66111513Sandreas.sandberg@arm.com main.Append(CCFLAGS=['-Wno-parentheses', 66211513Sandreas.sandberg@arm.com '-Wno-self-assign', 66311513Sandreas.sandberg@arm.com # Some versions of libstdc++ (4.8?) seem to 66411513Sandreas.sandberg@arm.com # use struct hash and class hash 66511513Sandreas.sandberg@arm.com # interchangeably. 66611513Sandreas.sandberg@arm.com '-Wno-mismatched-tags', 66711513Sandreas.sandberg@arm.com ]) 66811513Sandreas.sandberg@arm.com 66911513Sandreas.sandberg@arm.com main.Append(TCMALLOC_CCFLAGS=['-fno-builtin']) 67011513Sandreas.sandberg@arm.com 67111513Sandreas.sandberg@arm.com # On Mac OS X/Darwin we need to also use libc++ (part of XCode) as 67211513Sandreas.sandberg@arm.com # opposed to libstdc++, as the later is dated. 67311513Sandreas.sandberg@arm.com if sys.platform == "darwin": 67411513Sandreas.sandberg@arm.com main.Append(CXXFLAGS=['-stdlib=libc++']) 67511513Sandreas.sandberg@arm.com main.Append(LIBS=['c++']) 67611513Sandreas.sandberg@arm.com 67711513Sandreas.sandberg@arm.comelse: 67811513Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal, 67911513Sandreas.sandberg@arm.com print "Don't know what compiler options to use for your compiler." 68011513Sandreas.sandberg@arm.com print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX'] 68111513Sandreas.sandberg@arm.com print termcap.Yellow + ' version:' + termcap.Normal, 68211513Sandreas.sandberg@arm.com if not CXX_version: 68311513Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\ 68411513Sandreas.sandberg@arm.com termcap.Normal 68511513Sandreas.sandberg@arm.com else: 68611513Sandreas.sandberg@arm.com print CXX_version.replace('\n', '<nl>') 68711513Sandreas.sandberg@arm.com print " If you're trying to use a compiler other than GCC" 68811513Sandreas.sandberg@arm.com print " or clang, there appears to be something wrong with your" 68911513Sandreas.sandberg@arm.com print " environment." 69011513Sandreas.sandberg@arm.com print " " 69111513Sandreas.sandberg@arm.com print " If you are trying to use a compiler other than those listed" 69211513Sandreas.sandberg@arm.com print " above you will need to ease fix SConstruct and " 69311513Sandreas.sandberg@arm.com print " src/SConscript to support that compiler." 69411513Sandreas.sandberg@arm.com Exit(1) 69511513Sandreas.sandberg@arm.com 69611513Sandreas.sandberg@arm.com# Set up common yacc/bison flags (needed for Ruby) 69711513Sandreas.sandberg@arm.commain['YACCFLAGS'] = '-d' 69811513Sandreas.sandberg@arm.commain['YACCHXXFILESUFFIX'] = '.hh' 69911513Sandreas.sandberg@arm.com 70011513Sandreas.sandberg@arm.com# Do this after we save setting back, or else we'll tack on an 70111513Sandreas.sandberg@arm.com# extra 'qdo' every time we run scons. 70211513Sandreas.sandberg@arm.comif main['BATCH']: 70311513Sandreas.sandberg@arm.com main['CC'] = main['BATCH_CMD'] + ' ' + main['CC'] 70411513Sandreas.sandberg@arm.com main['CXX'] = main['BATCH_CMD'] + ' ' + main['CXX'] 70511513Sandreas.sandberg@arm.com main['AS'] = main['BATCH_CMD'] + ' ' + main['AS'] 70611513Sandreas.sandberg@arm.com main['AR'] = main['BATCH_CMD'] + ' ' + main['AR'] 70711513Sandreas.sandberg@arm.com main['RANLIB'] = main['BATCH_CMD'] + ' ' + main['RANLIB'] 70811513Sandreas.sandberg@arm.com 70911513Sandreas.sandberg@arm.comif sys.platform == 'cygwin': 71011513Sandreas.sandberg@arm.com # cygwin has some header file issues... 71111513Sandreas.sandberg@arm.com main.Append(CCFLAGS=["-Wno-uninitialized"]) 71211513Sandreas.sandberg@arm.com 71311513Sandreas.sandberg@arm.com# Check for the protobuf compiler 71411513Sandreas.sandberg@arm.comprotoc_version = readCommand([main['PROTOC'], '--version'], 71511513Sandreas.sandberg@arm.com exception='').split() 71611513Sandreas.sandberg@arm.com 71711513Sandreas.sandberg@arm.com# First two words should be "libprotoc x.y.z" 71811513Sandreas.sandberg@arm.comif len(protoc_version) < 2 or protoc_version[0] != 'libprotoc': 71911513Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + \ 72011513Sandreas.sandberg@arm.com 'Warning: Protocol buffer compiler (protoc) not found.\n' + \ 72111513Sandreas.sandberg@arm.com ' Please install protobuf-compiler for tracing support.' + \ 72211513Sandreas.sandberg@arm.com termcap.Normal 72311513Sandreas.sandberg@arm.com main['PROTOC'] = False 72411513Sandreas.sandberg@arm.comelse: 72511513Sandreas.sandberg@arm.com # Based on the availability of the compress stream wrappers, 72611513Sandreas.sandberg@arm.com # require 2.1.0 72711513Sandreas.sandberg@arm.com min_protoc_version = '2.1.0' 72811513Sandreas.sandberg@arm.com if compareVersions(protoc_version[1], min_protoc_version) < 0: 72911513Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + \ 73011513Sandreas.sandberg@arm.com 'Warning: protoc version', min_protoc_version, \ 73111513Sandreas.sandberg@arm.com 'or newer required.\n' + \ 73211513Sandreas.sandberg@arm.com ' Installed version:', protoc_version[1], \ 73311513Sandreas.sandberg@arm.com termcap.Normal 73411513Sandreas.sandberg@arm.com main['PROTOC'] = False 73511513Sandreas.sandberg@arm.com else: 73611513Sandreas.sandberg@arm.com # Attempt to determine the appropriate include path and 73711513Sandreas.sandberg@arm.com # library path using pkg-config, that means we also need to 73812403Sgiacomo.travaglini@arm.com # check for pkg-config. Note that it is possible to use 73912403Sgiacomo.travaglini@arm.com # protobuf without the involvement of pkg-config. Later on we 74012403Sgiacomo.travaglini@arm.com # check go a library config check and at that point the test 74112403Sgiacomo.travaglini@arm.com # will fail if libprotobuf cannot be found. 74212403Sgiacomo.travaglini@arm.com if readCommand(['pkg-config', '--version'], exception=''): 74312403Sgiacomo.travaglini@arm.com try: 74412403Sgiacomo.travaglini@arm.com # Attempt to establish what linking flags to add for protobuf 74512403Sgiacomo.travaglini@arm.com # using pkg-config 74612403Sgiacomo.travaglini@arm.com main.ParseConfig('pkg-config --cflags --libs-only-L protobuf') 74712403Sgiacomo.travaglini@arm.com except: 74812403Sgiacomo.travaglini@arm.com print termcap.Yellow + termcap.Bold + \ 74912403Sgiacomo.travaglini@arm.com 'Warning: pkg-config could not get protobuf flags.' + \ 75012403Sgiacomo.travaglini@arm.com termcap.Normal 75112403Sgiacomo.travaglini@arm.com 75212403Sgiacomo.travaglini@arm.com# Check for SWIG 75312403Sgiacomo.travaglini@arm.comif not main.has_key('SWIG'): 75412403Sgiacomo.travaglini@arm.com print 'Error: SWIG utility not found.' 75512403Sgiacomo.travaglini@arm.com print ' Please install (see http://www.swig.org) and retry.' 75612403Sgiacomo.travaglini@arm.com Exit(1) 75712403Sgiacomo.travaglini@arm.com 75812403Sgiacomo.travaglini@arm.com# Check for appropriate SWIG version 75912403Sgiacomo.travaglini@arm.comswig_version = readCommand([main['SWIG'], '-version'], exception='').split() 76012403Sgiacomo.travaglini@arm.com# First 3 words should be "SWIG Version x.y.z" 76112403Sgiacomo.travaglini@arm.comif len(swig_version) < 3 or \ 76212403Sgiacomo.travaglini@arm.com swig_version[0] != 'SWIG' or swig_version[1] != 'Version': 76312403Sgiacomo.travaglini@arm.com print 'Error determining SWIG version.' 76412403Sgiacomo.travaglini@arm.com Exit(1) 76512403Sgiacomo.travaglini@arm.com 76612403Sgiacomo.travaglini@arm.commin_swig_version = '2.0.4' 76712403Sgiacomo.travaglini@arm.comif compareVersions(swig_version[2], min_swig_version) < 0: 76812403Sgiacomo.travaglini@arm.com print 'Error: SWIG version', min_swig_version, 'or newer required.' 76912403Sgiacomo.travaglini@arm.com print ' Installed version:', swig_version[2] 77012403Sgiacomo.travaglini@arm.com Exit(1) 77112403Sgiacomo.travaglini@arm.com 77212403Sgiacomo.travaglini@arm.com# Check for known incompatibilities. The standard library shipped with 77312403Sgiacomo.travaglini@arm.com# gcc >= 4.9 does not play well with swig versions prior to 3.0 77412403Sgiacomo.travaglini@arm.comif main['GCC'] and compareVersions(gcc_version, '4.9') >= 0 and \ 77512403Sgiacomo.travaglini@arm.com compareVersions(swig_version[2], '3.0') < 0: 77612403Sgiacomo.travaglini@arm.com print termcap.Yellow + termcap.Bold + \ 77712403Sgiacomo.travaglini@arm.com 'Warning: This combination of gcc and swig have' + \ 77812403Sgiacomo.travaglini@arm.com ' known incompatibilities.\n' + \ 77912403Sgiacomo.travaglini@arm.com ' If you encounter build problems, please update ' + \ 78012403Sgiacomo.travaglini@arm.com 'swig to 3.0 or later.' + \ 78112403Sgiacomo.travaglini@arm.com termcap.Normal 78212403Sgiacomo.travaglini@arm.com 78312403Sgiacomo.travaglini@arm.com# Set up SWIG flags & scanner 78412403Sgiacomo.travaglini@arm.comswig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS') 78512403Sgiacomo.travaglini@arm.commain.Append(SWIGFLAGS=swig_flags) 78612403Sgiacomo.travaglini@arm.com 78712403Sgiacomo.travaglini@arm.com# Check for 'timeout' from GNU coreutils. If present, regressions will 78812403Sgiacomo.travaglini@arm.com# be run with a time limit. We require version 8.13 since we rely on 78912403Sgiacomo.travaglini@arm.com# support for the '--foreground' option. 79012403Sgiacomo.travaglini@arm.comtimeout_lines = readCommand(['timeout', '--version'], 79112403Sgiacomo.travaglini@arm.com exception='').splitlines() 79212403Sgiacomo.travaglini@arm.com# Get the first line and tokenize it 79312403Sgiacomo.travaglini@arm.comtimeout_version = timeout_lines[0].split() if timeout_lines else [] 79412403Sgiacomo.travaglini@arm.commain['TIMEOUT'] = timeout_version and \ 79512403Sgiacomo.travaglini@arm.com compareVersions(timeout_version[-1], '8.13') >= 0 79612403Sgiacomo.travaglini@arm.com 79712403Sgiacomo.travaglini@arm.com# filter out all existing swig scanners, they mess up the dependency 79812403Sgiacomo.travaglini@arm.com# stuff for some reason 79912403Sgiacomo.travaglini@arm.comscanners = [] 80012403Sgiacomo.travaglini@arm.comfor scanner in main['SCANNERS']: 80112403Sgiacomo.travaglini@arm.com skeys = scanner.skeys 80212403Sgiacomo.travaglini@arm.com if skeys == '.i': 80312403Sgiacomo.travaglini@arm.com continue 80412403Sgiacomo.travaglini@arm.com 80512403Sgiacomo.travaglini@arm.com if isinstance(skeys, (list, tuple)) and '.i' in skeys: 80612403Sgiacomo.travaglini@arm.com continue 80712403Sgiacomo.travaglini@arm.com 80812403Sgiacomo.travaglini@arm.com scanners.append(scanner) 80912403Sgiacomo.travaglini@arm.com 81012403Sgiacomo.travaglini@arm.com# add the new swig scanner that we like better 81112403Sgiacomo.travaglini@arm.comfrom SCons.Scanner import ClassicCPP as CPPScanner 81212403Sgiacomo.travaglini@arm.comswig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")' 81312403Sgiacomo.travaglini@arm.comscanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re)) 81412403Sgiacomo.travaglini@arm.com 81512403Sgiacomo.travaglini@arm.com# replace the scanners list that has what we want 81612403Sgiacomo.travaglini@arm.commain['SCANNERS'] = scanners 81712403Sgiacomo.travaglini@arm.com 81812403Sgiacomo.travaglini@arm.com# Add a custom Check function to test for structure members. 81912403Sgiacomo.travaglini@arm.comdef CheckMember(context, include, decl, member, include_quotes="<>"): 82012403Sgiacomo.travaglini@arm.com context.Message("Checking for member %s in %s..." % 82112403Sgiacomo.travaglini@arm.com (member, decl)) 82212403Sgiacomo.travaglini@arm.com text = """ 82312403Sgiacomo.travaglini@arm.com#include %(header)s 82412403Sgiacomo.travaglini@arm.comint main(){ 82512403Sgiacomo.travaglini@arm.com %(decl)s test; 82612403Sgiacomo.travaglini@arm.com (void)test.%(member)s; 82712403Sgiacomo.travaglini@arm.com return 0; 82812403Sgiacomo.travaglini@arm.com}; 82912403Sgiacomo.travaglini@arm.com""" % { "header" : include_quotes[0] + include + include_quotes[1], 83012403Sgiacomo.travaglini@arm.com "decl" : decl, 83112403Sgiacomo.travaglini@arm.com "member" : member, 83212403Sgiacomo.travaglini@arm.com } 83312403Sgiacomo.travaglini@arm.com 83412403Sgiacomo.travaglini@arm.com ret = context.TryCompile(text, extension=".cc") 83512403Sgiacomo.travaglini@arm.com context.Result(ret) 83612403Sgiacomo.travaglini@arm.com return ret 83712403Sgiacomo.travaglini@arm.com 83812403Sgiacomo.travaglini@arm.com# Platform-specific configuration. Note again that we assume that all 83912403Sgiacomo.travaglini@arm.com# builds under a given build root run on the same host platform. 84012403Sgiacomo.travaglini@arm.comconf = Configure(main, 84112403Sgiacomo.travaglini@arm.com conf_dir = joinpath(build_root, '.scons_config'), 84212403Sgiacomo.travaglini@arm.com log_file = joinpath(build_root, 'scons_config.log'), 84312403Sgiacomo.travaglini@arm.com custom_tests = { 84412403Sgiacomo.travaglini@arm.com 'CheckMember' : CheckMember, 84512403Sgiacomo.travaglini@arm.com }) 84612403Sgiacomo.travaglini@arm.com 84712403Sgiacomo.travaglini@arm.com# Check if we should compile a 64 bit binary on Mac OS X/Darwin 84812403Sgiacomo.travaglini@arm.comtry: 84912403Sgiacomo.travaglini@arm.com import platform 85012403Sgiacomo.travaglini@arm.com uname = platform.uname() 85112403Sgiacomo.travaglini@arm.com if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: 85212403Sgiacomo.travaglini@arm.com if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): 85312403Sgiacomo.travaglini@arm.com main.Append(CCFLAGS=['-arch', 'x86_64']) 85412403Sgiacomo.travaglini@arm.com main.Append(CFLAGS=['-arch', 'x86_64']) 85512403Sgiacomo.travaglini@arm.com main.Append(LINKFLAGS=['-arch', 'x86_64']) 85612403Sgiacomo.travaglini@arm.com main.Append(ASFLAGS=['-arch', 'x86_64']) 85712403Sgiacomo.travaglini@arm.comexcept: 85812403Sgiacomo.travaglini@arm.com pass 85912403Sgiacomo.travaglini@arm.com 86012403Sgiacomo.travaglini@arm.com# Recent versions of scons substitute a "Null" object for Configure() 86111513Sandreas.sandberg@arm.com# when configuration isn't necessary, e.g., if the "--help" option is 86212498Sgiacomo.travaglini@arm.com# present. Unfortuantely this Null object always returns false, 86312498Sgiacomo.travaglini@arm.com# breaking all our configuration checks. We replace it with our own 86412498Sgiacomo.travaglini@arm.com# more optimistic null object that returns True instead. 86512498Sgiacomo.travaglini@arm.comif not conf: 86612498Sgiacomo.travaglini@arm.com def NullCheck(*args, **kwargs): 86712498Sgiacomo.travaglini@arm.com return True 86812498Sgiacomo.travaglini@arm.com 86912498Sgiacomo.travaglini@arm.com class NullConf: 87012498Sgiacomo.travaglini@arm.com def __init__(self, env): 87112498Sgiacomo.travaglini@arm.com self.env = env 87212498Sgiacomo.travaglini@arm.com def Finish(self): 87312498Sgiacomo.travaglini@arm.com return self.env 87412498Sgiacomo.travaglini@arm.com def __getattr__(self, mname): 87512498Sgiacomo.travaglini@arm.com return NullCheck 87612498Sgiacomo.travaglini@arm.com 87712498Sgiacomo.travaglini@arm.com conf = NullConf(main) 87812498Sgiacomo.travaglini@arm.com 87912498Sgiacomo.travaglini@arm.com# Cache build files in the supplied directory. 88012498Sgiacomo.travaglini@arm.comif main['M5_BUILD_CACHE']: 88112498Sgiacomo.travaglini@arm.com print 'Using build cache located at', main['M5_BUILD_CACHE'] 88212498Sgiacomo.travaglini@arm.com CacheDir(main['M5_BUILD_CACHE']) 88312499Sgiacomo.travaglini@arm.com 88412498Sgiacomo.travaglini@arm.comif not GetOption('without_python'): 88512498Sgiacomo.travaglini@arm.com # Find Python include and library directories for embedding the 88612498Sgiacomo.travaglini@arm.com # interpreter. We rely on python-config to resolve the appropriate 88712498Sgiacomo.travaglini@arm.com # includes and linker flags. ParseConfig does not seem to understand 88812498Sgiacomo.travaglini@arm.com # the more exotic linker flags such as -Xlinker and -export-dynamic so 88912498Sgiacomo.travaglini@arm.com # we add them explicitly below. If you want to link in an alternate 89012498Sgiacomo.travaglini@arm.com # version of python, see above for instructions on how to invoke 89112498Sgiacomo.travaglini@arm.com # scons with the appropriate PATH set. 89212498Sgiacomo.travaglini@arm.com # 89312498Sgiacomo.travaglini@arm.com # First we check if python2-config exists, else we use python-config 89412498Sgiacomo.travaglini@arm.com python_config = readCommand(['which', 'python2-config'], 89512498Sgiacomo.travaglini@arm.com exception='').strip() 89612498Sgiacomo.travaglini@arm.com if not os.path.exists(python_config): 89712498Sgiacomo.travaglini@arm.com python_config = readCommand(['which', 'python-config'], 89812498Sgiacomo.travaglini@arm.com exception='').strip() 89912498Sgiacomo.travaglini@arm.com py_includes = readCommand([python_config, '--includes'], 90012498Sgiacomo.travaglini@arm.com exception='').split() 90112498Sgiacomo.travaglini@arm.com # Strip the -I from the include folders before adding them to the 90212498Sgiacomo.travaglini@arm.com # CPPPATH 90312498Sgiacomo.travaglini@arm.com main.Append(CPPPATH=map(lambda inc: inc[2:], py_includes)) 90412498Sgiacomo.travaglini@arm.com 90512498Sgiacomo.travaglini@arm.com # Read the linker flags and split them into libraries and other link 90612498Sgiacomo.travaglini@arm.com # flags. The libraries are added later through the call the CheckLib. 90712498Sgiacomo.travaglini@arm.com py_ld_flags = readCommand([python_config, '--ldflags'], 90812498Sgiacomo.travaglini@arm.com exception='').split() 90912498Sgiacomo.travaglini@arm.com py_libs = [] 91012498Sgiacomo.travaglini@arm.com for lib in py_ld_flags: 91112498Sgiacomo.travaglini@arm.com if not lib.startswith('-l'): 91212498Sgiacomo.travaglini@arm.com main.Append(LINKFLAGS=[lib]) 91312498Sgiacomo.travaglini@arm.com else: 91412498Sgiacomo.travaglini@arm.com lib = lib[2:] 91512498Sgiacomo.travaglini@arm.com if lib not in py_libs: 91612498Sgiacomo.travaglini@arm.com py_libs.append(lib) 91712498Sgiacomo.travaglini@arm.com 91812498Sgiacomo.travaglini@arm.com # verify that this stuff works 91912498Sgiacomo.travaglini@arm.com if not conf.CheckHeader('Python.h', '<>'): 92012498Sgiacomo.travaglini@arm.com print "Error: can't find Python.h header in", py_includes 92112498Sgiacomo.travaglini@arm.com print "Install Python headers (package python-dev on Ubuntu and RedHat)" 92212498Sgiacomo.travaglini@arm.com Exit(1) 92312498Sgiacomo.travaglini@arm.com 92412498Sgiacomo.travaglini@arm.com for lib in py_libs: 92512498Sgiacomo.travaglini@arm.com if not conf.CheckLib(lib): 92612498Sgiacomo.travaglini@arm.com print "Error: can't find library %s required by python" % lib 92712498Sgiacomo.travaglini@arm.com Exit(1) 92812498Sgiacomo.travaglini@arm.com 92912498Sgiacomo.travaglini@arm.com# On Solaris you need to use libsocket for socket ops 93012498Sgiacomo.travaglini@arm.comif not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): 93112498Sgiacomo.travaglini@arm.com if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): 93212498Sgiacomo.travaglini@arm.com print "Can't find library with socket calls (e.g. accept())" 93311514Sandreas.sandberg@arm.com Exit(1) 93411514Sandreas.sandberg@arm.com 93511514Sandreas.sandberg@arm.com# Check for zlib. If the check passes, libz will be automatically 93611514Sandreas.sandberg@arm.com# added to the LIBS environment variable. 93711514Sandreas.sandberg@arm.comif not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'): 93811514Sandreas.sandberg@arm.com print 'Error: did not find needed zlib compression library '\ 93911514Sandreas.sandberg@arm.com 'and/or zlib.h header file.' 94011514Sandreas.sandberg@arm.com print ' Please install zlib and try again.' 94111514Sandreas.sandberg@arm.com Exit(1) 94211514Sandreas.sandberg@arm.com 94311514Sandreas.sandberg@arm.com# If we have the protobuf compiler, also make sure we have the 94411514Sandreas.sandberg@arm.com# development libraries. If the check passes, libprotobuf will be 94511514Sandreas.sandberg@arm.com# automatically added to the LIBS environment variable. After 94611514Sandreas.sandberg@arm.com# this, we can use the HAVE_PROTOBUF flag to determine if we have 94711514Sandreas.sandberg@arm.com# got both protoc and libprotobuf available. 94811514Sandreas.sandberg@arm.commain['HAVE_PROTOBUF'] = main['PROTOC'] and \ 94911514Sandreas.sandberg@arm.com conf.CheckLibWithHeader('protobuf', 'google/protobuf/message.h', 95011514Sandreas.sandberg@arm.com 'C++', 'GOOGLE_PROTOBUF_VERIFY_VERSION;') 95111514Sandreas.sandberg@arm.com 95211514Sandreas.sandberg@arm.com# If we have the compiler but not the library, print another warning. 95311514Sandreas.sandberg@arm.comif main['PROTOC'] and not main['HAVE_PROTOBUF']: 95411514Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + \ 95511514Sandreas.sandberg@arm.com 'Warning: did not find protocol buffer library and/or headers.\n' + \ 95611514Sandreas.sandberg@arm.com ' Please install libprotobuf-dev for tracing support.' + \ 95711514Sandreas.sandberg@arm.com termcap.Normal 95811514Sandreas.sandberg@arm.com 95911514Sandreas.sandberg@arm.com# Check for librt. 96011513Sandreas.sandberg@arm.comhave_posix_clock = \ 96111514Sandreas.sandberg@arm.com conf.CheckLibWithHeader(None, 'time.h', 'C', 96211514Sandreas.sandberg@arm.com 'clock_nanosleep(0,0,NULL,NULL);') or \ 96311514Sandreas.sandberg@arm.com conf.CheckLibWithHeader('rt', 'time.h', 'C', 96411514Sandreas.sandberg@arm.com 'clock_nanosleep(0,0,NULL,NULL);') 96511514Sandreas.sandberg@arm.com 96611514Sandreas.sandberg@arm.comhave_posix_timers = \ 96711514Sandreas.sandberg@arm.com conf.CheckLibWithHeader([None, 'rt'], [ 'time.h', 'signal.h' ], 'C', 96811514Sandreas.sandberg@arm.com 'timer_create(CLOCK_MONOTONIC, NULL, NULL);') 96911514Sandreas.sandberg@arm.com 97011514Sandreas.sandberg@arm.comif not GetOption('without_tcmalloc'): 97112497Sgiacomo.travaglini@arm.com if conf.CheckLib('tcmalloc'): 97212497Sgiacomo.travaglini@arm.com main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS']) 97312497Sgiacomo.travaglini@arm.com elif conf.CheckLib('tcmalloc_minimal'): 97412497Sgiacomo.travaglini@arm.com main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS']) 97511514Sandreas.sandberg@arm.com else: 97611514Sandreas.sandberg@arm.com print termcap.Yellow + termcap.Bold + \ 97711514Sandreas.sandberg@arm.com "You can get a 12% performance improvement by "\ 97812497Sgiacomo.travaglini@arm.com "installing tcmalloc (libgoogle-perftools-dev package "\ 97911514Sandreas.sandberg@arm.com "on Ubuntu or RedHat)." + termcap.Normal 98011514Sandreas.sandberg@arm.com 98112497Sgiacomo.travaglini@arm.com 98212497Sgiacomo.travaglini@arm.com# Detect back trace implementations. The last implementation in the 98312497Sgiacomo.travaglini@arm.com# list will be used by default. 98412497Sgiacomo.travaglini@arm.combacktrace_impls = [ "none" ] 98512497Sgiacomo.travaglini@arm.com 98612497Sgiacomo.travaglini@arm.comif conf.CheckLibWithHeader(None, 'execinfo.h', 'C', 98712497Sgiacomo.travaglini@arm.com 'backtrace_symbols_fd((void*)0, 0, 0);'): 98812497Sgiacomo.travaglini@arm.com backtrace_impls.append("glibc") 98912497Sgiacomo.travaglini@arm.com 99012497Sgiacomo.travaglini@arm.comif backtrace_impls[-1] == "none": 99112497Sgiacomo.travaglini@arm.com default_backtrace_impl = "none" 99212497Sgiacomo.travaglini@arm.com print termcap.Yellow + termcap.Bold + \ 99311514Sandreas.sandberg@arm.com "No suitable back trace implementation found." + \ 99411514Sandreas.sandberg@arm.com termcap.Normal 99511514Sandreas.sandberg@arm.com 99611514Sandreas.sandberg@arm.comif not have_posix_clock: 99711514Sandreas.sandberg@arm.com print "Can't find library for POSIX clocks." 99811514Sandreas.sandberg@arm.com 99911514Sandreas.sandberg@arm.com# Check for <fenv.h> (C99 FP environment control) 100011514Sandreas.sandberg@arm.comhave_fenv = conf.CheckHeader('fenv.h', '<>') 100111514Sandreas.sandberg@arm.comif not have_fenv: 100211514Sandreas.sandberg@arm.com print "Warning: Header file <fenv.h> not found." 100311514Sandreas.sandberg@arm.com print " This host has no IEEE FP rounding mode control." 100412497Sgiacomo.travaglini@arm.com 100511514Sandreas.sandberg@arm.com# Check if we should enable KVM-based hardware virtualization. The API 100611514Sandreas.sandberg@arm.com# we rely on exists since version 2.6.36 of the kernel, but somehow 100711514Sandreas.sandberg@arm.com# the KVM_API_VERSION does not reflect the change. We test for one of 100811514Sandreas.sandberg@arm.com# the types as a fall back. 100911514Sandreas.sandberg@arm.comhave_kvm = conf.CheckHeader('linux/kvm.h', '<>') 101011514Sandreas.sandberg@arm.comif not have_kvm: 101111514Sandreas.sandberg@arm.com print "Info: Compatible header file <linux/kvm.h> not found, " \ 101211514Sandreas.sandberg@arm.com "disabling KVM support." 101311514Sandreas.sandberg@arm.com 101411514Sandreas.sandberg@arm.com# x86 needs support for xsave. We test for the structure here since we 101511514Sandreas.sandberg@arm.com# won't be able to run new tests by the time we know which ISA we're 101611514Sandreas.sandberg@arm.com# targeting. 101711514Sandreas.sandberg@arm.comhave_kvm_xsave = conf.CheckTypeSize('struct kvm_xsave', 101811514Sandreas.sandberg@arm.com '#include <linux/kvm.h>') != 0 101911514Sandreas.sandberg@arm.com 102011514Sandreas.sandberg@arm.com# Check if the requested target ISA is compatible with the host 102112510Sgiacomo.travaglini@arm.comdef is_isa_kvm_compatible(isa): 102212510Sgiacomo.travaglini@arm.com try: 102312510Sgiacomo.travaglini@arm.com import platform 102411514Sandreas.sandberg@arm.com host_isa = platform.machine() 102512510Sgiacomo.travaglini@arm.com except: 102612510Sgiacomo.travaglini@arm.com print "Warning: Failed to determine host ISA." 102712510Sgiacomo.travaglini@arm.com return False 102812510Sgiacomo.travaglini@arm.com 102912510Sgiacomo.travaglini@arm.com if not have_posix_timers: 103012510Sgiacomo.travaglini@arm.com print "Warning: Can not enable KVM, host seems to lack support " \ 103112510Sgiacomo.travaglini@arm.com "for POSIX timers" 103211514Sandreas.sandberg@arm.com return False 103311514Sandreas.sandberg@arm.com 103411514Sandreas.sandberg@arm.com if isa == "arm": 103511514Sandreas.sandberg@arm.com return host_isa in ( "armv7l", "aarch64" ) 103611514Sandreas.sandberg@arm.com elif isa == "x86": 103711514Sandreas.sandberg@arm.com if host_isa != "x86_64": 103811514Sandreas.sandberg@arm.com return False 103911514Sandreas.sandberg@arm.com 104011514Sandreas.sandberg@arm.com if not have_kvm_xsave: 104111514Sandreas.sandberg@arm.com print "KVM on x86 requires xsave support in kernel headers." 104211514Sandreas.sandberg@arm.com return False 104311514Sandreas.sandberg@arm.com 104411514Sandreas.sandberg@arm.com return True 104511514Sandreas.sandberg@arm.com else: 104611514Sandreas.sandberg@arm.com return False 104711514Sandreas.sandberg@arm.com 104811514Sandreas.sandberg@arm.com 104911514Sandreas.sandberg@arm.com# Check if the exclude_host attribute is available. We want this to 105011514Sandreas.sandberg@arm.com# get accurate instruction counts in KVM. 105111514Sandreas.sandberg@arm.commain['HAVE_PERF_ATTR_EXCLUDE_HOST'] = conf.CheckMember( 105211514Sandreas.sandberg@arm.com 'linux/perf_event.h', 'struct perf_event_attr', 'exclude_host') 105311514Sandreas.sandberg@arm.com 105411514Sandreas.sandberg@arm.com 105511514Sandreas.sandberg@arm.com###################################################################### 105611514Sandreas.sandberg@arm.com# 105711514Sandreas.sandberg@arm.com# Finish the configuration 105811514Sandreas.sandberg@arm.com# 105911514Sandreas.sandberg@arm.commain = conf.Finish() 106011514Sandreas.sandberg@arm.com 106111514Sandreas.sandberg@arm.com###################################################################### 106211514Sandreas.sandberg@arm.com# 106311514Sandreas.sandberg@arm.com# Collect all non-global variables 106411514Sandreas.sandberg@arm.com# 106512498Sgiacomo.travaglini@arm.com 106612498Sgiacomo.travaglini@arm.com# Define the universe of supported ISAs 106712498Sgiacomo.travaglini@arm.comall_isa_list = [ ] 106812498Sgiacomo.travaglini@arm.comall_gpu_isa_list = [ ] 106912498Sgiacomo.travaglini@arm.comExport('all_isa_list') 107012498Sgiacomo.travaglini@arm.comExport('all_gpu_isa_list') 107112498Sgiacomo.travaglini@arm.com 107212498Sgiacomo.travaglini@arm.comclass CpuModel(object): 107312498Sgiacomo.travaglini@arm.com '''The CpuModel class encapsulates everything the ISA parser needs to 107412498Sgiacomo.travaglini@arm.com know about a particular CPU model.''' 107512498Sgiacomo.travaglini@arm.com 107612498Sgiacomo.travaglini@arm.com # Dict of available CPU model objects. Accessible as CpuModel.dict. 107711514Sandreas.sandberg@arm.com dict = {} 107811514Sandreas.sandberg@arm.com 107911514Sandreas.sandberg@arm.com # Constructor. Automatically adds models to CpuModel.dict. 1080 def __init__(self, name, default=False): 1081 self.name = name # name of model 1082 1083 # This cpu is enabled by default 1084 self.default = default 1085 1086 # Add self to dict 1087 if name in CpuModel.dict: 1088 raise AttributeError, "CpuModel '%s' already registered" % name 1089 CpuModel.dict[name] = self 1090 1091Export('CpuModel') 1092 1093# Sticky variables get saved in the variables file so they persist from 1094# one invocation to the next (unless overridden, in which case the new 1095# value becomes sticky). 1096sticky_vars = Variables(args=ARGUMENTS) 1097Export('sticky_vars') 1098 1099# Sticky variables that should be exported 1100export_vars = [] 1101Export('export_vars') 1102 1103# For Ruby 1104all_protocols = [] 1105Export('all_protocols') 1106protocol_dirs = [] 1107Export('protocol_dirs') 1108slicc_includes = [] 1109Export('slicc_includes') 1110 1111# Walk the tree and execute all SConsopts scripts that wil add to the 1112# above variables 1113if GetOption('verbose'): 1114 print "Reading SConsopts" 1115for bdir in [ base_dir ] + extras_dir_list: 1116 if not isdir(bdir): 1117 print "Error: directory '%s' does not exist" % bdir 1118 Exit(1) 1119 for root, dirs, files in os.walk(bdir): 1120 if 'SConsopts' in files: 1121 if GetOption('verbose'): 1122 print "Reading", joinpath(root, 'SConsopts') 1123 SConscript(joinpath(root, 'SConsopts')) 1124 1125all_isa_list.sort() 1126all_gpu_isa_list.sort() 1127 1128sticky_vars.AddVariables( 1129 EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), 1130 EnumVariable('TARGET_GPU_ISA', 'Target GPU ISA', 'hsail', all_gpu_isa_list), 1131 ListVariable('CPU_MODELS', 'CPU models', 1132 sorted(n for n,m in CpuModel.dict.iteritems() if m.default), 1133 sorted(CpuModel.dict.keys())), 1134 BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger', 1135 False), 1136 BoolVariable('SS_COMPATIBLE_FP', 1137 'Make floating-point results compatible with SimpleScalar', 1138 False), 1139 BoolVariable('USE_SSE2', 1140 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', 1141 False), 1142 BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock), 1143 BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), 1144 BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), 1145 BoolVariable('USE_KVM', 'Enable hardware virtualized (KVM) CPU models', have_kvm), 1146 BoolVariable('BUILD_GPU', 'Build the compute-GPU model', False), 1147 EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None', 1148 all_protocols), 1149 EnumVariable('BACKTRACE_IMPL', 'Post-mortem dump implementation', 1150 backtrace_impls[-1], backtrace_impls) 1151 ) 1152 1153# These variables get exported to #defines in config/*.hh (see src/SConscript). 1154export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'TARGET_GPU_ISA', 1155 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'PROTOCOL', 1156 'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST'] 1157 1158################################################### 1159# 1160# Define a SCons builder for configuration flag headers. 1161# 1162################################################### 1163 1164# This function generates a config header file that #defines the 1165# variable symbol to the current variable setting (0 or 1). The source 1166# operands are the name of the variable and a Value node containing the 1167# value of the variable. 1168def build_config_file(target, source, env): 1169 (variable, value) = [s.get_contents() for s in source] 1170 f = file(str(target[0]), 'w') 1171 print >> f, '#define', variable, value 1172 f.close() 1173 return None 1174 1175# Combine the two functions into a scons Action object. 1176config_action = MakeAction(build_config_file, Transform("CONFIG H", 2)) 1177 1178# The emitter munges the source & target node lists to reflect what 1179# we're really doing. 1180def config_emitter(target, source, env): 1181 # extract variable name from Builder arg 1182 variable = str(target[0]) 1183 # True target is config header file 1184 target = joinpath('config', variable.lower() + '.hh') 1185 val = env[variable] 1186 if isinstance(val, bool): 1187 # Force value to 0/1 1188 val = int(val) 1189 elif isinstance(val, str): 1190 val = '"' + val + '"' 1191 1192 # Sources are variable name & value (packaged in SCons Value nodes) 1193 return ([target], [Value(variable), Value(val)]) 1194 1195config_builder = Builder(emitter = config_emitter, action = config_action) 1196 1197main.Append(BUILDERS = { 'ConfigFile' : config_builder }) 1198 1199# libelf build is shared across all configs in the build root. 1200main.SConscript('ext/libelf/SConscript', 1201 variant_dir = joinpath(build_root, 'libelf')) 1202 1203# iostream3 build is shared across all configs in the build root. 1204main.SConscript('ext/iostream3/SConscript', 1205 variant_dir = joinpath(build_root, 'iostream3')) 1206 1207# libfdt build is shared across all configs in the build root. 1208main.SConscript('ext/libfdt/SConscript', 1209 variant_dir = joinpath(build_root, 'libfdt')) 1210 1211# fputils build is shared across all configs in the build root. 1212main.SConscript('ext/fputils/SConscript', 1213 variant_dir = joinpath(build_root, 'fputils')) 1214 1215# DRAMSim2 build is shared across all configs in the build root. 1216main.SConscript('ext/dramsim2/SConscript', 1217 variant_dir = joinpath(build_root, 'dramsim2')) 1218 1219# DRAMPower build is shared across all configs in the build root. 1220main.SConscript('ext/drampower/SConscript', 1221 variant_dir = joinpath(build_root, 'drampower')) 1222 1223# nomali build is shared across all configs in the build root. 1224main.SConscript('ext/nomali/SConscript', 1225 variant_dir = joinpath(build_root, 'nomali')) 1226 1227################################################### 1228# 1229# This function is used to set up a directory with switching headers 1230# 1231################################################### 1232 1233main['ALL_ISA_LIST'] = all_isa_list 1234main['ALL_GPU_ISA_LIST'] = all_gpu_isa_list 1235all_isa_deps = {} 1236def make_switching_dir(dname, switch_headers, env): 1237 # Generate the header. target[0] is the full path of the output 1238 # header to generate. 'source' is a dummy variable, since we get the 1239 # list of ISAs from env['ALL_ISA_LIST']. 1240 def gen_switch_hdr(target, source, env): 1241 fname = str(target[0]) 1242 isa = env['TARGET_ISA'].lower() 1243 try: 1244 f = open(fname, 'w') 1245 print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 1246 f.close() 1247 except IOError: 1248 print "Failed to create %s" % fname 1249 raise 1250 1251 # Build SCons Action object. 'varlist' specifies env vars that this 1252 # action depends on; when env['ALL_ISA_LIST'] changes these actions 1253 # should get re-executed. 1254 switch_hdr_action = MakeAction(gen_switch_hdr, 1255 Transform("GENERATE"), varlist=['ALL_ISA_LIST']) 1256 1257 # Instantiate actions for each header 1258 for hdr in switch_headers: 1259 env.Command(hdr, [], switch_hdr_action) 1260 1261 isa_target = Dir('.').up().name.lower().replace('_', '-') 1262 env['PHONY_BASE'] = '#'+isa_target 1263 all_isa_deps[isa_target] = None 1264 1265Export('make_switching_dir') 1266 1267def make_gpu_switching_dir(dname, switch_headers, env): 1268 # Generate the header. target[0] is the full path of the output 1269 # header to generate. 'source' is a dummy variable, since we get the 1270 # list of ISAs from env['ALL_ISA_LIST']. 1271 def gen_switch_hdr(target, source, env): 1272 fname = str(target[0]) 1273 1274 isa = env['TARGET_GPU_ISA'].lower() 1275 1276 try: 1277 f = open(fname, 'w') 1278 print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 1279 f.close() 1280 except IOError: 1281 print "Failed to create %s" % fname 1282 raise 1283 1284 # Build SCons Action object. 'varlist' specifies env vars that this 1285 # action depends on; when env['ALL_ISA_LIST'] changes these actions 1286 # should get re-executed. 1287 switch_hdr_action = MakeAction(gen_switch_hdr, 1288 Transform("GENERATE"), varlist=['ALL_ISA_GPU_LIST']) 1289 1290 # Instantiate actions for each header 1291 for hdr in switch_headers: 1292 env.Command(hdr, [], switch_hdr_action) 1293 1294Export('make_gpu_switching_dir') 1295 1296# all-isas -> all-deps -> all-environs -> all_targets 1297main.Alias('#all-isas', []) 1298main.Alias('#all-deps', '#all-isas') 1299 1300# Dummy target to ensure all environments are created before telling 1301# SCons what to actually make (the command line arguments). We attach 1302# them to the dependence graph after the environments are complete. 1303ORIG_BUILD_TARGETS = list(BUILD_TARGETS) # force a copy; gets closure to work. 1304def environsComplete(target, source, env): 1305 for t in ORIG_BUILD_TARGETS: 1306 main.Depends('#all-targets', t) 1307 1308# Each build/* switching_dir attaches its *-environs target to #all-environs. 1309main.Append(BUILDERS = {'CompleteEnvirons' : 1310 Builder(action=MakeAction(environsComplete, None))}) 1311main.CompleteEnvirons('#all-environs', []) 1312 1313def doNothing(**ignored): pass 1314main.Append(BUILDERS = {'Dummy': Builder(action=MakeAction(doNothing, None))}) 1315 1316# The final target to which all the original targets ultimately get attached. 1317main.Dummy('#all-targets', '#all-environs') 1318BUILD_TARGETS[:] = ['#all-targets'] 1319 1320################################################### 1321# 1322# Define build environments for selected configurations. 1323# 1324################################################### 1325 1326for variant_path in variant_paths: 1327 if not GetOption('silent'): 1328 print "Building in", variant_path 1329 1330 # Make a copy of the build-root environment to use for this config. 1331 env = main.Clone() 1332 env['BUILDDIR'] = variant_path 1333 1334 # variant_dir is the tail component of build path, and is used to 1335 # determine the build parameters (e.g., 'ALPHA_SE') 1336 (build_root, variant_dir) = splitpath(variant_path) 1337 1338 # Set env variables according to the build directory config. 1339 sticky_vars.files = [] 1340 # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in 1341 # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke 1342 # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings. 1343 current_vars_file = joinpath(build_root, 'variables', variant_dir) 1344 if isfile(current_vars_file): 1345 sticky_vars.files.append(current_vars_file) 1346 if not GetOption('silent'): 1347 print "Using saved variables file %s" % current_vars_file 1348 else: 1349 # Build dir-specific variables file doesn't exist. 1350 1351 # Make sure the directory is there so we can create it later 1352 opt_dir = dirname(current_vars_file) 1353 if not isdir(opt_dir): 1354 mkdir(opt_dir) 1355 1356 # Get default build variables from source tree. Variables are 1357 # normally determined by name of $VARIANT_DIR, but can be 1358 # overridden by '--default=' arg on command line. 1359 default = GetOption('default') 1360 opts_dir = joinpath(main.root.abspath, 'build_opts') 1361 if default: 1362 default_vars_files = [joinpath(build_root, 'variables', default), 1363 joinpath(opts_dir, default)] 1364 else: 1365 default_vars_files = [joinpath(opts_dir, variant_dir)] 1366 existing_files = filter(isfile, default_vars_files) 1367 if existing_files: 1368 default_vars_file = existing_files[0] 1369 sticky_vars.files.append(default_vars_file) 1370 print "Variables file %s not found,\n using defaults in %s" \ 1371 % (current_vars_file, default_vars_file) 1372 else: 1373 print "Error: cannot find variables file %s or " \ 1374 "default file(s) %s" \ 1375 % (current_vars_file, ' or '.join(default_vars_files)) 1376 Exit(1) 1377 1378 # Apply current variable settings to env 1379 sticky_vars.Update(env) 1380 1381 help_texts["local_vars"] += \ 1382 "Build variables for %s:\n" % variant_dir \ 1383 + sticky_vars.GenerateHelpText(env) 1384 1385 # Process variable settings. 1386 1387 if not have_fenv and env['USE_FENV']: 1388 print "Warning: <fenv.h> not available; " \ 1389 "forcing USE_FENV to False in", variant_dir + "." 1390 env['USE_FENV'] = False 1391 1392 if not env['USE_FENV']: 1393 print "Warning: No IEEE FP rounding mode control in", variant_dir + "." 1394 print " FP results may deviate slightly from other platforms." 1395 1396 if env['EFENCE']: 1397 env.Append(LIBS=['efence']) 1398 1399 if env['USE_KVM']: 1400 if not have_kvm: 1401 print "Warning: Can not enable KVM, host seems to lack KVM support" 1402 env['USE_KVM'] = False 1403 elif not is_isa_kvm_compatible(env['TARGET_ISA']): 1404 print "Info: KVM support disabled due to unsupported host and " \ 1405 "target ISA combination" 1406 env['USE_KVM'] = False 1407 1408 # Warn about missing optional functionality 1409 if env['USE_KVM']: 1410 if not main['HAVE_PERF_ATTR_EXCLUDE_HOST']: 1411 print "Warning: perf_event headers lack support for the " \ 1412 "exclude_host attribute. KVM instruction counts will " \ 1413 "be inaccurate." 1414 1415 # Save sticky variable settings back to current variables file 1416 sticky_vars.Save(current_vars_file, env) 1417 1418 if env['USE_SSE2']: 1419 env.Append(CCFLAGS=['-msse2']) 1420 1421 # The src/SConscript file sets up the build rules in 'env' according 1422 # to the configured variables. It returns a list of environments, 1423 # one for each variant build (debug, opt, etc.) 1424 SConscript('src/SConscript', variant_dir = variant_path, exports = 'env') 1425 1426def pairwise(iterable): 1427 "s -> (s0,s1), (s1,s2), (s2, s3), ..." 1428 a, b = itertools.tee(iterable) 1429 b.next() 1430 return itertools.izip(a, b) 1431 1432# Create false dependencies so SCons will parse ISAs, establish 1433# dependencies, and setup the build Environments serially. Either 1434# SCons (likely) and/or our SConscripts (possibly) cannot cope with -j 1435# greater than 1. It appears to be standard race condition stuff; it 1436# doesn't always fail, but usually, and the behaviors are different. 1437# Every time I tried to remove this, builds would fail in some 1438# creative new way. So, don't do that. You'll want to, though, because 1439# tests/SConscript takes a long time to make its Environments. 1440for t1, t2 in pairwise(sorted(all_isa_deps.iterkeys())): 1441 main.Depends('#%s-deps' % t2, '#%s-deps' % t1) 1442 main.Depends('#%s-environs' % t2, '#%s-environs' % t1) 1443 1444# base help text 1445Help(''' 1446Usage: scons [scons options] [build variables] [target(s)] 1447 1448Extra scons options: 1449%(options)s 1450 1451Global build variables: 1452%(global_vars)s 1453 1454%(local_vars)s 1455''' % help_texts) 1456