SConstruct revision 11887:f08918a690cf
1360SN/A# -*- mode:python -*- 210850SGiacomo.Gabrielli@arm.com 310796Sbrandon.potter@amd.com# Copyright (c) 2013, 2015, 2016 ARM Limited 410027SChris.Adeniyi-Jones@arm.com# All rights reserved. 510027SChris.Adeniyi-Jones@arm.com# 610027SChris.Adeniyi-Jones@arm.com# The license below extends only to copyright in the software and shall 710027SChris.Adeniyi-Jones@arm.com# not be construed as granting a license to any other intellectual 810027SChris.Adeniyi-Jones@arm.com# property including but not limited to intellectual property relating 910027SChris.Adeniyi-Jones@arm.com# to a hardware implementation of the functionality of the software 1010027SChris.Adeniyi-Jones@arm.com# licensed hereunder. You may use the software subject to the license 1110027SChris.Adeniyi-Jones@arm.com# terms below provided that you ensure that this notice is replicated 1210027SChris.Adeniyi-Jones@arm.com# unmodified and in its entirety in all distributions of the software, 1310027SChris.Adeniyi-Jones@arm.com# modified or unmodified, in source code or in binary form. 1410027SChris.Adeniyi-Jones@arm.com# 151458SN/A# Copyright (c) 2011 Advanced Micro Devices, Inc. 16360SN/A# Copyright (c) 2009 The Hewlett-Packard Development Company 17360SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 18360SN/A# All rights reserved. 19360SN/A# 20360SN/A# Redistribution and use in source and binary forms, with or without 21360SN/A# modification, are permitted provided that the following conditions are 22360SN/A# met: redistributions of source code must retain the above copyright 23360SN/A# notice, this list of conditions and the following disclaimer; 24360SN/A# redistributions in binary form must reproduce the above copyright 25360SN/A# notice, this list of conditions and the following disclaimer in the 26360SN/A# documentation and/or other materials provided with the distribution; 27360SN/A# neither the name of the copyright holders nor the names of its 28360SN/A# contributors may be used to endorse or promote products derived from 29360SN/A# this software without specific prior written permission. 30360SN/A# 31360SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32360SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33360SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34360SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35360SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36360SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 37360SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38360SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39360SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 402665Ssaidi@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 412665Ssaidi@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 422665Ssaidi@eecs.umich.edu# 43360SN/A# Authors: Steve Reinhardt 44360SN/A# Nathan Binkert 451354SN/A 461354SN/A################################################### 47360SN/A# 4812018Sandreas.sandberg@arm.com# SCons top-level build description (SConstruct) file. 4912018Sandreas.sandberg@arm.com# 5012018Sandreas.sandberg@arm.com# While in this directory ('gem5'), just type 'scons' to build the default 5112018Sandreas.sandberg@arm.com# configuration (see below), or type 'scons build/<CONFIG>/<binary>' 5212018Sandreas.sandberg@arm.com# to build some other configuration (e.g., 'build/ALPHA/gem5.opt' for 5312018Sandreas.sandberg@arm.com# the optimized full-system version). 5412018Sandreas.sandberg@arm.com# 552064SN/A# You can build gem5 in a different directory as long as there is a 56360SN/A# 'build/<CONFIG>' somewhere along the target path. The build system 57360SN/A# expects that all configs under the same build directory are being 58360SN/A# built for the same host system. 59360SN/A# 60360SN/A# Examples: 61360SN/A# 6213936SAndrea.Mondelli@ucf.edu# The following two commands are equivalent. The '-u' option tells 6313933Sbrandon.potter@amd.com# scons to search up the directory tree for this SConstruct file. 6413933Sbrandon.potter@amd.com# % cd <path-to-src>/gem5 ; scons build/ALPHA/gem5.debug 6513933Sbrandon.potter@amd.com# % cd <path-to-src>/gem5/build/ALPHA; scons -u gem5.debug 6613936SAndrea.Mondelli@ucf.edu# 6713936SAndrea.Mondelli@ucf.edu# The following two commands are equivalent and demonstrate building 6813936SAndrea.Mondelli@ucf.edu# in a directory outside of the source tree. The '-C' option tells 6913933Sbrandon.potter@amd.com# scons to chdir to the specified directory to find this SConstruct 7013933Sbrandon.potter@amd.com# file. 711809SN/A# % cd <path-to-src>/gem5 ; scons /local/foo/build/ALPHA/gem5.debug 7211800Sbrandon.potter@amd.com# % cd /local/foo/build/ALPHA; scons -C <path-to-src>/gem5 gem5.debug 7311392Sbrandon.potter@amd.com# 741809SN/A# You can use 'scons -H' to print scons options. If you're in this 7511392Sbrandon.potter@amd.com# 'gem5' directory (or use -u or -C to tell scons where to find this 7613902Sbrandon.potter@amd.com# file), you can use 'scons -h' to print all the gem5-specific build 7713570Sbrandon.potter@amd.com# options as well. 7813902Sbrandon.potter@amd.com# 7911383Sbrandon.potter@amd.com################################################### 8013568Sbrandon.potter@amd.com 813113Sgblack@eecs.umich.edu# Check for recent-enough Python and SCons versions. 828229Snate@binkert.orgtry: 8313570Sbrandon.potter@amd.com # Really old versions of scons only take two options for the 848229Snate@binkert.org # function, so check once without the revision and once with the 8511594Santhony.gutierrez@amd.com # revision, the first instance will fail for stuff other than 867075Snate@binkert.org # 0.98, and the second will fail for 0.98.0 878229Snate@binkert.org EnsureSConsVersion(0, 98) 8811856Sbrandon.potter@amd.com EnsureSConsVersion(0, 98, 1) 897075Snate@binkert.orgexcept SystemExit, e: 90360SN/A print """ 9112461Sgabeblack@google.comFor more details, see: 9211886Sbrandon.potter@amd.com http://gem5.org/Dependencies 9311800Sbrandon.potter@amd.com""" 9411392Sbrandon.potter@amd.com raise 9512334Sgabeblack@google.com 961354SN/A# We ensure the python version early because because python-config 976216Snate@binkert.org# requires python 2.5 986658Snate@binkert.orgtry: 992474SN/A EnsurePythonVersion(2, 5) 1002680Sktlim@umich.eduexcept SystemExit, e: 1018229Snate@binkert.org print """ 10211886Sbrandon.potter@amd.comYou can use a non-default installation of the Python interpreter by 10310496Ssteve.reinhardt@amd.comrearranging your PATH so that scons finds the non-default 'python' and 10411911SBrandon.Potter@amd.com'python-config' first. 1058229Snate@binkert.org 10611794Sbrandon.potter@amd.comFor more details, see: 10711886Sbrandon.potter@amd.com http://gem5.org/wiki/index.php/Using_a_non-default_Python_installation 10810497Ssteve.reinhardt@amd.com""" 10911794Sbrandon.potter@amd.com raise 110360SN/A 11113629SAndrea.Mondelli@ucf.edu# Global Python includes 11213629SAndrea.Mondelli@ucf.eduimport itertools 11313629SAndrea.Mondelli@ucf.eduimport os 11413629SAndrea.Mondelli@ucf.eduimport re 115360SN/Aimport shutil 116360SN/Aimport subprocess 117360SN/Aimport sys 118360SN/A 119360SN/Afrom os import mkdir, environ 120360SN/Afrom os.path import abspath, basename, dirname, expanduser, normpath 121360SN/Afrom os.path import exists, isdir, isfile 122360SN/Afrom os.path import join as joinpath, split as splitpath 12313933Sbrandon.potter@amd.com 124360SN/A# SCons includes 125378SN/Aimport SCons 12613995Sbrandon.potter@amd.comimport SCons.Node 127378SN/A 128378SN/Aextra_python_paths = [ 129378SN/A Dir('src/python').srcnode().abspath, # gem5 includes 130378SN/A Dir('ext/ply').srcnode().abspath, # ply is used by several files 131378SN/A ] 13213995Sbrandon.potter@amd.com 133360SN/Asys.path[1:1] = extra_python_paths 13411760Sbrandon.potter@amd.com 13513995Sbrandon.potter@amd.comfrom m5.util import compareVersions, readCommand 13611760Sbrandon.potter@amd.comfrom m5.util.terminal import get_termcap 1376109Ssanchezd@stanford.edu 13813995Sbrandon.potter@amd.comhelp_texts = { 139378SN/A "options" : "", 1406109Ssanchezd@stanford.edu "global_vars" : "", 14113995Sbrandon.potter@amd.com "local_vars" : "" 1426109Ssanchezd@stanford.edu} 14311886Sbrandon.potter@amd.com 14413995Sbrandon.potter@amd.comExport("help_texts") 14511886Sbrandon.potter@amd.com 146378SN/A 14713995Sbrandon.potter@amd.com# There's a bug in scons in that (1) by default, the help texts from 148378SN/A# AddOption() are supposed to be displayed when you type 'scons -h' 1495748SSteve.Reinhardt@amd.com# and (2) you can override the help displayed by 'scons -h' using the 15013995Sbrandon.potter@amd.com# Help() function, but these two features are incompatible: once 151378SN/A# you've overridden the help text using Help(), there's no way to get 152378SN/A# at the help texts from AddOptions. See: 15313995Sbrandon.potter@amd.com# http://scons.tigris.org/issues/show_bug.cgi?id=2356 154378SN/A# http://scons.tigris.org/issues/show_bug.cgi?id=2611 155378SN/A# This hack lets us extract the help text from AddOptions and 15613995Sbrandon.potter@amd.com# re-inject it via Help(). Ideally someday this bug will be fixed and 157378SN/A# we can just use AddOption directly. 1584118Sgblack@eecs.umich.edudef AddLocalOption(*args, **kwargs): 15913995Sbrandon.potter@amd.com col_width = 30 1604118Sgblack@eecs.umich.edu 161378SN/A help = " " + ", ".join(args) 16213995Sbrandon.potter@amd.com if "help" in kwargs: 163378SN/A length = len(help) 16413568Sbrandon.potter@amd.com if length >= col_width: 16513995Sbrandon.potter@amd.com help += "\n" + " " * col_width 16613568Sbrandon.potter@amd.com else: 167378SN/A help += " " * (col_width - length) 16813995Sbrandon.potter@amd.com help += kwargs["help"] 169360SN/A help_texts["options"] += help + "\n" 1705513SMichael.Adler@intel.com 17113995Sbrandon.potter@amd.com AddOption(*args, **kwargs) 1725513SMichael.Adler@intel.com 17310203SAli.Saidi@ARM.comAddLocalOption('--colors', dest='use_colors', action='store_true', 17413995Sbrandon.potter@amd.com help="Add color to abbreviated scons output") 17510203SAli.Saidi@ARM.comAddLocalOption('--no-colors', dest='use_colors', action='store_false', 17613995Sbrandon.potter@amd.com help="Don't add color to abbreviated scons output") 1775513SMichael.Adler@intel.comAddLocalOption('--with-cxx-config', dest='with_cxx_config', 178511SN/A action='store_true', 17913995Sbrandon.potter@amd.com help="Build with support for C++-based configuration") 18010633Smichaelupton@gmail.comAddLocalOption('--default', dest='default', type='string', action='store', 18113995Sbrandon.potter@amd.com help='Override which build_opts file to use for defaults') 182511SN/AAddLocalOption('--ignore-style', dest='ignore_style', action='store_true', 18312795Smattdsinclair@gmail.com help='Disable style checking hooks') 18413995Sbrandon.potter@amd.comAddLocalOption('--no-lto', dest='no_lto', action='store_true', 18512795Smattdsinclair@gmail.com help='Disable Link-Time Optimization for fast') 18612796Smattdsinclair@gmail.comAddLocalOption('--update-ref', dest='update_ref', action='store_true', 18713995Sbrandon.potter@amd.com help='Update test reference outputs') 18812796Smattdsinclair@gmail.comAddLocalOption('--verbose', dest='verbose', action='store_true', 1895513SMichael.Adler@intel.com help='Print full tool command lines') 19013995Sbrandon.potter@amd.comAddLocalOption('--without-python', dest='without_python', 1915513SMichael.Adler@intel.com action='store_true', 19213031Sbrandon.potter@amd.com help='Build without Python configuration support') 19313995Sbrandon.potter@amd.comAddLocalOption('--without-tcmalloc', dest='without_tcmalloc', 19413031Sbrandon.potter@amd.com action='store_true', 19513031Sbrandon.potter@amd.com help='Disable linking against tcmalloc') 19613995Sbrandon.potter@amd.comAddLocalOption('--with-ubsan', dest='with_ubsan', action='store_true', 19713031Sbrandon.potter@amd.com help='Build with Undefined Behavior Sanitizer if available') 19813031Sbrandon.potter@amd.comAddLocalOption('--with-asan', dest='with_asan', action='store_true', 19913995Sbrandon.potter@amd.com help='Build with Address Sanitizer if available') 20013031Sbrandon.potter@amd.com 201511SN/Atermcap = get_termcap(GetOption('use_colors')) 20213995Sbrandon.potter@amd.com 2031706SN/A######################################################################## 2041706SN/A# 2051706SN/A# Set up the main build environment. 20613995Sbrandon.potter@amd.com# 2071706SN/A######################################################################## 2081706SN/A 2091706SN/A# export TERM so that clang reports errors in color 21013995Sbrandon.potter@amd.comuse_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 2111706SN/A 'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PROTOC', 212511SN/A 'PYTHONPATH', 'RANLIB', 'SWIG', 'TERM' ]) 2136703Svince@csl.cornell.edu 21413995Sbrandon.potter@amd.comuse_prefixes = [ 2156703Svince@csl.cornell.edu "ASAN_", # address sanitizer symbolizer path and settings 2166685Stjones1@inf.ed.ac.uk "CCACHE_", # ccache (caching compiler wrapper) configuration 21713995Sbrandon.potter@amd.com "CCC_", # clang static analyzer configuration 2186685Stjones1@inf.ed.ac.uk "DISTCC_", # distcc (distributed compiler wrapper) configuration 2196685Stjones1@inf.ed.ac.uk "INCLUDE_SERVER_", # distcc pump server settings 2205513SMichael.Adler@intel.com "M5", # M5 configuration (e.g., path to kernels) 22113995Sbrandon.potter@amd.com ] 2225513SMichael.Adler@intel.com 22311885Sbrandon.potter@amd.comuse_env = {} 22413995Sbrandon.potter@amd.comfor key,val in sorted(os.environ.iteritems()): 2255513SMichael.Adler@intel.com if key in use_vars or \ 2261999SN/A any([key.startswith(prefix) for prefix in use_prefixes]): 22713995Sbrandon.potter@amd.com use_env[key] = val 2281999SN/A 22911885Sbrandon.potter@amd.com# Tell scons to avoid implicit command dependencies to avoid issues 23013995Sbrandon.potter@amd.com# with the param wrappes being compiled twice (see 2311999SN/A# http://scons.tigris.org/issues/show_bug.cgi?id=2811) 2321999SN/Amain = Environment(ENV=use_env, IMPLICIT_COMMAND_DEPENDENCIES=0) 23313995Sbrandon.potter@amd.commain.Decider('MD5-timestamp') 2341999SN/Amain.root = Dir(".") # The current directory (where this file lives). 2353079Sstever@eecs.umich.edumain.srcdir = Dir("src") # The source directory 23613995Sbrandon.potter@amd.com 2373079Sstever@eecs.umich.edumain_dict_keys = main.Dictionary().keys() 23811908SBrandon.Potter@amd.com 23913995Sbrandon.potter@amd.com# Check that we have a C/C++ compiler 24011908SBrandon.Potter@amd.comif not ('CC' in main_dict_keys and 'CXX' in main_dict_keys): 24111875Sbrandon.potter@amd.com print "No C++ compiler installed (package g++ on Ubuntu and RedHat)" 24213995Sbrandon.potter@amd.com Exit(1) 2432093SN/A 2442687Sksewell@umich.edu# Check that swig is present 24513995Sbrandon.potter@amd.comif not 'SWIG' in main_dict_keys: 2462687Sksewell@umich.edu print "swig is not installed (package swig on Ubuntu and RedHat)" 2472238SN/A Exit(1) 24813995Sbrandon.potter@amd.com 2492238SN/A# add useful python code PYTHONPATH so it can be used by subprocesses 25011908SBrandon.Potter@amd.com# as well 25113995Sbrandon.potter@amd.commain.AppendENVPath('PYTHONPATH', extra_python_paths) 25211908SBrandon.Potter@amd.com 25311908SBrandon.Potter@amd.com######################################################################## 25413995Sbrandon.potter@amd.com# 25513995Sbrandon.potter@amd.com# Mercurial Stuff. 25611908SBrandon.Potter@amd.com# 2572238SN/A# If the gem5 directory is a mercurial repository, we should do some 25813995Sbrandon.potter@amd.com# extra things. 2592238SN/A# 26013571Sbrandon.potter@amd.com######################################################################## 26113995Sbrandon.potter@amd.com 26213571Sbrandon.potter@amd.comhgdir = main.root.Dir(".hg") 26313568Sbrandon.potter@amd.com 26413995Sbrandon.potter@amd.com 26513568Sbrandon.potter@amd.comstyle_message = """ 26613568Sbrandon.potter@amd.comYou're missing the gem5 style hook, which automatically checks your code 26713995Sbrandon.potter@amd.comagainst the gem5 style rules on %s. 26813568Sbrandon.potter@amd.comThis script will now install the hook in your %s. 26913568Sbrandon.potter@amd.comPress enter to continue, or ctrl-c to abort: """ 27013995Sbrandon.potter@amd.com 27113568Sbrandon.potter@amd.commercurial_style_message = """ 27213448Sciro.santilli@arm.comYou're missing the gem5 style hook, which automatically checks your code 27313031Sbrandon.potter@amd.comagainst the gem5 style rules on hg commit and qrefresh commands. 27413995Sbrandon.potter@amd.comThis script will now install the hook in your .hg/hgrc file. 27513448Sciro.santilli@arm.comPress enter to continue, or ctrl-c to abort: """ 27613031Sbrandon.potter@amd.com 27713539Sjavier.setoain@arm.comgit_style_message = """ 27813539Sjavier.setoain@arm.comYou're missing the gem5 style or commit message hook. These hooks help 27913995Sbrandon.potter@amd.comto ensure that your code follows gem5's style rules on git commit. 28013539Sjavier.setoain@arm.comThis script will now install the hook in your .git/hooks/ directory. 28113539Sjavier.setoain@arm.comPress enter to continue, or ctrl-c to abort: """ 28213569Sbrandon.potter@amd.com 28313995Sbrandon.potter@amd.commercurial_style_upgrade_message = """ 28413569Sbrandon.potter@amd.comYour Mercurial style hooks are not up-to-date. This script will now 28513569Sbrandon.potter@amd.comtry to automatically update them. A backup of your hgrc will be saved 28613995Sbrandon.potter@amd.comin .hg/hgrc.old. 28713569Sbrandon.potter@amd.comPress enter to continue, or ctrl-c to abort: """ 28813569Sbrandon.potter@amd.com 28913995Sbrandon.potter@amd.commercurial_style_hook = """ 29013569Sbrandon.potter@amd.com# The following lines were automatically added by gem5/SConstruct 29113569Sbrandon.potter@amd.com# to provide the gem5 style-checking hooks 29213995Sbrandon.potter@amd.com[extensions] 29313569Sbrandon.potter@amd.comhgstyle = %s/util/hgstyle.py 29413031Sbrandon.potter@amd.com 29513995Sbrandon.potter@amd.com[hooks] 2962238SN/Apretxncommit.style = python:hgstyle.check_style 2972238SN/Apre-qrefresh.style = python:hgstyle.check_style 29813995Sbrandon.potter@amd.com# End of SConstruct additions 2992238SN/A 3002238SN/A""" % (main.root.abspath) 30113995Sbrandon.potter@amd.com 3022238SN/Amercurial_lib_not_found = """ 3032238SN/AMercurial libraries cannot be found, ignoring style hook. If 30413995Sbrandon.potter@amd.comyou are a gem5 developer, please fix this and run the style 3052238SN/Ahook. It is important. 3062238SN/A""" 30713995Sbrandon.potter@amd.com 3082238SN/A# Check for style hook and prompt for installation if it's not there. 3099455Smitch.hayenga+gem5@gmail.com# Skip this if --ignore-style was specified, there's no interactive 31013995Sbrandon.potter@amd.com# terminal to prompt, or no recognized revision control system can be 31113995Sbrandon.potter@amd.com# found. 31211851Sbrandon.potter@amd.comignore_style = GetOption('ignore_style') or not sys.stdin.isatty() 3139455Smitch.hayenga+gem5@gmail.com 31413571Sbrandon.potter@amd.com# Try wire up Mercurial to the style hooks 31513995Sbrandon.potter@amd.comif not ignore_style and hgdir.exists(): 31613571Sbrandon.potter@amd.com style_hook = True 31713571Sbrandon.potter@amd.com style_hooks = tuple() 31813995Sbrandon.potter@amd.com hgrc = hgdir.File('hgrc') 31913571Sbrandon.potter@amd.com hgrc_old = hgdir.File('hgrc.old') 32013571Sbrandon.potter@amd.com try: 32113995Sbrandon.potter@amd.com from mercurial import ui 32213571Sbrandon.potter@amd.com ui = ui.ui() 3239112Smarc.orr@gmail.com ui.readconfig(hgrc.abspath) 32411906SBrandon.Potter@amd.com style_hooks = (ui.config('hooks', 'pretxncommit.style', None), 32511906SBrandon.Potter@amd.com ui.config('hooks', 'pre-qrefresh.style', None)) 3269112Smarc.orr@gmail.com style_hook = all(style_hooks) 3279112Smarc.orr@gmail.com style_extension = ui.config('extensions', 'style', None) 32813995Sbrandon.potter@amd.com except ImportError: 3299112Smarc.orr@gmail.com print mercurial_lib_not_found 33011911SBrandon.Potter@amd.com 3319112Smarc.orr@gmail.com if "python:style.check_style" in style_hooks: 33211911SBrandon.Potter@amd.com # Try to upgrade the style hooks 33313995Sbrandon.potter@amd.com print mercurial_style_upgrade_message 33413995Sbrandon.potter@amd.com # continue unless user does ctrl-c/ctrl-d etc. 33511911SBrandon.Potter@amd.com try: 33611911SBrandon.Potter@amd.com raw_input() 33711911SBrandon.Potter@amd.com except: 33813642Sqtt2@cornell.edu print "Input exception, exiting scons.\n" 33913642Sqtt2@cornell.edu sys.exit(1) 34013642Sqtt2@cornell.edu shutil.copyfile(hgrc.abspath, hgrc_old.abspath) 3419112Smarc.orr@gmail.com re_style_hook = re.compile(r"^([^=#]+)\.style\s*=\s*([^#\s]+).*") 34211911SBrandon.Potter@amd.com re_style_extension = re.compile("style\s*=\s*([^#\s]+).*") 34311911SBrandon.Potter@amd.com old, new = open(hgrc_old.abspath, 'r'), open(hgrc.abspath, 'w') 34411911SBrandon.Potter@amd.com for l in old: 34511911SBrandon.Potter@amd.com m_hook = re_style_hook.match(l) 3469238Slluc.alvarez@bsc.es m_ext = re_style_extension.match(l) 34713642Sqtt2@cornell.edu if m_hook: 3489112Smarc.orr@gmail.com hook, check = m_hook.groups() 34911911SBrandon.Potter@amd.com if check != "python:style.check_style": 3509112Smarc.orr@gmail.com print "Warning: %s.style is using a non-default " \ 35113642Sqtt2@cornell.edu "checker: %s" % (hook, check) 35211911SBrandon.Potter@amd.com if hook not in ("pretxncommit", "pre-qrefresh"): 35311911SBrandon.Potter@amd.com print "Warning: Updating unknown style hook: %s" % hook 35414024Sgabeblack@google.com 35511911SBrandon.Potter@amd.com l = "%s.style = python:hgstyle.check_style\n" % hook 3569112Smarc.orr@gmail.com elif m_ext and m_ext.group(1) == style_extension: 35711911SBrandon.Potter@amd.com l = "hgstyle = %s/util/hgstyle.py\n" % main.root.abspath 35811911SBrandon.Potter@amd.com 35911911SBrandon.Potter@amd.com new.write(l) 36011911SBrandon.Potter@amd.com elif not style_hook: 36111911SBrandon.Potter@amd.com print mercurial_style_message, 36211911SBrandon.Potter@amd.com # continue unless user does ctrl-c/ctrl-d etc. 3639112Smarc.orr@gmail.com try: 3649112Smarc.orr@gmail.com raw_input() 36513642Sqtt2@cornell.edu except: 36613642Sqtt2@cornell.edu print "Input exception, exiting scons.\n" 36713642Sqtt2@cornell.edu sys.exit(1) 36813642Sqtt2@cornell.edu hgrc_path = '%s/.hg/hgrc' % main.root.abspath 36913642Sqtt2@cornell.edu print "Adding style hook to", hgrc_path, "\n" 37011911SBrandon.Potter@amd.com try: 3719112Smarc.orr@gmail.com with open(hgrc_path, 'a') as f: 37211911SBrandon.Potter@amd.com f.write(mercurial_style_hook) 37311911SBrandon.Potter@amd.com except: 37413642Sqtt2@cornell.edu print "Error updating", hgrc_path 37513642Sqtt2@cornell.edu sys.exit(1) 37613650Smw828@cornell.edu 37713650Smw828@cornell.edudef install_git_style_hooks(): 37813650Smw828@cornell.edu try: 37913650Smw828@cornell.edu gitdir = Dir(readCommand( 38013650Smw828@cornell.edu ["git", "rev-parse", "--git-dir"]).strip("\n")) 38114024Sgabeblack@google.com except Exception, e: 38213650Smw828@cornell.edu print "Warning: Failed to find git repo directory: %s" % e 38313650Smw828@cornell.edu return 38413650Smw828@cornell.edu 38513650Smw828@cornell.edu git_hooks = gitdir.Dir("hooks") 38613650Smw828@cornell.edu def hook_exists(hook_name): 38713650Smw828@cornell.edu hook = git_hooks.File(hook_name) 38813650Smw828@cornell.edu return hook.exists() 38913650Smw828@cornell.edu 39013651Smw828@cornell.edu def hook_install(hook_name, script): 39113651Smw828@cornell.edu hook = git_hooks.File(hook_name) 39213651Smw828@cornell.edu if hook.exists(): 39313651Smw828@cornell.edu print "Warning: Can't install %s, hook already exists." % hook_name 39413651Smw828@cornell.edu return 39513651Smw828@cornell.edu 39613651Smw828@cornell.edu if not git_hooks.exists(): 39713651Smw828@cornell.edu mkdir(git_hooks.get_abspath()) 39813651Smw828@cornell.edu 39913651Smw828@cornell.edu # Use a relative symlink if the hooks live in the source directory 40013651Smw828@cornell.edu if hook.is_under(main.root): 40113651Smw828@cornell.edu script_path = os.path.relpath( 40213651Smw828@cornell.edu script.get_abspath(), 40313651Smw828@cornell.edu hook.Dir(".").get_abspath()) 40413651Smw828@cornell.edu else: 40513651Smw828@cornell.edu script_path = script.get_abspath() 40613651Smw828@cornell.edu 40713651Smw828@cornell.edu try: 40813651Smw828@cornell.edu os.symlink(script_path, hook.get_abspath()) 40913651Smw828@cornell.edu except: 41013651Smw828@cornell.edu print "Error updating git %s hook" % hook_name 41113651Smw828@cornell.edu raise 41213651Smw828@cornell.edu 41313651Smw828@cornell.edu if hook_exists("pre-commit") and hook_exists("commit-msg"): 41414024Sgabeblack@google.com return 41513651Smw828@cornell.edu 41613651Smw828@cornell.edu print git_style_message, 41713651Smw828@cornell.edu try: 41813651Smw828@cornell.edu raw_input() 41913651Smw828@cornell.edu except: 42013651Smw828@cornell.edu print "Input exception, exiting scons.\n" 42113651Smw828@cornell.edu sys.exit(1) 42213651Smw828@cornell.edu 42313651Smw828@cornell.edu git_style_script = File("util/git-pre-commit.py") 42413651Smw828@cornell.edu git_msg_script = File("ext/git-commit-msg") 42513651Smw828@cornell.edu 42613651Smw828@cornell.edu hook_install("pre-commit", git_style_script) 42713651Smw828@cornell.edu hook_install("commit-msg", git_msg_script) 42813651Smw828@cornell.edu 42913651Smw828@cornell.edu# Try to wire up git to the style hooks 43013651Smw828@cornell.eduif not ignore_style and main.root.Entry(".git").exists(): 43113651Smw828@cornell.edu install_git_style_hooks() 43213651Smw828@cornell.edu 43313651Smw828@cornell.edu################################################### 43413651Smw828@cornell.edu# 43513651Smw828@cornell.edu# Figure out which configurations to set up based on the path(s) of 43613651Smw828@cornell.edu# the target(s). 43713651Smw828@cornell.edu# 43814024Sgabeblack@google.com################################################### 43913651Smw828@cornell.edu 44013651Smw828@cornell.edu# Find default configuration & binary. 44113651Smw828@cornell.eduDefault(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA/gem5.debug')) 44213651Smw828@cornell.edu 44313651Smw828@cornell.edu# helper function: find last occurrence of element in list 44413651Smw828@cornell.edudef rfind(l, elt, offs = -1): 44513651Smw828@cornell.edu for i in range(len(l)+offs, 0, -1): 44613651Smw828@cornell.edu if l[i] == elt: 44713651Smw828@cornell.edu return i 44813651Smw828@cornell.edu raise ValueError, "element not found" 44913651Smw828@cornell.edu 45013651Smw828@cornell.edu# Take a list of paths (or SCons Nodes) and return a list with all 45113651Smw828@cornell.edu# paths made absolute and ~-expanded. Paths will be interpreted 45213651Smw828@cornell.edu# relative to the launch directory unless a different root is provided 45313651Smw828@cornell.edudef makePathListAbsolute(path_list, root=GetLaunchDir()): 45413651Smw828@cornell.edu return [abspath(joinpath(root, expanduser(str(p)))) 45513651Smw828@cornell.edu for p in path_list] 45613651Smw828@cornell.edu 45713651Smw828@cornell.edu# Each target must have 'build' in the interior of the path; the 45813651Smw828@cornell.edu# directory below this will determine the build parameters. For 45913651Smw828@cornell.edu# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we 46013651Smw828@cornell.edu# recognize that ALPHA_SE specifies the configuration because it 4619112Smarc.orr@gmail.com# follow 'build' in the build path. 46211911SBrandon.Potter@amd.com 46311911SBrandon.Potter@amd.com# The funky assignment to "[:]" is needed to replace the list contents 4649112Smarc.orr@gmail.com# in place rather than reassign the symbol to a new list, which 4659112Smarc.orr@gmail.com# doesn't work (obviously!). 4662238SN/ABUILD_TARGETS[:] = makePathListAbsolute(BUILD_TARGETS) 4672238SN/A 4682238SN/A# Generate a list of the unique build roots and configs that the 46913995Sbrandon.potter@amd.com# collected targets reference. 4702238SN/Avariant_paths = [] 4712238SN/Abuild_root = None 47213995Sbrandon.potter@amd.comfor t in BUILD_TARGETS: 4732238SN/A path_dirs = t.split('/') 4742238SN/A try: 47513995Sbrandon.potter@amd.com build_top = rfind(path_dirs, 'build', -2) 4762238SN/A except: 4772238SN/A print "Error: no non-leaf 'build' dir found on target path", t 47813995Sbrandon.potter@amd.com Exit(1) 4792238SN/A this_build_root = joinpath('/',*path_dirs[:build_top+1]) 4802238SN/A if not build_root: 4811354SN/A build_root = this_build_root 4821354SN/A else: 48310796Sbrandon.potter@amd.com if this_build_root != build_root: 48410796Sbrandon.potter@amd.com print "Error: build targets not under same build root\n"\ 4851354SN/A " %s\n %s" % (build_root, this_build_root) 4861354SN/A Exit(1) 4871354SN/A variant_path = joinpath('/',*path_dirs[:build_top+2]) 4881354SN/A if variant_path not in variant_paths: 4891354SN/A variant_paths.append(variant_path) 4901354SN/A 4911354SN/A# Make sure build_root exists (might not if this is the first build there) 4921354SN/Aif not isdir(build_root): 4931354SN/A mkdir(build_root) 4941354SN/Amain['BUILDROOT'] = build_root 49510796Sbrandon.potter@amd.com 4961354SN/AExport('main') 49710796Sbrandon.potter@amd.com 4981354SN/Amain.SConsignFile(joinpath(build_root, "sconsign")) 4991354SN/A 5001354SN/A# Default duplicate option is to use hard links, but this messes up 5011354SN/A# when you use emacs to edit a file in the target dir, as emacs moves 50210796Sbrandon.potter@amd.com# file to file~ then copies to file, breaking the link. Symbolic 50310796Sbrandon.potter@amd.com# (soft) links work better. 50410796Sbrandon.potter@amd.commain.SetOption('duplicate', 'soft-copy') 50510796Sbrandon.potter@amd.com 50610796Sbrandon.potter@amd.com# 50710796Sbrandon.potter@amd.com# Set up global sticky variables... these are common to an entire build 50810796Sbrandon.potter@amd.com# tree (not specific to a particular build like ALPHA_SE) 50910796Sbrandon.potter@amd.com# 51010796Sbrandon.potter@amd.com 51110796Sbrandon.potter@amd.comglobal_vars_file = joinpath(build_root, 'variables.global') 51210796Sbrandon.potter@amd.com 513360SN/Aglobal_vars = Variables(global_vars_file, args=ARGUMENTS) 514360SN/A 515360SN/Aglobal_vars.AddVariables( 516360SN/A ('CC', 'C compiler', environ.get('CC', main['CC'])), 517360SN/A ('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])), 518360SN/A ('SWIG', 'SWIG tool', environ.get('SWIG', main['SWIG'])), 519360SN/A ('PROTOC', 'protoc tool', environ.get('PROTOC', 'protoc')), 52011759Sbrandon.potter@amd.com ('BATCH', 'Use batch pool for build and tests', False), 5213113Sgblack@eecs.umich.edu ('BATCH_CMD', 'Batch pool submission command name', 'qdo'), 5223113Sgblack@eecs.umich.edu ('M5_BUILD_CACHE', 'Cache built objects in this directory', False), 5233113Sgblack@eecs.umich.edu ('EXTRAS', 'Add extra directories to the compilation', '') 5243113Sgblack@eecs.umich.edu ) 5253113Sgblack@eecs.umich.edu 5263113Sgblack@eecs.umich.edu# Update main environment with values from ARGUMENTS & global_vars_file 5273113Sgblack@eecs.umich.eduglobal_vars.Update(main) 5283113Sgblack@eecs.umich.eduhelp_texts["global_vars"] += global_vars.GenerateHelpText(main) 5293113Sgblack@eecs.umich.edu 5303113Sgblack@eecs.umich.edu# Save sticky variable settings back to current variables file 5313113Sgblack@eecs.umich.eduglobal_vars.Save(global_vars_file, main) 5323113Sgblack@eecs.umich.edu 5333113Sgblack@eecs.umich.edu# Parse EXTRAS variable to build list of all directories where we're 53412032Sandreas.sandberg@arm.com# look for sources etc. This list is exported as extras_dir_list. 5353113Sgblack@eecs.umich.edubase_dir = main.srcdir.abspath 5363113Sgblack@eecs.umich.eduif main['EXTRAS']: 5374189Sgblack@eecs.umich.edu extras_dir_list = makePathListAbsolute(main['EXTRAS'].split(':')) 5384189Sgblack@eecs.umich.eduelse: 5393113Sgblack@eecs.umich.edu extras_dir_list = [] 5403113Sgblack@eecs.umich.edu 5413113Sgblack@eecs.umich.eduExport('base_dir') 5423113Sgblack@eecs.umich.eduExport('extras_dir_list') 5438737Skoansin.tan@gmail.com 5443113Sgblack@eecs.umich.edu# the ext directory should be on the #includes path 5458737Skoansin.tan@gmail.commain.Append(CPPPATH=[Dir('ext')]) 5463277Sgblack@eecs.umich.edu 5475515SMichael.Adler@intel.comdef strip_build_path(path, env): 5485515SMichael.Adler@intel.com path = str(path) 5495515SMichael.Adler@intel.com variant_base = env['BUILDROOT'] + os.path.sep 5505515SMichael.Adler@intel.com if path.startswith(variant_base): 5515515SMichael.Adler@intel.com path = path[len(variant_base):] 5528737Skoansin.tan@gmail.com elif path.startswith('build/'): 5533277Sgblack@eecs.umich.edu path = path[6:] 5548737Skoansin.tan@gmail.com return path 5553277Sgblack@eecs.umich.edu 5568737Skoansin.tan@gmail.com# Generate a string of the form: 5573277Sgblack@eecs.umich.edu# common/path/prefix/src1, src2 -> tgt1, tgt2 5588737Skoansin.tan@gmail.com# to print while building. 5593113Sgblack@eecs.umich.educlass Transform(object): 5603113Sgblack@eecs.umich.edu # all specific color settings should be here and nowhere else 5613113Sgblack@eecs.umich.edu tool_color = termcap.Normal 5623113Sgblack@eecs.umich.edu pfx_color = termcap.Yellow 5638737Skoansin.tan@gmail.com srcs_color = termcap.Yellow + termcap.Bold 5643113Sgblack@eecs.umich.edu arrow_color = termcap.Blue + termcap.Bold 5658737Skoansin.tan@gmail.com tgts_color = termcap.Yellow + termcap.Bold 5663114Sgblack@eecs.umich.edu 5678737Skoansin.tan@gmail.com def __init__(self, tool, max_sources=99): 5683114Sgblack@eecs.umich.edu self.format = self.tool_color + (" [%8s] " % tool) \ 5698737Skoansin.tan@gmail.com + self.pfx_color + "%s" \ 5703114Sgblack@eecs.umich.edu + self.srcs_color + "%s" \ 5718737Skoansin.tan@gmail.com + self.arrow_color + " -> " \ 57211906SBrandon.Potter@amd.com + self.tgts_color + "%s" \ 5734061Sgblack@eecs.umich.edu + termcap.Normal 5744061Sgblack@eecs.umich.edu self.max_sources = max_sources 5758737Skoansin.tan@gmail.com 5763113Sgblack@eecs.umich.edu def __call__(self, target, source, env, for_signature=None): 5778737Skoansin.tan@gmail.com # truncate source list according to max_sources param 5783113Sgblack@eecs.umich.edu source = source[0:self.max_sources] 5793113Sgblack@eecs.umich.edu def strip(f): 5803113Sgblack@eecs.umich.edu return strip_build_path(str(f), env) 5813113Sgblack@eecs.umich.edu if len(source) > 0: 5823113Sgblack@eecs.umich.edu srcs = map(strip, source) 58312032Sandreas.sandberg@arm.com else: 5843113Sgblack@eecs.umich.edu srcs = [''] 5853113Sgblack@eecs.umich.edu tgts = map(strip, target) 5864189Sgblack@eecs.umich.edu # surprisingly, os.path.commonprefix is a dumb char-by-char string 5874189Sgblack@eecs.umich.edu # operation that has nothing to do with paths. 5883113Sgblack@eecs.umich.edu com_pfx = os.path.commonprefix(srcs + tgts) 5893113Sgblack@eecs.umich.edu com_pfx_len = len(com_pfx) 5903113Sgblack@eecs.umich.edu if com_pfx: 5918737Skoansin.tan@gmail.com # do some cleanup and sanity checking on common prefix 5923113Sgblack@eecs.umich.edu if com_pfx[-1] == ".": 5938737Skoansin.tan@gmail.com # prefix matches all but file extension: ok 5943113Sgblack@eecs.umich.edu # back up one to change 'foo.cc -> o' to 'foo.cc -> .o' 5958737Skoansin.tan@gmail.com com_pfx = com_pfx[0:-1] 5963113Sgblack@eecs.umich.edu elif com_pfx[-1] == "/": 5973113Sgblack@eecs.umich.edu # common prefix is directory path: OK 5983113Sgblack@eecs.umich.edu pass 5993113Sgblack@eecs.umich.edu else: 6003113Sgblack@eecs.umich.edu src0_len = len(srcs[0]) 6013113Sgblack@eecs.umich.edu tgt0_len = len(tgts[0]) 6023113Sgblack@eecs.umich.edu if src0_len == com_pfx_len: 60311906SBrandon.Potter@amd.com # source is a substring of target, OK 6043113Sgblack@eecs.umich.edu pass 60512032Sandreas.sandberg@arm.com elif tgt0_len == com_pfx_len: 60614020Sgabeblack@google.com # target is a substring of source, need to back up to 60711906SBrandon.Potter@amd.com # avoid empty string on RHS of arrow 6083113Sgblack@eecs.umich.edu sep_idx = com_pfx.rfind(".") 6093113Sgblack@eecs.umich.edu if sep_idx != -1: 6103113Sgblack@eecs.umich.edu com_pfx = com_pfx[0:sep_idx] 6113113Sgblack@eecs.umich.edu else: 6123113Sgblack@eecs.umich.edu com_pfx = '' 6133113Sgblack@eecs.umich.edu elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".": 6143113Sgblack@eecs.umich.edu # still splitting at file extension: ok 6153113Sgblack@eecs.umich.edu pass 61612032Sandreas.sandberg@arm.com else: 61714020Sgabeblack@google.com # probably a fluke; ignore it 61811906SBrandon.Potter@amd.com com_pfx = '' 6193113Sgblack@eecs.umich.edu # recalculate length in case com_pfx was modified 6203113Sgblack@eecs.umich.edu com_pfx_len = len(com_pfx) 6213113Sgblack@eecs.umich.edu def fmt(files): 6226686Stjones1@inf.ed.ac.uk f = map(lambda s: s[com_pfx_len:], files) 6233113Sgblack@eecs.umich.edu return ', '.join(f) 6243113Sgblack@eecs.umich.edu return self.format % (com_pfx, fmt(srcs), fmt(tgts)) 6253113Sgblack@eecs.umich.edu 62611759Sbrandon.potter@amd.comExport('Transform') 62712032Sandreas.sandberg@arm.com 62814020Sgabeblack@google.com# enable the regression script to use the termcap 62911759Sbrandon.potter@amd.commain['TERMCAP'] = termcap 63011759Sbrandon.potter@amd.com 63111759Sbrandon.potter@amd.comif GetOption('verbose'): 63211759Sbrandon.potter@amd.com def MakeAction(action, string, *args, **kwargs): 63311812Sbaz21@cam.ac.uk return Action(action, *args, **kwargs) 63411812Sbaz21@cam.ac.ukelse: 63511812Sbaz21@cam.ac.uk MakeAction = Action 63611759Sbrandon.potter@amd.com main['CCCOMSTR'] = Transform("CC") 63711812Sbaz21@cam.ac.uk main['CXXCOMSTR'] = Transform("CXX") 63811759Sbrandon.potter@amd.com main['ASCOMSTR'] = Transform("AS") 63911759Sbrandon.potter@amd.com main['SWIGCOMSTR'] = Transform("SWIG") 64011759Sbrandon.potter@amd.com main['ARCOMSTR'] = Transform("AR", 0) 64111759Sbrandon.potter@amd.com main['LINKCOMSTR'] = Transform("LINK", 0) 64211759Sbrandon.potter@amd.com main['RANLIBCOMSTR'] = Transform("RANLIB", 0) 64311759Sbrandon.potter@amd.com main['M4COMSTR'] = Transform("M4") 64411759Sbrandon.potter@amd.com main['SHCCCOMSTR'] = Transform("SHCC") 64511812Sbaz21@cam.ac.uk main['SHCXXCOMSTR'] = Transform("SHCXX") 64611812Sbaz21@cam.ac.ukExport('MakeAction') 64711812Sbaz21@cam.ac.uk 64811812Sbaz21@cam.ac.uk# Initialize the Link-Time Optimization (LTO) flags 64911812Sbaz21@cam.ac.ukmain['LTO_CCFLAGS'] = [] 65011812Sbaz21@cam.ac.ukmain['LTO_LDFLAGS'] = [] 65111812Sbaz21@cam.ac.uk 65211759Sbrandon.potter@amd.com# According to the readme, tcmalloc works best if the compiler doesn't 65311759Sbrandon.potter@amd.com# assume that we're using the builtin malloc and friends. These flags 65411812Sbaz21@cam.ac.uk# are compiler-specific, so we need to set them after we detect which 65511812Sbaz21@cam.ac.uk# compiler we're using. 65611759Sbrandon.potter@amd.commain['TCMALLOC_CCFLAGS'] = [] 65711812Sbaz21@cam.ac.uk 65811812Sbaz21@cam.ac.ukCXX_version = readCommand([main['CXX'],'--version'], exception=False) 65911812Sbaz21@cam.ac.ukCXX_V = readCommand([main['CXX'],'-V'], exception=False) 66011812Sbaz21@cam.ac.uk 66111812Sbaz21@cam.ac.ukmain['GCC'] = CXX_version and CXX_version.find('g++') >= 0 66211812Sbaz21@cam.ac.ukmain['CLANG'] = CXX_version and CXX_version.find('clang') >= 0 66311812Sbaz21@cam.ac.ukif main['GCC'] + main['CLANG'] > 1: 66411759Sbrandon.potter@amd.com print 'Error: How can we have two at the same time?' 66511759Sbrandon.potter@amd.com Exit(1) 66611759Sbrandon.potter@amd.com 66711759Sbrandon.potter@amd.com# Set up default C++ compiler flags 668378SN/Aif main['GCC'] or main['CLANG']: 669378SN/A # As gcc and clang share many flags, do the common parts here 6709141Smarc.orr@gmail.com main.Append(CCFLAGS=['-pipe']) 6719141Smarc.orr@gmail.com main.Append(CCFLAGS=['-fno-strict-aliasing']) 672360SN/A # Enable -Wall and -Wextra and then disable the few warnings that 6731450SN/A # we consistently violate 67413995Sbrandon.potter@amd.com main.Append(CCFLAGS=['-Wall', '-Wundef', '-Wextra', 675360SN/A '-Wno-sign-compare', '-Wno-unused-parameter']) 6766701Sgblack@eecs.umich.edu # We always compile using C++11 67713995Sbrandon.potter@amd.com main.Append(CXXFLAGS=['-std=c++11']) 67813995Sbrandon.potter@amd.com if sys.platform.startswith('freebsd'): 67911856Sbrandon.potter@amd.com main.Append(CCFLAGS=['-I/usr/local/include']) 68011856Sbrandon.potter@amd.com main.Append(CXXFLAGS=['-I/usr/local/include']) 681360SN/Aelse: 68213907Salexandru.dutu@amd.com print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal, 683360SN/A print "Don't know what compiler options to use for your compiler." 68411856Sbrandon.potter@amd.com print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX'] 68511856Sbrandon.potter@amd.com print termcap.Yellow + ' version:' + termcap.Normal, 68610496Ssteve.reinhardt@amd.com if not CXX_version: 68711856Sbrandon.potter@amd.com print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\ 68813902Sbrandon.potter@amd.com termcap.Normal 68913902Sbrandon.potter@amd.com else: 69013902Sbrandon.potter@amd.com print CXX_version.replace('\n', '<nl>') 69113995Sbrandon.potter@amd.com print " If you're trying to use a compiler other than GCC" 69213902Sbrandon.potter@amd.com print " or clang, there appears to be something wrong with your" 69313902Sbrandon.potter@amd.com print " environment." 69413902Sbrandon.potter@amd.com print " " 69513902Sbrandon.potter@amd.com print " If you are trying to use a compiler other than those listed" 69613902Sbrandon.potter@amd.com print " above you will need to ease fix SConstruct and " 69713902Sbrandon.potter@amd.com print " src/SConscript to support that compiler." 69813902Sbrandon.potter@amd.com Exit(1) 69913902Sbrandon.potter@amd.com 70013902Sbrandon.potter@amd.comif main['GCC']: 70113902Sbrandon.potter@amd.com # Check for a supported version of gcc. >= 4.8 is chosen for its 70214024Sgabeblack@google.com # level of c++11 support. See 70313902Sbrandon.potter@amd.com # http://gcc.gnu.org/projects/cxx0x.html for details. 70413902Sbrandon.potter@amd.com gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False) 70513902Sbrandon.potter@amd.com if compareVersions(gcc_version, "4.8") < 0: 70613902Sbrandon.potter@amd.com print 'Error: gcc version 4.8 or newer required.' 70714024Sgabeblack@google.com print ' Installed version:', gcc_version 70813902Sbrandon.potter@amd.com Exit(1) 70913902Sbrandon.potter@amd.com 71013902Sbrandon.potter@amd.com main['GCC_VERSION'] = gcc_version 71113902Sbrandon.potter@amd.com 71213902Sbrandon.potter@amd.com # gcc from version 4.8 and above generates "rep; ret" instructions 71313902Sbrandon.potter@amd.com # to avoid performance penalties on certain AMD chips. Older 71414024Sgabeblack@google.com # assemblers detect this as an error, "Error: expecting string 71514024Sgabeblack@google.com # instruction after `rep'" 71613902Sbrandon.potter@amd.com as_version_raw = readCommand([main['AS'], '-v', '/dev/null'], 71713902Sbrandon.potter@amd.com exception=False).split() 71813902Sbrandon.potter@amd.com 71913902Sbrandon.potter@amd.com # version strings may contain extra distro-specific 72013902Sbrandon.potter@amd.com # qualifiers, so play it safe and keep only what comes before 72113936SAndrea.Mondelli@ucf.edu # the first hyphen 72213902Sbrandon.potter@amd.com as_version = as_version_raw[-1].split('-')[0] if as_version_raw else None 72313902Sbrandon.potter@amd.com 72413902Sbrandon.potter@amd.com if not as_version or compareVersions(as_version, "2.23") < 0: 72513902Sbrandon.potter@amd.com print termcap.Yellow + termcap.Bold + \ 72613936SAndrea.Mondelli@ucf.edu 'Warning: This combination of gcc and binutils have' + \ 72713902Sbrandon.potter@amd.com ' known incompatibilities.\n' + \ 72813902Sbrandon.potter@amd.com ' If you encounter build problems, please update ' + \ 72913902Sbrandon.potter@amd.com 'binutils to 2.23.' + \ 73013902Sbrandon.potter@amd.com termcap.Normal 73113902Sbrandon.potter@amd.com 73214024Sgabeblack@google.com # Make sure we warn if the user has requested to compile with the 73313902Sbrandon.potter@amd.com # Undefined Benahvior Sanitizer and this version of gcc does not 73413902Sbrandon.potter@amd.com # support it. 73513902Sbrandon.potter@amd.com if GetOption('with_ubsan') and \ 73614024Sgabeblack@google.com compareVersions(gcc_version, '4.9') < 0: 73713902Sbrandon.potter@amd.com print termcap.Yellow + termcap.Bold + \ 73813902Sbrandon.potter@amd.com 'Warning: UBSan is only supported using gcc 4.9 and later.' + \ 73913902Sbrandon.potter@amd.com termcap.Normal 74013902Sbrandon.potter@amd.com 74110496Ssteve.reinhardt@amd.com # Add the appropriate Link-Time Optimization (LTO) flags 74211856Sbrandon.potter@amd.com # unless LTO is explicitly turned off. Note that these flags 74311856Sbrandon.potter@amd.com # are only used by the fast target. 74411856Sbrandon.potter@amd.com if not GetOption('no_lto'): 74511856Sbrandon.potter@amd.com # Pass the LTO flag when compiling to produce GIMPLE 74611856Sbrandon.potter@amd.com # output, we merely create the flags here and only append 74710930Sbrandon.potter@amd.com # them later 7489141Smarc.orr@gmail.com main['LTO_CCFLAGS'] = ['-flto=%d' % GetOption('num_jobs')] 749360SN/A 750360SN/A # Use the same amount of jobs for LTO as we are running 751360SN/A # scons with 75211907SBrandon.Potter@amd.com main['LTO_LDFLAGS'] = ['-flto=%d' % GetOption('num_jobs')] 75313995Sbrandon.potter@amd.com 754360SN/A main.Append(TCMALLOC_CCFLAGS=['-fno-builtin-malloc', '-fno-builtin-calloc', 75511907SBrandon.Potter@amd.com '-fno-builtin-realloc', '-fno-builtin-free']) 75613995Sbrandon.potter@amd.com 75711907SBrandon.Potter@amd.com # add option to check for undeclared overrides 75811907SBrandon.Potter@amd.com if compareVersions(gcc_version, "5.0") > 0: 75911907SBrandon.Potter@amd.com main.Append(CCFLAGS=['-Wno-error=suggest-override']) 76011907SBrandon.Potter@amd.com 76111907SBrandon.Potter@amd.comelif main['CLANG']: 76211907SBrandon.Potter@amd.com # Check for a supported version of clang, >= 3.1 is needed to 76311907SBrandon.Potter@amd.com # support similar features as gcc 4.8. See 76411907SBrandon.Potter@amd.com # http://clang.llvm.org/cxx_status.html for details 76511907SBrandon.Potter@amd.com clang_version_re = re.compile(".* version (\d+\.\d+)") 76611907SBrandon.Potter@amd.com clang_version_match = clang_version_re.search(CXX_version) 76711907SBrandon.Potter@amd.com if (clang_version_match): 76811907SBrandon.Potter@amd.com clang_version = clang_version_match.groups()[0] 76911907SBrandon.Potter@amd.com if compareVersions(clang_version, "3.1") < 0: 770360SN/A print 'Error: clang version 3.1 or newer required.' 77114024Sgabeblack@google.com print ' Installed version:', clang_version 7721458SN/A Exit(1) 773360SN/A else: 77411907SBrandon.Potter@amd.com print 'Error: Unable to determine clang version.' 77511907SBrandon.Potter@amd.com Exit(1) 77611907SBrandon.Potter@amd.com 77711907SBrandon.Potter@amd.com # clang has a few additional warnings that we disable, extraneous 77811907SBrandon.Potter@amd.com # parantheses are allowed due to Ruby's printing of the AST, 77911907SBrandon.Potter@amd.com # finally self assignments are allowed as the generated CPU code 78011907SBrandon.Potter@amd.com # is relying on this 78111907SBrandon.Potter@amd.com main.Append(CCFLAGS=['-Wno-parentheses', 78211907SBrandon.Potter@amd.com '-Wno-self-assign', 78311907SBrandon.Potter@amd.com # Some versions of libstdc++ (4.8?) seem to 784360SN/A # use struct hash and class hash 78511907SBrandon.Potter@amd.com # interchangeably. 78611907SBrandon.Potter@amd.com '-Wno-mismatched-tags', 78711907SBrandon.Potter@amd.com ]) 788360SN/A 789360SN/A main.Append(TCMALLOC_CCFLAGS=['-fno-builtin']) 79011907SBrandon.Potter@amd.com 79111907SBrandon.Potter@amd.com # On Mac OS X/Darwin we need to also use libc++ (part of XCode) as 79211907SBrandon.Potter@amd.com # opposed to libstdc++, as the later is dated. 79311907SBrandon.Potter@amd.com if sys.platform == "darwin": 794360SN/A main.Append(CXXFLAGS=['-stdlib=libc++']) 79511907SBrandon.Potter@amd.com main.Append(LIBS=['c++']) 796360SN/A 797360SN/A # On FreeBSD we need libthr. 79811907SBrandon.Potter@amd.com if sys.platform.startswith('freebsd'): 7993669Sbinkertn@umich.edu main.Append(LIBS=['thr']) 80011907SBrandon.Potter@amd.com 80111907SBrandon.Potter@amd.comelse: 80211907SBrandon.Potter@amd.com print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal, 80311907SBrandon.Potter@amd.com print "Don't know what compiler options to use for your compiler." 80411907SBrandon.Potter@amd.com print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX'] 80511907SBrandon.Potter@amd.com print termcap.Yellow + ' version:' + termcap.Normal, 80611907SBrandon.Potter@amd.com if not CXX_version: 80711907SBrandon.Potter@amd.com print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\ 80811907SBrandon.Potter@amd.com termcap.Normal 80911907SBrandon.Potter@amd.com else: 81011907SBrandon.Potter@amd.com print CXX_version.replace('\n', '<nl>') 81111907SBrandon.Potter@amd.com print " If you're trying to use a compiler other than GCC" 81213883Sdavid.hashe@amd.com print " or clang, there appears to be something wrong with your" 81313883Sdavid.hashe@amd.com print " environment." 81413883Sdavid.hashe@amd.com print " " 81513883Sdavid.hashe@amd.com print " If you are trying to use a compiler other than those listed" 81613883Sdavid.hashe@amd.com print " above you will need to ease fix SConstruct and " 81711907SBrandon.Potter@amd.com print " src/SConscript to support that compiler." 81811907SBrandon.Potter@amd.com Exit(1) 81911907SBrandon.Potter@amd.com 82011907SBrandon.Potter@amd.com# Set up common yacc/bison flags (needed for Ruby) 82111907SBrandon.Potter@amd.commain['YACCFLAGS'] = '-d' 82213883Sdavid.hashe@amd.commain['YACCHXXFILESUFFIX'] = '.hh' 82313883Sdavid.hashe@amd.com 82411907SBrandon.Potter@amd.com# Do this after we save setting back, or else we'll tack on an 8251706SN/A# extra 'qdo' every time we run scons. 82611907SBrandon.Potter@amd.comif main['BATCH']: 82711907SBrandon.Potter@amd.com main['CC'] = main['BATCH_CMD'] + ' ' + main['CC'] 82811907SBrandon.Potter@amd.com main['CXX'] = main['BATCH_CMD'] + ' ' + main['CXX'] 82911907SBrandon.Potter@amd.com main['AS'] = main['BATCH_CMD'] + ' ' + main['AS'] 83011907SBrandon.Potter@amd.com main['AR'] = main['BATCH_CMD'] + ' ' + main['AR'] 83111907SBrandon.Potter@amd.com main['RANLIB'] = main['BATCH_CMD'] + ' ' + main['RANLIB'] 83213883Sdavid.hashe@amd.com 83313883Sdavid.hashe@amd.comif sys.platform == 'cygwin': 83411907SBrandon.Potter@amd.com # cygwin has some header file issues... 83511907SBrandon.Potter@amd.com main.Append(CCFLAGS=["-Wno-uninitialized"]) 83611907SBrandon.Potter@amd.com 83711907SBrandon.Potter@amd.com# Check for the protobuf compiler 83813883Sdavid.hashe@amd.comprotoc_version = readCommand([main['PROTOC'], '--version'], 83913995Sbrandon.potter@amd.com exception='').split() 84010496Ssteve.reinhardt@amd.com 84111907SBrandon.Potter@amd.com# First two words should be "libprotoc x.y.z" 84211907SBrandon.Potter@amd.comif len(protoc_version) < 2 or protoc_version[0] != 'libprotoc': 84311907SBrandon.Potter@amd.com print termcap.Yellow + termcap.Bold + \ 84411907SBrandon.Potter@amd.com 'Warning: Protocol buffer compiler (protoc) not found.\n' + \ 84510496Ssteve.reinhardt@amd.com ' Please install protobuf-compiler for tracing support.' + \ 84610496Ssteve.reinhardt@amd.com termcap.Normal 84711907SBrandon.Potter@amd.com main['PROTOC'] = False 84813883Sdavid.hashe@amd.comelse: 84913883Sdavid.hashe@amd.com # Based on the availability of the compress stream wrappers, 85013883Sdavid.hashe@amd.com # require 2.1.0 85113883Sdavid.hashe@amd.com min_protoc_version = '2.1.0' 85213883Sdavid.hashe@amd.com if compareVersions(protoc_version[1], min_protoc_version) < 0: 85313883Sdavid.hashe@amd.com print termcap.Yellow + termcap.Bold + \ 85413883Sdavid.hashe@amd.com 'Warning: protoc version', min_protoc_version, \ 85513883Sdavid.hashe@amd.com 'or newer required.\n' + \ 85613883Sdavid.hashe@amd.com ' Installed version:', protoc_version[1], \ 85713883Sdavid.hashe@amd.com termcap.Normal 85813883Sdavid.hashe@amd.com main['PROTOC'] = False 85913883Sdavid.hashe@amd.com else: 86013883Sdavid.hashe@amd.com # Attempt to determine the appropriate include path and 86113883Sdavid.hashe@amd.com # library path using pkg-config, that means we also need to 86213883Sdavid.hashe@amd.com # check for pkg-config. Note that it is possible to use 86313883Sdavid.hashe@amd.com # protobuf without the involvement of pkg-config. Later on we 86413883Sdavid.hashe@amd.com # check go a library config check and at that point the test 86513883Sdavid.hashe@amd.com # will fail if libprotobuf cannot be found. 86613883Sdavid.hashe@amd.com if readCommand(['pkg-config', '--version'], exception=''): 86713883Sdavid.hashe@amd.com try: 86813883Sdavid.hashe@amd.com # Attempt to establish what linking flags to add for protobuf 86913883Sdavid.hashe@amd.com # using pkg-config 87011907SBrandon.Potter@amd.com main.ParseConfig('pkg-config --cflags --libs-only-L protobuf') 87111907SBrandon.Potter@amd.com except: 87213883Sdavid.hashe@amd.com print termcap.Yellow + termcap.Bold + \ 87311907SBrandon.Potter@amd.com 'Warning: pkg-config could not get protobuf flags.' + \ 87413994Santhony.gutierrez@amd.com termcap.Normal 87511907SBrandon.Potter@amd.com 87613883Sdavid.hashe@amd.com# Check for SWIG 87713883Sdavid.hashe@amd.comif not main.has_key('SWIG'): 87813883Sdavid.hashe@amd.com print 'Error: SWIG utility not found.' 87913883Sdavid.hashe@amd.com print ' Please install (see http://www.swig.org) and retry.' 88011907SBrandon.Potter@amd.com Exit(1) 88111907SBrandon.Potter@amd.com 88213883Sdavid.hashe@amd.com# Check for appropriate SWIG version 88313883Sdavid.hashe@amd.comswig_version = readCommand([main['SWIG'], '-version'], exception='').split() 88411907SBrandon.Potter@amd.com# First 3 words should be "SWIG Version x.y.z" 88511907SBrandon.Potter@amd.comif len(swig_version) < 3 or \ 88611907SBrandon.Potter@amd.com swig_version[0] != 'SWIG' or swig_version[1] != 'Version': 88713883Sdavid.hashe@amd.com print 'Error determining SWIG version.' 88813883Sdavid.hashe@amd.com Exit(1) 88913883Sdavid.hashe@amd.com 89011907SBrandon.Potter@amd.commin_swig_version = '2.0.4' 89111907SBrandon.Potter@amd.comif compareVersions(swig_version[2], min_swig_version) < 0: 892360SN/A print 'Error: SWIG version', min_swig_version, 'or newer required.' 89311907SBrandon.Potter@amd.com print ' Installed version:', swig_version[2] 89411907SBrandon.Potter@amd.com Exit(1) 89511907SBrandon.Potter@amd.com 89611907SBrandon.Potter@amd.com# Check for known incompatibilities. The standard library shipped with 89711907SBrandon.Potter@amd.com# gcc >= 4.9 does not play well with swig versions prior to 3.0 89811907SBrandon.Potter@amd.comif main['GCC'] and compareVersions(gcc_version, '4.9') >= 0 and \ 89911907SBrandon.Potter@amd.com compareVersions(swig_version[2], '3.0') < 0: 90011907SBrandon.Potter@amd.com print termcap.Yellow + termcap.Bold + \ 90111907SBrandon.Potter@amd.com 'Warning: This combination of gcc and swig have' + \ 90211907SBrandon.Potter@amd.com ' known incompatibilities.\n' + \ 90313883Sdavid.hashe@amd.com ' If you encounter build problems, please update ' + \ 90413883Sdavid.hashe@amd.com 'swig to 3.0 or later.' + \ 90513883Sdavid.hashe@amd.com termcap.Normal 90611907SBrandon.Potter@amd.com 907360SN/A# Set up SWIG flags & scanner 908360SN/Aswig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS') 90910027SChris.Adeniyi-Jones@arm.commain.Append(SWIGFLAGS=swig_flags) 91010027SChris.Adeniyi-Jones@arm.com 91110027SChris.Adeniyi-Jones@arm.com# Check for 'timeout' from GNU coreutils. If present, regressions will 91213995Sbrandon.potter@amd.com# be run with a time limit. We require version 8.13 since we rely on 91310027SChris.Adeniyi-Jones@arm.com# support for the '--foreground' option. 91413995Sbrandon.potter@amd.comif sys.platform.startswith('freebsd'): 91510027SChris.Adeniyi-Jones@arm.com timeout_lines = readCommand(['gtimeout', '--version'], 91610027SChris.Adeniyi-Jones@arm.com exception='').splitlines() 91710027SChris.Adeniyi-Jones@arm.comelse: 91810027SChris.Adeniyi-Jones@arm.com timeout_lines = readCommand(['timeout', '--version'], 91910027SChris.Adeniyi-Jones@arm.com exception='').splitlines() 92013995Sbrandon.potter@amd.com# Get the first line and tokenize it 92110027SChris.Adeniyi-Jones@arm.comtimeout_version = timeout_lines[0].split() if timeout_lines else [] 92213995Sbrandon.potter@amd.commain['TIMEOUT'] = timeout_version and \ 92310027SChris.Adeniyi-Jones@arm.com compareVersions(timeout_version[-1], '8.13') >= 0 92410027SChris.Adeniyi-Jones@arm.com 92510633Smichaelupton@gmail.com# filter out all existing swig scanners, they mess up the dependency 92610633Smichaelupton@gmail.com# stuff for some reason 92710633Smichaelupton@gmail.comscanners = [] 92813995Sbrandon.potter@amd.comfor scanner in main['SCANNERS']: 92910633Smichaelupton@gmail.com skeys = scanner.skeys 93010633Smichaelupton@gmail.com if skeys == '.i': 93113995Sbrandon.potter@amd.com continue 93210633Smichaelupton@gmail.com 93310633Smichaelupton@gmail.com if isinstance(skeys, (list, tuple)) and '.i' in skeys: 93410633Smichaelupton@gmail.com continue 93510633Smichaelupton@gmail.com 93613995Sbrandon.potter@amd.com scanners.append(scanner) 93710633Smichaelupton@gmail.com 93810633Smichaelupton@gmail.com# add the new swig scanner that we like better 93910203SAli.Saidi@ARM.comfrom SCons.Scanner import ClassicCPP as CPPScanner 94010203SAli.Saidi@ARM.comswig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")' 94110203SAli.Saidi@ARM.comscanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re)) 94213995Sbrandon.potter@amd.com 94310203SAli.Saidi@ARM.com# replace the scanners list that has what we want 94410203SAli.Saidi@ARM.commain['SCANNERS'] = scanners 94513995Sbrandon.potter@amd.com 94610203SAli.Saidi@ARM.com# Add a custom Check function to test for structure members. 94710203SAli.Saidi@ARM.comdef CheckMember(context, include, decl, member, include_quotes="<>"): 94810203SAli.Saidi@ARM.com context.Message("Checking for member %s in %s..." % 94913995Sbrandon.potter@amd.com (member, decl)) 95010203SAli.Saidi@ARM.com text = """ 95110203SAli.Saidi@ARM.com#include %(header)s 95210203SAli.Saidi@ARM.comint main(){ 95310203SAli.Saidi@ARM.com %(decl)s test; 95410203SAli.Saidi@ARM.com (void)test.%(member)s; 95513995Sbrandon.potter@amd.com return 0; 95610203SAli.Saidi@ARM.com}; 95710203SAli.Saidi@ARM.com""" % { "header" : include_quotes[0] + include + include_quotes[1], 95813995Sbrandon.potter@amd.com "decl" : decl, 95910203SAli.Saidi@ARM.com "member" : member, 96010203SAli.Saidi@ARM.com } 96110203SAli.Saidi@ARM.com 96213995Sbrandon.potter@amd.com ret = context.TryCompile(text, extension=".cc") 96310203SAli.Saidi@ARM.com context.Result(ret) 96410203SAli.Saidi@ARM.com return ret 96510850SGiacomo.Gabrielli@arm.com 96610850SGiacomo.Gabrielli@arm.com# Platform-specific configuration. Note again that we assume that all 96710850SGiacomo.Gabrielli@arm.com# builds under a given build root run on the same host platform. 96813995Sbrandon.potter@amd.comconf = Configure(main, 96910850SGiacomo.Gabrielli@arm.com conf_dir = joinpath(build_root, '.scons_config'), 97010850SGiacomo.Gabrielli@arm.com log_file = joinpath(build_root, 'scons_config.log'), 97113995Sbrandon.potter@amd.com custom_tests = { 97210850SGiacomo.Gabrielli@arm.com 'CheckMember' : CheckMember, 97310850SGiacomo.Gabrielli@arm.com }) 97410850SGiacomo.Gabrielli@arm.com 97510850SGiacomo.Gabrielli@arm.com# Check if we should compile a 64 bit binary on Mac OS X/Darwin 97610850SGiacomo.Gabrielli@arm.comtry: 97710850SGiacomo.Gabrielli@arm.com import platform 97810850SGiacomo.Gabrielli@arm.com uname = platform.uname() 97914024Sgabeblack@google.com if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: 98010850SGiacomo.Gabrielli@arm.com if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): 98110850SGiacomo.Gabrielli@arm.com main.Append(CCFLAGS=['-arch', 'x86_64']) 98210850SGiacomo.Gabrielli@arm.com main.Append(CFLAGS=['-arch', 'x86_64']) 98310850SGiacomo.Gabrielli@arm.com main.Append(LINKFLAGS=['-arch', 'x86_64']) 98410850SGiacomo.Gabrielli@arm.com main.Append(ASFLAGS=['-arch', 'x86_64']) 98510850SGiacomo.Gabrielli@arm.comexcept: 98610850SGiacomo.Gabrielli@arm.com pass 98710850SGiacomo.Gabrielli@arm.com 98810850SGiacomo.Gabrielli@arm.com# Recent versions of scons substitute a "Null" object for Configure() 98914024Sgabeblack@google.com# when configuration isn't necessary, e.g., if the "--help" option is 99010850SGiacomo.Gabrielli@arm.com# present. Unfortuantely this Null object always returns false, 99110850SGiacomo.Gabrielli@arm.com# breaking all our configuration checks. We replace it with our own 99210850SGiacomo.Gabrielli@arm.com# more optimistic null object that returns True instead. 99313883Sdavid.hashe@amd.comif not conf: 99413883Sdavid.hashe@amd.com def NullCheck(*args, **kwargs): 99513883Sdavid.hashe@amd.com return True 99610850SGiacomo.Gabrielli@arm.com 99710850SGiacomo.Gabrielli@arm.com class NullConf: 99810850SGiacomo.Gabrielli@arm.com def __init__(self, env): 99910850SGiacomo.Gabrielli@arm.com self.env = env 100010850SGiacomo.Gabrielli@arm.com def Finish(self): 10016640Svince@csl.cornell.edu return self.env 10026640Svince@csl.cornell.edu def __getattr__(self, mname): 10036640Svince@csl.cornell.edu return NullCheck 100413995Sbrandon.potter@amd.com 10056640Svince@csl.cornell.edu conf = NullConf(main) 10066701Sgblack@eecs.umich.edu 100713995Sbrandon.potter@amd.com# Cache build files in the supplied directory. 100813995Sbrandon.potter@amd.comif main['M5_BUILD_CACHE']: 10096701Sgblack@eecs.umich.edu print 'Using build cache located at', main['M5_BUILD_CACHE'] 101010793Sbrandon.potter@amd.com CacheDir(main['M5_BUILD_CACHE']) 10116640Svince@csl.cornell.edu 101211758Sbrandon.potter@amd.comif not GetOption('without_python'): 101311758Sbrandon.potter@amd.com # Find Python include and library directories for embedding the 101411758Sbrandon.potter@amd.com # interpreter. We rely on python-config to resolve the appropriate 10156640Svince@csl.cornell.edu # includes and linker flags. ParseConfig does not seem to understand 101614024Sgabeblack@google.com # the more exotic linker flags such as -Xlinker and -export-dynamic so 10176640Svince@csl.cornell.edu # we add them explicitly below. If you want to link in an alternate 10186701Sgblack@eecs.umich.edu # version of python, see above for instructions on how to invoke 10196640Svince@csl.cornell.edu # scons with the appropriate PATH set. 1020360SN/A # 10211999SN/A # First we check if python2-config exists, else we use python-config 10221999SN/A python_config = readCommand(['which', 'python2-config'], 10231999SN/A exception='').strip() 102413995Sbrandon.potter@amd.com if not os.path.exists(python_config): 10251999SN/A python_config = readCommand(['which', 'python-config'], 10261999SN/A exception='').strip() 102713995Sbrandon.potter@amd.com py_includes = readCommand([python_config, '--includes'], 10281999SN/A exception='').split() 10296701Sgblack@eecs.umich.edu # Strip the -I from the include folders before adding them to the 103014024Sgabeblack@google.com # CPPPATH 10316701Sgblack@eecs.umich.edu main.Append(CPPPATH=map(lambda inc: inc[2:], py_includes)) 10321999SN/A 10336701Sgblack@eecs.umich.edu # Read the linker flags and split them into libraries and other link 10341999SN/A # flags. The libraries are added later through the call the CheckLib. 10356701Sgblack@eecs.umich.edu py_ld_flags = readCommand([python_config, '--ldflags'], 10361999SN/A exception='').split() 10371999SN/A py_libs = [] 10381999SN/A for lib in py_ld_flags: 10391999SN/A if not lib.startswith('-l'): 10401999SN/A main.Append(LINKFLAGS=[lib]) 104113883Sdavid.hashe@amd.com else: 104213883Sdavid.hashe@amd.com lib = lib[2:] 10433669Sbinkertn@umich.edu if lib not in py_libs: 10441999SN/A py_libs.append(lib) 10451999SN/A 10461999SN/A # verify that this stuff works 10472218SN/A if not conf.CheckHeader('Python.h', '<>'): 10481999SN/A print "Error: can't find Python.h header in", py_includes 10491999SN/A print "Install Python headers (package python-dev on Ubuntu and RedHat)" 10501999SN/A Exit(1) 10511999SN/A 105213570Sbrandon.potter@amd.com for lib in py_libs: 105313570Sbrandon.potter@amd.com if not conf.CheckLib(lib): 105413995Sbrandon.potter@amd.com print "Error: can't find library %s required by python" % lib 105513570Sbrandon.potter@amd.com Exit(1) 105613570Sbrandon.potter@amd.com 105713995Sbrandon.potter@amd.com# On Solaris you need to use libsocket for socket ops 105813570Sbrandon.potter@amd.comif not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): 105913570Sbrandon.potter@amd.com if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): 106013570Sbrandon.potter@amd.com print "Can't find library with socket calls (e.g. accept())" 106113570Sbrandon.potter@amd.com Exit(1) 106213570Sbrandon.potter@amd.com 106314024Sgabeblack@google.com# Check for zlib. If the check passes, libz will be automatically 106413570Sbrandon.potter@amd.com# added to the LIBS environment variable. 106513570Sbrandon.potter@amd.comif not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'): 106613570Sbrandon.potter@amd.com print 'Error: did not find needed zlib compression library '\ 106713570Sbrandon.potter@amd.com 'and/or zlib.h header file.' 106813570Sbrandon.potter@amd.com print ' Please install zlib and try again.' 106913570Sbrandon.potter@amd.com Exit(1) 107013570Sbrandon.potter@amd.com 107113570Sbrandon.potter@amd.com# If we have the protobuf compiler, also make sure we have the 107213570Sbrandon.potter@amd.com# development libraries. If the check passes, libprotobuf will be 107313570Sbrandon.potter@amd.com# automatically added to the LIBS environment variable. After 107413570Sbrandon.potter@amd.com# this, we can use the HAVE_PROTOBUF flag to determine if we have 107513570Sbrandon.potter@amd.com# got both protoc and libprotobuf available. 107613570Sbrandon.potter@amd.commain['HAVE_PROTOBUF'] = main['PROTOC'] and \ 107713570Sbrandon.potter@amd.com conf.CheckLibWithHeader('protobuf', 'google/protobuf/message.h', 107813570Sbrandon.potter@amd.com 'C++', 'GOOGLE_PROTOBUF_VERIFY_VERSION;') 107913570Sbrandon.potter@amd.com 108013570Sbrandon.potter@amd.com# If we have the compiler but not the library, print another warning. 108113570Sbrandon.potter@amd.comif main['PROTOC'] and not main['HAVE_PROTOBUF']: 108213570Sbrandon.potter@amd.com print termcap.Yellow + termcap.Bold + \ 108313570Sbrandon.potter@amd.com 'Warning: did not find protocol buffer library and/or headers.\n' + \ 108413570Sbrandon.potter@amd.com ' Please install libprotobuf-dev for tracing support.' + \ 108513570Sbrandon.potter@amd.com termcap.Normal 108613570Sbrandon.potter@amd.com 108713570Sbrandon.potter@amd.com# Check for librt. 108813570Sbrandon.potter@amd.comhave_posix_clock = \ 108913570Sbrandon.potter@amd.com conf.CheckLibWithHeader(None, 'time.h', 'C', 109013570Sbrandon.potter@amd.com 'clock_nanosleep(0,0,NULL,NULL);') or \ 109113570Sbrandon.potter@amd.com conf.CheckLibWithHeader('rt', 'time.h', 'C', 109213570Sbrandon.potter@amd.com 'clock_nanosleep(0,0,NULL,NULL);') 109313570Sbrandon.potter@amd.com 109413570Sbrandon.potter@amd.comhave_posix_timers = \ 109513570Sbrandon.potter@amd.com conf.CheckLibWithHeader([None, 'rt'], [ 'time.h', 'signal.h' ], 'C', 109613570Sbrandon.potter@amd.com 'timer_create(CLOCK_MONOTONIC, NULL, NULL);') 109713570Sbrandon.potter@amd.com 109813570Sbrandon.potter@amd.comif not GetOption('without_tcmalloc'): 109913570Sbrandon.potter@amd.com if conf.CheckLib('tcmalloc'): 110013570Sbrandon.potter@amd.com main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS']) 110113570Sbrandon.potter@amd.com elif conf.CheckLib('tcmalloc_minimal'): 110213570Sbrandon.potter@amd.com main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS']) 110313570Sbrandon.potter@amd.com else: 110413570Sbrandon.potter@amd.com print termcap.Yellow + termcap.Bold + \ 110513570Sbrandon.potter@amd.com "You can get a 12% performance improvement by "\ 110613570Sbrandon.potter@amd.com "installing tcmalloc (libgoogle-perftools-dev package "\ 110713570Sbrandon.potter@amd.com "on Ubuntu or RedHat)." + termcap.Normal 110813570Sbrandon.potter@amd.com 110913570Sbrandon.potter@amd.com 111013570Sbrandon.potter@amd.com# Detect back trace implementations. The last implementation in the 111113570Sbrandon.potter@amd.com# list will be used by default. 111213570Sbrandon.potter@amd.combacktrace_impls = [ "none" ] 111313570Sbrandon.potter@amd.com 111413570Sbrandon.potter@amd.comif conf.CheckLibWithHeader(None, 'execinfo.h', 'C', 111513570Sbrandon.potter@amd.com 'backtrace_symbols_fd((void*)0, 0, 0);'): 111613570Sbrandon.potter@amd.com backtrace_impls.append("glibc") 111713570Sbrandon.potter@amd.comelif conf.CheckLibWithHeader('execinfo', 'execinfo.h', 'C', 111813570Sbrandon.potter@amd.com 'backtrace_symbols_fd((void*)0, 0, 0);'): 111913570Sbrandon.potter@amd.com # NetBSD and FreeBSD need libexecinfo. 112013570Sbrandon.potter@amd.com backtrace_impls.append("glibc") 112113570Sbrandon.potter@amd.com main.Append(LIBS=['execinfo']) 112213570Sbrandon.potter@amd.com 112314024Sgabeblack@google.comif backtrace_impls[-1] == "none": 112413570Sbrandon.potter@amd.com default_backtrace_impl = "none" 112513570Sbrandon.potter@amd.com print termcap.Yellow + termcap.Bold + \ 112613570Sbrandon.potter@amd.com "No suitable back trace implementation found." + \ 11271999SN/A termcap.Normal 11281999SN/A 11291999SN/Aif not have_posix_clock: 11301999SN/A print "Can't find library for POSIX clocks." 113113995Sbrandon.potter@amd.com 11321999SN/A# Check for <fenv.h> (C99 FP environment control) 11336701Sgblack@eecs.umich.eduhave_fenv = conf.CheckHeader('fenv.h', '<>') 113413995Sbrandon.potter@amd.comif not have_fenv: 113511856Sbrandon.potter@amd.com print "Warning: Header file <fenv.h> not found." 113611856Sbrandon.potter@amd.com print " This host has no IEEE FP rounding mode control." 113710931Sbrandon.potter@amd.com 113811856Sbrandon.potter@amd.com# Check if we should enable KVM-based hardware virtualization. The API 113911856Sbrandon.potter@amd.com# we rely on exists since version 2.6.36 of the kernel, but somehow 11401999SN/A# the KVM_API_VERSION does not reflect the change. We test for one of 114111856Sbrandon.potter@amd.com# the types as a fall back. 11421999SN/Ahave_kvm = conf.CheckHeader('linux/kvm.h', '<>') 114311856Sbrandon.potter@amd.comif not have_kvm: 11441999SN/A print "Info: Compatible header file <linux/kvm.h> not found, " \ 114511856Sbrandon.potter@amd.com "disabling KVM support." 11461999SN/A 114711856Sbrandon.potter@amd.com# x86 needs support for xsave. We test for the structure here since we 11481999SN/A# won't be able to run new tests by the time we know which ISA we're 11491999SN/A# targeting. 11505877Shsul@eecs.umich.eduhave_kvm_xsave = conf.CheckTypeSize('struct kvm_xsave', 11515877Shsul@eecs.umich.edu '#include <linux/kvm.h>') != 0 11525877Shsul@eecs.umich.edu 115313995Sbrandon.potter@amd.com# Check if the requested target ISA is compatible with the host 11545877Shsul@eecs.umich.edudef is_isa_kvm_compatible(isa): 11556701Sgblack@eecs.umich.edu try: 115613995Sbrandon.potter@amd.com import platform 11576701Sgblack@eecs.umich.edu host_isa = platform.machine() 11586701Sgblack@eecs.umich.edu except: 11596701Sgblack@eecs.umich.edu print "Warning: Failed to determine host ISA." 11606701Sgblack@eecs.umich.edu return False 116110027SChris.Adeniyi-Jones@arm.com 116210027SChris.Adeniyi-Jones@arm.com if not have_posix_timers: 116310027SChris.Adeniyi-Jones@arm.com print "Warning: Can not enable KVM, host seems to lack support " \ 116410027SChris.Adeniyi-Jones@arm.com "for POSIX timers" 116510027SChris.Adeniyi-Jones@arm.com return False 11665877Shsul@eecs.umich.edu 116710318Sandreas.hansson@arm.com if isa == "arm": 116810318Sandreas.hansson@arm.com return host_isa in ( "armv7l", "aarch64" ) 11695877Shsul@eecs.umich.edu elif isa == "x86": 11705877Shsul@eecs.umich.edu if host_isa != "x86_64": 11715877Shsul@eecs.umich.edu return False 11725877Shsul@eecs.umich.edu 117310486Stjablin@gmail.com if not have_kvm_xsave: 117410486Stjablin@gmail.com print "KVM on x86 requires xsave support in kernel headers." 11755877Shsul@eecs.umich.edu return False 117611905SBrandon.Potter@amd.com 117711905SBrandon.Potter@amd.com return True 117811905SBrandon.Potter@amd.com else: 117911905SBrandon.Potter@amd.com return False 118010027SChris.Adeniyi-Jones@arm.com 118112206Srico.amslinger@informatik.uni-augsburg.de 118212206Srico.amslinger@informatik.uni-augsburg.de# Check if the exclude_host attribute is available. We want this to 11835877Shsul@eecs.umich.edu# get accurate instruction counts in KVM. 118411905SBrandon.Potter@amd.commain['HAVE_PERF_ATTR_EXCLUDE_HOST'] = conf.CheckMember( 118511905SBrandon.Potter@amd.com 'linux/perf_event.h', 'struct perf_event_attr', 'exclude_host') 11865877Shsul@eecs.umich.edu 11875877Shsul@eecs.umich.edu 118810027SChris.Adeniyi-Jones@arm.com###################################################################### 11895877Shsul@eecs.umich.edu# 11905877Shsul@eecs.umich.edu# Finish the configuration 11915877Shsul@eecs.umich.edu# 119212206Srico.amslinger@informatik.uni-augsburg.demain = conf.Finish() 119312206Srico.amslinger@informatik.uni-augsburg.de 119412206Srico.amslinger@informatik.uni-augsburg.de###################################################################### 119512206Srico.amslinger@informatik.uni-augsburg.de# 119612206Srico.amslinger@informatik.uni-augsburg.de# Collect all non-global variables 119712206Srico.amslinger@informatik.uni-augsburg.de# 119812206Srico.amslinger@informatik.uni-augsburg.de 119912206Srico.amslinger@informatik.uni-augsburg.de# Define the universe of supported ISAs 120012206Srico.amslinger@informatik.uni-augsburg.deall_isa_list = [ ] 120110027SChris.Adeniyi-Jones@arm.comall_gpu_isa_list = [ ] 120210027SChris.Adeniyi-Jones@arm.comExport('all_isa_list') 120310027SChris.Adeniyi-Jones@arm.comExport('all_gpu_isa_list') 120410027SChris.Adeniyi-Jones@arm.com 12055877Shsul@eecs.umich.educlass CpuModel(object): 120610027SChris.Adeniyi-Jones@arm.com '''The CpuModel class encapsulates everything the ISA parser needs to 120710027SChris.Adeniyi-Jones@arm.com know about a particular CPU model.''' 120810027SChris.Adeniyi-Jones@arm.com 120910027SChris.Adeniyi-Jones@arm.com # Dict of available CPU model objects. Accessible as CpuModel.dict. 121012206Srico.amslinger@informatik.uni-augsburg.de dict = {} 121112206Srico.amslinger@informatik.uni-augsburg.de 121212206Srico.amslinger@informatik.uni-augsburg.de # Constructor. Automatically adds models to CpuModel.dict. 121312206Srico.amslinger@informatik.uni-augsburg.de def __init__(self, name, default=False): 121410027SChris.Adeniyi-Jones@arm.com self.name = name # name of model 121510027SChris.Adeniyi-Jones@arm.com 121610027SChris.Adeniyi-Jones@arm.com # This cpu is enabled by default 121710027SChris.Adeniyi-Jones@arm.com self.default = default 121810027SChris.Adeniyi-Jones@arm.com 121910027SChris.Adeniyi-Jones@arm.com # Add self to dict 12205877Shsul@eecs.umich.edu if name in CpuModel.dict: 12215877Shsul@eecs.umich.edu raise AttributeError, "CpuModel '%s' already registered" % name 12225877Shsul@eecs.umich.edu CpuModel.dict[name] = self 122310027SChris.Adeniyi-Jones@arm.com 122410027SChris.Adeniyi-Jones@arm.comExport('CpuModel') 12258601Ssteve.reinhardt@amd.com 122610027SChris.Adeniyi-Jones@arm.com# Sticky variables get saved in the variables file so they persist from 12275877Shsul@eecs.umich.edu# one invocation to the next (unless overridden, in which case the new 12285877Shsul@eecs.umich.edu# value becomes sticky). 12291999SN/Asticky_vars = Variables(args=ARGUMENTS) 1230378SN/AExport('sticky_vars') 1231360SN/A 12321450SN/A# Sticky variables that should be exported 123313995Sbrandon.potter@amd.comexport_vars = [] 1234360SN/AExport('export_vars') 1235360SN/A 123613995Sbrandon.potter@amd.com# For Ruby 1237360SN/Aall_protocols = [] 12386701Sgblack@eecs.umich.eduExport('all_protocols') 123914024Sgabeblack@google.comprotocol_dirs = [] 12406701Sgblack@eecs.umich.eduExport('protocol_dirs') 12416701Sgblack@eecs.umich.eduslicc_includes = [] 12426701Sgblack@eecs.umich.eduExport('slicc_includes') 12436701Sgblack@eecs.umich.edu 1244360SN/A# Walk the tree and execute all SConsopts scripts that wil add to the 124513883Sdavid.hashe@amd.com# above variables 124613883Sdavid.hashe@amd.comif GetOption('verbose'): 12473669Sbinkertn@umich.edu print "Reading SConsopts" 1248360SN/Afor bdir in [ base_dir ] + extras_dir_list: 1249360SN/A if not isdir(bdir): 1250360SN/A print "Error: directory '%s' does not exist" % bdir 1251360SN/A Exit(1) 12522218SN/A for root, dirs, files in os.walk(bdir): 1253360SN/A if 'SConsopts' in files: 125414024Sgabeblack@google.com if GetOption('verbose'): 1255360SN/A print "Reading", joinpath(root, 'SConsopts') 12561458SN/A SConscript(joinpath(root, 'SConsopts')) 1257360SN/A 1258360SN/Aall_isa_list.sort() 1259360SN/Aall_gpu_isa_list.sort() 12605074Ssaidi@eecs.umich.edu 12615074Ssaidi@eecs.umich.edusticky_vars.AddVariables( 12625074Ssaidi@eecs.umich.edu EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), 126313995Sbrandon.potter@amd.com EnumVariable('TARGET_GPU_ISA', 'Target GPU ISA', 'hsail', all_gpu_isa_list), 12645074Ssaidi@eecs.umich.edu ListVariable('CPU_MODELS', 'CPU models', 12655074Ssaidi@eecs.umich.edu sorted(n for n,m in CpuModel.dict.iteritems() if m.default), 126613995Sbrandon.potter@amd.com sorted(CpuModel.dict.keys())), 12675074Ssaidi@eecs.umich.edu BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger', 12686701Sgblack@eecs.umich.edu False), 126914024Sgabeblack@google.com BoolVariable('SS_COMPATIBLE_FP', 12706701Sgblack@eecs.umich.edu 'Make floating-point results compatible with SimpleScalar', 12715074Ssaidi@eecs.umich.edu False), 12726701Sgblack@eecs.umich.edu BoolVariable('USE_SSE2', 12735074Ssaidi@eecs.umich.edu 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', 127413883Sdavid.hashe@amd.com False), 127513883Sdavid.hashe@amd.com BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock), 12765074Ssaidi@eecs.umich.edu BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), 12775208Ssaidi@eecs.umich.edu BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), 12785208Ssaidi@eecs.umich.edu BoolVariable('USE_KVM', 'Enable hardware virtualized (KVM) CPU models', have_kvm), 12795208Ssaidi@eecs.umich.edu BoolVariable('BUILD_GPU', 'Build the compute-GPU model', False), 12805208Ssaidi@eecs.umich.edu EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None', 12815074Ssaidi@eecs.umich.edu all_protocols), 12825074Ssaidi@eecs.umich.edu EnumVariable('BACKTRACE_IMPL', 'Post-mortem dump implementation', 12835208Ssaidi@eecs.umich.edu backtrace_impls[-1], backtrace_impls) 12845074Ssaidi@eecs.umich.edu ) 12855074Ssaidi@eecs.umich.edu 12865074Ssaidi@eecs.umich.edu# These variables get exported to #defines in config/*.hh (see src/SConscript). 12875074Ssaidi@eecs.umich.eduexport_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'TARGET_GPU_ISA', 128814024Sgabeblack@google.com 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'PROTOCOL', 12895074Ssaidi@eecs.umich.edu 'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST'] 12905074Ssaidi@eecs.umich.edu 12915074Ssaidi@eecs.umich.edu################################################### 12925074Ssaidi@eecs.umich.edu# 12935074Ssaidi@eecs.umich.edu# Define a SCons builder for configuration flag headers. 129410027SChris.Adeniyi-Jones@arm.com# 129510027SChris.Adeniyi-Jones@arm.com################################################### 129610027SChris.Adeniyi-Jones@arm.com 129713995Sbrandon.potter@amd.com# This function generates a config header file that #defines the 129810027SChris.Adeniyi-Jones@arm.com# variable symbol to the current variable setting (0 or 1). The source 129910027SChris.Adeniyi-Jones@arm.com# operands are the name of the variable and a Value node containing the 130013995Sbrandon.potter@amd.com# value of the variable. 130110027SChris.Adeniyi-Jones@arm.comdef build_config_file(target, source, env): 130210027SChris.Adeniyi-Jones@arm.com (variable, value) = [s.get_contents() for s in source] 130310793Sbrandon.potter@amd.com f = file(str(target[0]), 'w') 130410027SChris.Adeniyi-Jones@arm.com print >> f, '#define', variable, value 130510027SChris.Adeniyi-Jones@arm.com f.close() 130614024Sgabeblack@google.com return None 130710027SChris.Adeniyi-Jones@arm.com 130810027SChris.Adeniyi-Jones@arm.com# Combine the two functions into a scons Action object. 130910027SChris.Adeniyi-Jones@arm.comconfig_action = MakeAction(build_config_file, Transform("CONFIG H", 2)) 131010027SChris.Adeniyi-Jones@arm.com 131113883Sdavid.hashe@amd.com# The emitter munges the source & target node lists to reflect what 131213883Sdavid.hashe@amd.com# we're really doing. 131310027SChris.Adeniyi-Jones@arm.comdef config_emitter(target, source, env): 131410027SChris.Adeniyi-Jones@arm.com # extract variable name from Builder arg 131510027SChris.Adeniyi-Jones@arm.com variable = str(target[0]) 131610027SChris.Adeniyi-Jones@arm.com # True target is config header file 131710027SChris.Adeniyi-Jones@arm.com target = joinpath('config', variable.lower() + '.hh') 131810027SChris.Adeniyi-Jones@arm.com val = env[variable] 131910027SChris.Adeniyi-Jones@arm.com if isinstance(val, bool): 132010027SChris.Adeniyi-Jones@arm.com # Force value to 0/1 132110027SChris.Adeniyi-Jones@arm.com val = int(val) 132210027SChris.Adeniyi-Jones@arm.com elif isinstance(val, str): 132310027SChris.Adeniyi-Jones@arm.com val = '"' + val + '"' 132410027SChris.Adeniyi-Jones@arm.com 132514024Sgabeblack@google.com # Sources are variable name & value (packaged in SCons Value nodes) 132610027SChris.Adeniyi-Jones@arm.com return ([target], [Value(variable), Value(val)]) 132710027SChris.Adeniyi-Jones@arm.com 132810027SChris.Adeniyi-Jones@arm.comconfig_builder = Builder(emitter = config_emitter, action = config_action) 132910027SChris.Adeniyi-Jones@arm.com 133010027SChris.Adeniyi-Jones@arm.commain.Append(BUILDERS = { 'ConfigFile' : config_builder }) 13311999SN/A 13321999SN/A# libelf build is shared across all configs in the build root. 13331999SN/Amain.SConscript('ext/libelf/SConscript', 133413995Sbrandon.potter@amd.com variant_dir = joinpath(build_root, 'libelf')) 13351999SN/A 13366701Sgblack@eecs.umich.edu# iostream3 build is shared across all configs in the build root. 133713995Sbrandon.potter@amd.commain.SConscript('ext/iostream3/SConscript', 133811856Sbrandon.potter@amd.com variant_dir = joinpath(build_root, 'iostream3')) 133911856Sbrandon.potter@amd.com 134010931Sbrandon.potter@amd.com# libfdt build is shared across all configs in the build root. 134111856Sbrandon.potter@amd.commain.SConscript('ext/libfdt/SConscript', 134211856Sbrandon.potter@amd.com variant_dir = joinpath(build_root, 'libfdt')) 13431999SN/A 134411856Sbrandon.potter@amd.com# fputils build is shared across all configs in the build root. 13451999SN/Amain.SConscript('ext/fputils/SConscript', 13462764Sstever@eecs.umich.edu variant_dir = joinpath(build_root, 'fputils')) 13472064SN/A 134810931Sbrandon.potter@amd.com# DRAMSim2 build is shared across all configs in the build root. 13492064SN/Amain.SConscript('ext/dramsim2/SConscript', 13502064SN/A variant_dir = joinpath(build_root, 'dramsim2')) 135110931Sbrandon.potter@amd.com 13522064SN/A# DRAMPower build is shared across all configs in the build root. 13531999SN/Amain.SConscript('ext/drampower/SConscript', 13541999SN/A variant_dir = joinpath(build_root, 'drampower')) 13552218SN/A 13561999SN/A# nomali build is shared across all configs in the build root. 135714024Sgabeblack@google.commain.SConscript('ext/nomali/SConscript', 13581999SN/A variant_dir = joinpath(build_root, 'nomali')) 13591999SN/A 13601999SN/A################################################### 13611999SN/A# 13621999SN/A# This function is used to set up a directory with switching headers 1363378SN/A# 1364360SN/A################################################### 13651450SN/A 136613995Sbrandon.potter@amd.commain['ALL_ISA_LIST'] = all_isa_list 1367360SN/Amain['ALL_GPU_ISA_LIST'] = all_gpu_isa_list 1368360SN/Aall_isa_deps = {} 136913995Sbrandon.potter@amd.comdef make_switching_dir(dname, switch_headers, env): 1370360SN/A # Generate the header. target[0] is the full path of the output 13716701Sgblack@eecs.umich.edu # header to generate. 'source' is a dummy variable, since we get the 137214024Sgabeblack@google.com # list of ISAs from env['ALL_ISA_LIST']. 13736701Sgblack@eecs.umich.edu def gen_switch_hdr(target, source, env): 13746701Sgblack@eecs.umich.edu fname = str(target[0]) 13756701Sgblack@eecs.umich.edu isa = env['TARGET_ISA'].lower() 13766701Sgblack@eecs.umich.edu try: 1377360SN/A f = open(fname, 'w') 137813883Sdavid.hashe@amd.com print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 137913883Sdavid.hashe@amd.com f.close() 13803669Sbinkertn@umich.edu except IOError: 1381360SN/A print "Failed to create %s" % fname 1382360SN/A raise 1383360SN/A 1384360SN/A # Build SCons Action object. 'varlist' specifies env vars that this 13851458SN/A # action depends on; when env['ALL_ISA_LIST'] changes these actions 1386360SN/A # should get re-executed. 138714024Sgabeblack@google.com switch_hdr_action = MakeAction(gen_switch_hdr, 1388360SN/A Transform("GENERATE"), varlist=['ALL_ISA_LIST']) 13891458SN/A 1390360SN/A # Instantiate actions for each header 1391360SN/A for hdr in switch_headers: 13921999SN/A env.Command(hdr, [], switch_hdr_action) 13931999SN/A 13941999SN/A isa_target = Dir('.').up().name.lower().replace('_', '-') 139513995Sbrandon.potter@amd.com env['PHONY_BASE'] = '#'+isa_target 13961999SN/A all_isa_deps[isa_target] = None 13971999SN/A 139813995Sbrandon.potter@amd.comExport('make_switching_dir') 13991999SN/A 14006701Sgblack@eecs.umich.edudef make_gpu_switching_dir(dname, switch_headers, env): 140114024Sgabeblack@google.com # Generate the header. target[0] is the full path of the output 14026701Sgblack@eecs.umich.edu # header to generate. 'source' is a dummy variable, since we get the 14036701Sgblack@eecs.umich.edu # list of ISAs from env['ALL_ISA_LIST']. 14046701Sgblack@eecs.umich.edu def gen_switch_hdr(target, source, env): 14056701Sgblack@eecs.umich.edu fname = str(target[0]) 14061999SN/A 140713883Sdavid.hashe@amd.com isa = env['TARGET_GPU_ISA'].lower() 140813883Sdavid.hashe@amd.com 14093669Sbinkertn@umich.edu try: 14102764Sstever@eecs.umich.edu f = open(fname, 'w') 14112064SN/A print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 14122064SN/A f.close() 14132064SN/A except IOError: 14141999SN/A print "Failed to create %s" % fname 14151999SN/A raise 14162064SN/A 14171999SN/A # Build SCons Action object. 'varlist' specifies env vars that this 14181999SN/A # action depends on; when env['ALL_ISA_LIST'] changes these actions 14191999SN/A # should get re-executed. 14201999SN/A switch_hdr_action = MakeAction(gen_switch_hdr, 142114024Sgabeblack@google.com Transform("GENERATE"), varlist=['ALL_ISA_GPU_LIST']) 14221999SN/A 14231999SN/A # Instantiate actions for each header 14241999SN/A for hdr in switch_headers: 14251999SN/A env.Command(hdr, [], switch_hdr_action) 1426378SN/A 1427360SN/AExport('make_gpu_switching_dir') 14281450SN/A 142913995Sbrandon.potter@amd.com# all-isas -> all-deps -> all-environs -> all_targets 1430360SN/Amain.Alias('#all-isas', []) 14316701Sgblack@eecs.umich.edumain.Alias('#all-deps', '#all-isas') 143213995Sbrandon.potter@amd.com 143311856Sbrandon.potter@amd.com# Dummy target to ensure all environments are created before telling 143411856Sbrandon.potter@amd.com# SCons what to actually make (the command line arguments). We attach 1435360SN/A# them to the dependence graph after the environments are complete. 143611380Salexandru.dutu@amd.comORIG_BUILD_TARGETS = list(BUILD_TARGETS) # force a copy; gets closure to work. 1437360SN/Adef environsComplete(target, source, env): 143811856Sbrandon.potter@amd.com for t in ORIG_BUILD_TARGETS: 143911856Sbrandon.potter@amd.com main.Depends('#all-targets', t) 14401458SN/A 144111856Sbrandon.potter@amd.com# Each build/* switching_dir attaches its *-environs target to #all-environs. 1442360SN/Amain.Append(BUILDERS = {'CompleteEnvirons' : 1443360SN/A Builder(action=MakeAction(environsComplete, None))}) 144410931Sbrandon.potter@amd.commain.CompleteEnvirons('#all-environs', []) 1445360SN/A 1446360SN/Adef doNothing(**ignored): pass 14471458SN/Amain.Append(BUILDERS = {'Dummy': Builder(action=MakeAction(doNothing, None))}) 1448360SN/A 144914024Sgabeblack@google.com# The final target to which all the original targets ultimately get attached. 14502021SN/Amain.Dummy('#all-targets', '#all-environs') 14511458SN/ABUILD_TARGETS[:] = ['#all-targets'] 1452360SN/A 1453360SN/A################################################### 14541706SN/A# 14551706SN/A# Define build environments for selected configurations. 14561706SN/A# 145713995Sbrandon.potter@amd.com################################################### 14581706SN/A 145913936SAndrea.Mondelli@ucf.edufor variant_path in variant_paths: 14601706SN/A if not GetOption('silent'): 146113995Sbrandon.potter@amd.com print "Building in", variant_path 14621706SN/A 14636701Sgblack@eecs.umich.edu # Make a copy of the build-root environment to use for this config. 146414024Sgabeblack@google.com env = main.Clone() 14656701Sgblack@eecs.umich.edu env['BUILDDIR'] = variant_path 14666701Sgblack@eecs.umich.edu 14676701Sgblack@eecs.umich.edu # variant_dir is the tail component of build path, and is used to 14686701Sgblack@eecs.umich.edu # determine the build parameters (e.g., 'ALPHA_SE') 14691706SN/A (build_root, variant_dir) = splitpath(variant_path) 147013883Sdavid.hashe@amd.com 147113883Sdavid.hashe@amd.com # Set env variables according to the build directory config. 14723669Sbinkertn@umich.edu sticky_vars.files = [] 14731706SN/A # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in 14741706SN/A # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke 14751706SN/A # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings. 14761706SN/A current_vars_file = joinpath(build_root, 'variables', variant_dir) 14772218SN/A if isfile(current_vars_file): 14781706SN/A sticky_vars.files.append(current_vars_file) 147914024Sgabeblack@google.com if not GetOption('silent'): 148013933Sbrandon.potter@amd.com print "Using saved variables file %s" % current_vars_file 148113933Sbrandon.potter@amd.com else: 148213933Sbrandon.potter@amd.com # Build dir-specific variables file doesn't exist. 148313933Sbrandon.potter@amd.com 148411799Sbrandon.potter@amd.com # Make sure the directory is there so we can create it later 14851706SN/A opt_dir = dirname(current_vars_file) 14861706SN/A if not isdir(opt_dir): 148711886Sbrandon.potter@amd.com mkdir(opt_dir) 148811886Sbrandon.potter@amd.com 148913995Sbrandon.potter@amd.com # Get default build variables from source tree. Variables are 149011886Sbrandon.potter@amd.com # normally determined by name of $VARIANT_DIR, but can be 149111886Sbrandon.potter@amd.com # overridden by '--default=' arg on command line. 149212426Sqtt2@cornell.edu default = GetOption('default') 149313995Sbrandon.potter@amd.com opts_dir = joinpath(main.root.abspath, 'build_opts') 149413557Sgabeblack@google.com if default: 149513557Sgabeblack@google.com default_vars_files = [joinpath(build_root, 'variables', default), 149611886Sbrandon.potter@amd.com joinpath(opts_dir, default)] 149712426Sqtt2@cornell.edu else: 149813534Sandreas.sandberg@arm.com default_vars_files = [joinpath(opts_dir, variant_dir)] 149912426Sqtt2@cornell.edu existing_files = filter(isfile, default_vars_files) 150013534Sandreas.sandberg@arm.com if existing_files: 150112426Sqtt2@cornell.edu default_vars_file = existing_files[0] 150212426Sqtt2@cornell.edu sticky_vars.files.append(default_vars_file) 150312426Sqtt2@cornell.edu print "Variables file %s not found,\n using defaults in %s" \ 150413536Sandreas.sandberg@arm.com % (current_vars_file, default_vars_file) 150512426Sqtt2@cornell.edu else: 150612426Sqtt2@cornell.edu print "Error: cannot find variables file %s or " \ 150711886Sbrandon.potter@amd.com "default file(s) %s" \ 150813536Sandreas.sandberg@arm.com % (current_vars_file, ' or '.join(default_vars_files)) 150912426Sqtt2@cornell.edu Exit(1) 151011886Sbrandon.potter@amd.com 151111886Sbrandon.potter@amd.com # Apply current variable settings to env 151211886Sbrandon.potter@amd.com sticky_vars.Update(env) 151311886Sbrandon.potter@amd.com 151411886Sbrandon.potter@amd.com help_texts["local_vars"] += \ 151511886Sbrandon.potter@amd.com "Build variables for %s:\n" % variant_dir \ 151611886Sbrandon.potter@amd.com + sticky_vars.GenerateHelpText(env) 151711886Sbrandon.potter@amd.com 151811886Sbrandon.potter@amd.com # Process variable settings. 151911886Sbrandon.potter@amd.com 152013649Sqtt2@cornell.edu if not have_fenv and env['USE_FENV']: 152113649Sqtt2@cornell.edu print "Warning: <fenv.h> not available; " \ 152213649Sqtt2@cornell.edu "forcing USE_FENV to False in", variant_dir + "." 152313649Sqtt2@cornell.edu env['USE_FENV'] = False 152413649Sqtt2@cornell.edu 152511886Sbrandon.potter@amd.com if not env['USE_FENV']: 152611886Sbrandon.potter@amd.com print "Warning: No IEEE FP rounding mode control in", variant_dir + "." 152711886Sbrandon.potter@amd.com print " FP results may deviate slightly from other platforms." 152811886Sbrandon.potter@amd.com 152911886Sbrandon.potter@amd.com if env['EFENCE']: 153011886Sbrandon.potter@amd.com env.Append(LIBS=['efence']) 153111886Sbrandon.potter@amd.com 153211886Sbrandon.potter@amd.com if env['USE_KVM']: 153311886Sbrandon.potter@amd.com if not have_kvm: 153411886Sbrandon.potter@amd.com print "Warning: Can not enable KVM, host seems to lack KVM support" 153511886Sbrandon.potter@amd.com env['USE_KVM'] = False 153613883Sdavid.hashe@amd.com elif not is_isa_kvm_compatible(env['TARGET_ISA']): 153711886Sbrandon.potter@amd.com print "Info: KVM support disabled due to unsupported host and " \ 153811886Sbrandon.potter@amd.com "target ISA combination" 153911886Sbrandon.potter@amd.com env['USE_KVM'] = False 154011886Sbrandon.potter@amd.com 154111886Sbrandon.potter@amd.com if env['BUILD_GPU']: 154211886Sbrandon.potter@amd.com env.Append(CPPDEFINES=['BUILD_GPU']) 154311886Sbrandon.potter@amd.com 154411886Sbrandon.potter@amd.com # Warn about missing optional functionality 154511886Sbrandon.potter@amd.com if env['USE_KVM']: 154611886Sbrandon.potter@amd.com if not main['HAVE_PERF_ATTR_EXCLUDE_HOST']: 154711886Sbrandon.potter@amd.com print "Warning: perf_event headers lack support for the " \ 154811886Sbrandon.potter@amd.com "exclude_host attribute. KVM instruction counts will " \ 154911886Sbrandon.potter@amd.com "be inaccurate." 155011886Sbrandon.potter@amd.com 155111886Sbrandon.potter@amd.com # Save sticky variable settings back to current variables file 155211886Sbrandon.potter@amd.com sticky_vars.Save(current_vars_file, env) 155311886Sbrandon.potter@amd.com 155411886Sbrandon.potter@amd.com if env['USE_SSE2']: 155511886Sbrandon.potter@amd.com env.Append(CCFLAGS=['-msse2']) 155613867Salexandru.dutu@amd.com 155713867Salexandru.dutu@amd.com # The src/SConscript file sets up the build rules in 'env' according 155811886Sbrandon.potter@amd.com # to the configured variables. It returns a list of environments, 155911886Sbrandon.potter@amd.com # one for each variant build (debug, opt, etc.) 156011886Sbrandon.potter@amd.com SConscript('src/SConscript', variant_dir = variant_path, exports = 'env') 156111886Sbrandon.potter@amd.com 156211886Sbrandon.potter@amd.comdef pairwise(iterable): 156311886Sbrandon.potter@amd.com "s -> (s0,s1), (s1,s2), (s2, s3), ..." 156411886Sbrandon.potter@amd.com a, b = itertools.tee(iterable) 156511886Sbrandon.potter@amd.com b.next() 156611886Sbrandon.potter@amd.com return itertools.izip(a, b) 156711886Sbrandon.potter@amd.com 156811886Sbrandon.potter@amd.com# Create false dependencies so SCons will parse ISAs, establish 156911886Sbrandon.potter@amd.com# dependencies, and setup the build Environments serially. Either 157014024Sgabeblack@google.com# SCons (likely) and/or our SConscripts (possibly) cannot cope with -j 157111886Sbrandon.potter@amd.com# greater than 1. It appears to be standard race condition stuff; it 157211886Sbrandon.potter@amd.com# doesn't always fail, but usually, and the behaviors are different. 157313867Salexandru.dutu@amd.com# Every time I tried to remove this, builds would fail in some 157413867Salexandru.dutu@amd.com# creative new way. So, don't do that. You'll want to, though, because 157513867Salexandru.dutu@amd.com# tests/SConscript takes a long time to make its Environments. 157613867Salexandru.dutu@amd.comfor t1, t2 in pairwise(sorted(all_isa_deps.iterkeys())): 157711886Sbrandon.potter@amd.com main.Depends('#%s-deps' % t2, '#%s-deps' % t1) 157811886Sbrandon.potter@amd.com main.Depends('#%s-environs' % t2, '#%s-environs' % t1) 157911886Sbrandon.potter@amd.com 158011911SBrandon.Potter@amd.com# base help text 158111911SBrandon.Potter@amd.comHelp(''' 158211911SBrandon.Potter@amd.comUsage: scons [scons options] [build variables] [target(s)] 158311911SBrandon.Potter@amd.com 158411911SBrandon.Potter@amd.comExtra scons options: 158511911SBrandon.Potter@amd.com%(options)s 158611911SBrandon.Potter@amd.com 158711886Sbrandon.potter@amd.comGlobal build variables: 158811886Sbrandon.potter@amd.com%(global_vars)s 158911886Sbrandon.potter@amd.com 159011886Sbrandon.potter@amd.com%(local_vars)s 159114024Sgabeblack@google.com''' % help_texts) 159211886Sbrandon.potter@amd.com