SConstruct revision 9591:b6a47b43f4df
12221SN/A# -*- mode:python -*- 22221SN/A 32221SN/A# Copyright (c) 2011 Advanced Micro Devices, Inc. 42221SN/A# Copyright (c) 2009 The Hewlett-Packard Development Company 52221SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 62221SN/A# All rights reserved. 72221SN/A# 82221SN/A# Redistribution and use in source and binary forms, with or without 92221SN/A# modification, are permitted provided that the following conditions are 102221SN/A# met: redistributions of source code must retain the above copyright 112221SN/A# notice, this list of conditions and the following disclaimer; 122221SN/A# redistributions in binary form must reproduce the above copyright 132221SN/A# notice, this list of conditions and the following disclaimer in the 142221SN/A# documentation and/or other materials provided with the distribution; 152221SN/A# neither the name of the copyright holders nor the names of its 162221SN/A# contributors may be used to endorse or promote products derived from 172221SN/A# this software without specific prior written permission. 182221SN/A# 192221SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 202221SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 212221SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 222221SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 232221SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 242221SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 252221SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 262221SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 272665Ssaidi@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 282665Ssaidi@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 292665Ssaidi@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 302221SN/A# 312221SN/A# Authors: Steve Reinhardt 3211793Sbrandon.potter@amd.com# Nathan Binkert 3311793Sbrandon.potter@amd.com 343415Sgblack@eecs.umich.edu################################################### 353415Sgblack@eecs.umich.edu# 363415Sgblack@eecs.umich.edu# SCons top-level build description (SConstruct) file. 378778Sgblack@eecs.umich.edu# 3812461Sgabeblack@google.com# While in this directory ('gem5'), just type 'scons' to build the default 393578Sgblack@eecs.umich.edu# configuration (see below), or type 'scons build/<CONFIG>/<binary>' 403415Sgblack@eecs.umich.edu# to build some other configuration (e.g., 'build/ALPHA/gem5.opt' for 413415Sgblack@eecs.umich.edu# the optimized full-system version). 423415Sgblack@eecs.umich.edu# 432680Sktlim@umich.edu# You can build gem5 in a different directory as long as there is a 443415Sgblack@eecs.umich.edu# 'build/<CONFIG>' somewhere along the target path. The build system 4511793Sbrandon.potter@amd.com# expects that all configs under the same build directory are being 462800Ssaidi@eecs.umich.edu# built for the same host system. 472221SN/A# 483415Sgblack@eecs.umich.edu# Examples: 493415Sgblack@eecs.umich.edu# 502223SN/A# The following two commands are equivalent. The '-u' option tells 512221SN/A# scons to search up the directory tree for this SConstruct file. 522221SN/A# % cd <path-to-src>/gem5 ; scons build/ALPHA/gem5.debug 533573Sgblack@eecs.umich.edu# % cd <path-to-src>/gem5/build/ALPHA; scons -u gem5.debug 5412517Srekai.gonzalezalberquilla@arm.com# 5512572Sgabeblack@google.com# The following two commands are equivalent and demonstrate building 562221SN/A# in a directory outside of the source tree. The '-C' option tells 573573Sgblack@eecs.umich.edu# scons to chdir to the specified directory to find this SConstruct 5812517Srekai.gonzalezalberquilla@arm.com# file. 5912572Sgabeblack@google.com# % cd <path-to-src>/gem5 ; scons /local/foo/build/ALPHA/gem5.debug 602221SN/A# % cd /local/foo/build/ALPHA; scons -C <path-to-src>/gem5 gem5.debug 613573Sgblack@eecs.umich.edu# 6212517Srekai.gonzalezalberquilla@arm.com# You can use 'scons -H' to print scons options. If you're in this 6312572Sgabeblack@google.com# 'gem5' directory (or use -u or -C to tell scons where to find this 642221SN/A# file), you can use 'scons -h' to print all the gem5-specific build 653573Sgblack@eecs.umich.edu# options as well. 6612517Srekai.gonzalezalberquilla@arm.com# 6712572Sgabeblack@google.com################################################### 682221SN/A 693573Sgblack@eecs.umich.edu# Check for recent-enough Python and SCons versions. 7012517Srekai.gonzalezalberquilla@arm.comtry: 7112572Sgabeblack@google.com # Really old versions of scons only take two options for the 722221SN/A # function, so check once without the revision and once with the 733573Sgblack@eecs.umich.edu # revision, the first instance will fail for stuff other than 7412517Srekai.gonzalezalberquilla@arm.com # 0.98, and the second will fail for 0.98.0 7512572Sgabeblack@google.com EnsureSConsVersion(0, 98) 762221SN/A EnsureSConsVersion(0, 98, 1) 773573Sgblack@eecs.umich.eduexcept SystemExit, e: 7812517Srekai.gonzalezalberquilla@arm.com print """ 7912572Sgabeblack@google.comFor more details, see: 803576Sgblack@eecs.umich.edu http://gem5.org/Dependencies 813576Sgblack@eecs.umich.edu""" 823576Sgblack@eecs.umich.edu raise 8312517Srekai.gonzalezalberquilla@arm.com 8412572Sgabeblack@google.com# We ensure the python version early because we have stuff that 852221SN/A# requires python 2.4 863573Sgblack@eecs.umich.edutry: 8712517Srekai.gonzalezalberquilla@arm.com EnsurePythonVersion(2, 4) 8812572Sgabeblack@google.comexcept SystemExit, e: 892221SN/A print """ 903573Sgblack@eecs.umich.eduYou can use a non-default installation of the Python interpreter by 9112517Srekai.gonzalezalberquilla@arm.comeither (1) rearranging your PATH so that scons finds the non-default 9212572Sgabeblack@google.com'python' first or (2) explicitly invoking an alternative interpreter 932221SN/Aon the scons script. 943573Sgblack@eecs.umich.edu 9512517Srekai.gonzalezalberquilla@arm.comFor more details, see: 9612572Sgabeblack@google.com http://gem5.org/wiki/index.php/Using_a_non-default_Python_installation 973576Sgblack@eecs.umich.edu""" 983576Sgblack@eecs.umich.edu raise 993576Sgblack@eecs.umich.edu 10012517Srekai.gonzalezalberquilla@arm.com# Global Python includes 10112572Sgabeblack@google.comimport os 1023576Sgblack@eecs.umich.eduimport re 1033576Sgblack@eecs.umich.eduimport subprocess 1043576Sgblack@eecs.umich.eduimport sys 10512517Srekai.gonzalezalberquilla@arm.com 10612572Sgabeblack@google.comfrom os import mkdir, environ 1072221SN/Afrom os.path import abspath, basename, dirname, expanduser, normpath 1083573Sgblack@eecs.umich.edufrom os.path import exists, isdir, isfile 10912517Srekai.gonzalezalberquilla@arm.comfrom os.path import join as joinpath, split as splitpath 11012572Sgabeblack@google.com 1112221SN/A# SCons includes 11212110SRekai.GonzalezAlberquilla@arm.comimport SCons 11312110SRekai.GonzalezAlberquilla@arm.comimport SCons.Node 11412110SRekai.GonzalezAlberquilla@arm.com 11512572Sgabeblack@google.comextra_python_paths = [ 11612572Sgabeblack@google.com Dir('src/python').srcnode().abspath, # gem5 includes 11712110SRekai.GonzalezAlberquilla@arm.com Dir('ext/ply').srcnode().abspath, # ply is used by several files 1183573Sgblack@eecs.umich.edu ] 11912517Srekai.gonzalezalberquilla@arm.com 12012572Sgabeblack@google.comsys.path[1:1] = extra_python_paths 1212221SN/A 1223573Sgblack@eecs.umich.edufrom m5.util import compareVersions, readCommand 12312517Srekai.gonzalezalberquilla@arm.comfrom m5.util.terminal import get_termcap 12412572Sgabeblack@google.com 1252221SN/Ahelp_texts = { 1263573Sgblack@eecs.umich.edu "options" : "", 12712517Srekai.gonzalezalberquilla@arm.com "global_vars" : "", 12812572Sgabeblack@google.com "local_vars" : "" 1292221SN/A} 1303573Sgblack@eecs.umich.edu 13112517Srekai.gonzalezalberquilla@arm.comExport("help_texts") 13212572Sgabeblack@google.com 1332221SN/A 1343573Sgblack@eecs.umich.edu# There's a bug in scons in that (1) by default, the help texts from 13512517Srekai.gonzalezalberquilla@arm.com# AddOption() are supposed to be displayed when you type 'scons -h' 13612572Sgabeblack@google.com# and (2) you can override the help displayed by 'scons -h' using the 1372223SN/A# Help() function, but these two features are incompatible: once 1383573Sgblack@eecs.umich.edu# you've overridden the help text using Help(), there's no way to get 13912517Srekai.gonzalezalberquilla@arm.com# at the help texts from AddOptions. See: 14012572Sgabeblack@google.com# http://scons.tigris.org/issues/show_bug.cgi?id=2356 1412223SN/A# http://scons.tigris.org/issues/show_bug.cgi?id=2611 1423573Sgblack@eecs.umich.edu# This hack lets us extract the help text from AddOptions and 14312517Srekai.gonzalezalberquilla@arm.com# re-inject it via Help(). Ideally someday this bug will be fixed and 14412572Sgabeblack@google.com# we can just use AddOption directly. 1452223SN/Adef AddLocalOption(*args, **kwargs): 1463573Sgblack@eecs.umich.edu col_width = 30 14712517Srekai.gonzalezalberquilla@arm.com 14812572Sgabeblack@google.com help = " " + ", ".join(args) 1492223SN/A if "help" in kwargs: 1503573Sgblack@eecs.umich.edu length = len(help) 15112517Srekai.gonzalezalberquilla@arm.com if length >= col_width: 15212572Sgabeblack@google.com help += "\n" + " " * col_width 1533576Sgblack@eecs.umich.edu else: 1543576Sgblack@eecs.umich.edu help += " " * (col_width - length) 1553576Sgblack@eecs.umich.edu help += kwargs["help"] 15612517Srekai.gonzalezalberquilla@arm.com help_texts["options"] += help + "\n" 15712572Sgabeblack@google.com 1582223SN/A AddOption(*args, **kwargs) 1593573Sgblack@eecs.umich.edu 16012517Srekai.gonzalezalberquilla@arm.comAddLocalOption('--colors', dest='use_colors', action='store_true', 16112572Sgabeblack@google.com help="Add color to abbreviated scons output") 1622223SN/AAddLocalOption('--no-colors', dest='use_colors', action='store_false', 1633573Sgblack@eecs.umich.edu help="Don't add color to abbreviated scons output") 16412517Srekai.gonzalezalberquilla@arm.comAddLocalOption('--default', dest='default', type='string', action='store', 16512572Sgabeblack@google.com help='Override which build_opts file to use for defaults') 1662223SN/AAddLocalOption('--ignore-style', dest='ignore_style', action='store_true', 1673573Sgblack@eecs.umich.edu help='Disable style checking hooks') 16812517Srekai.gonzalezalberquilla@arm.comAddLocalOption('--no-lto', dest='no_lto', action='store_true', 16912572Sgabeblack@google.com help='Disable Link-Time Optimization for fast') 1702223SN/AAddLocalOption('--update-ref', dest='update_ref', action='store_true', 1713573Sgblack@eecs.umich.edu help='Update test reference outputs') 17212517Srekai.gonzalezalberquilla@arm.comAddLocalOption('--verbose', dest='verbose', action='store_true', 17312572Sgabeblack@google.com help='Print full tool command lines') 1742223SN/A 1753573Sgblack@eecs.umich.edutermcap = get_termcap(GetOption('use_colors')) 17612517Srekai.gonzalezalberquilla@arm.com 17712572Sgabeblack@google.com######################################################################## 1782223SN/A# 1793573Sgblack@eecs.umich.edu# Set up the main build environment. 18012517Srekai.gonzalezalberquilla@arm.com# 18112572Sgabeblack@google.com######################################################################## 1822223SN/Ause_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 1833573Sgblack@eecs.umich.edu 'LIBRARY_PATH', 'PATH', 'PKG_CONFIG_PATH', 'PYTHONPATH', 18412517Srekai.gonzalezalberquilla@arm.com 'RANLIB', 'SWIG' ]) 18512572Sgabeblack@google.com 1862223SN/Ause_prefixes = [ 1873573Sgblack@eecs.umich.edu "M5", # M5 configuration (e.g., path to kernels) 18812517Srekai.gonzalezalberquilla@arm.com "DISTCC_", # distcc (distributed compiler wrapper) configuration 18912572Sgabeblack@google.com "CCACHE_", # ccache (caching compiler wrapper) configuration 1902223SN/A "CCC_", # clang static analyzer configuration 1913573Sgblack@eecs.umich.edu ] 19212517Srekai.gonzalezalberquilla@arm.com 19312572Sgabeblack@google.comuse_env = {} 1942223SN/Afor key,val in os.environ.iteritems(): 1953573Sgblack@eecs.umich.edu if key in use_vars or \ 19612517Srekai.gonzalezalberquilla@arm.com any([key.startswith(prefix) for prefix in use_prefixes]): 19712572Sgabeblack@google.com use_env[key] = val 1982223SN/A 1993576Sgblack@eecs.umich.edumain = Environment(ENV=use_env) 2003576Sgblack@eecs.umich.edumain.Decider('MD5-timestamp') 20112517Srekai.gonzalezalberquilla@arm.commain.root = Dir(".") # The current directory (where this file lives). 20212572Sgabeblack@google.commain.srcdir = Dir("src") # The source directory 2032527SN/A 2043573Sgblack@eecs.umich.edumain_dict_keys = main.Dictionary().keys() 20512517Srekai.gonzalezalberquilla@arm.com 20612572Sgabeblack@google.com# Check that we have a C/C++ compiler 2072223SN/Aif not ('CC' in main_dict_keys and 'CXX' in main_dict_keys): 2083573Sgblack@eecs.umich.edu print "No C++ compiler installed (package g++ on Ubuntu and RedHat)" 20912517Srekai.gonzalezalberquilla@arm.com Exit(1) 21012572Sgabeblack@google.com 2112223SN/A# Check that swig is present 2123573Sgblack@eecs.umich.eduif not 'SWIG' in main_dict_keys: 21312517Srekai.gonzalezalberquilla@arm.com print "swig is not installed (package swig on Ubuntu and RedHat)" 21412572Sgabeblack@google.com Exit(1) 2152223SN/A 2163573Sgblack@eecs.umich.edu# add useful python code PYTHONPATH so it can be used by subprocesses 21712517Srekai.gonzalezalberquilla@arm.com# as well 21812572Sgabeblack@google.commain.AppendENVPath('PYTHONPATH', extra_python_paths) 2194103Ssaidi@eecs.umich.edu 2204103Ssaidi@eecs.umich.edu######################################################################## 22112517Srekai.gonzalezalberquilla@arm.com# 22212572Sgabeblack@google.com# Mercurial Stuff. 2232223SN/A# 2243573Sgblack@eecs.umich.edu# If the gem5 directory is a mercurial repository, we should do some 22512517Srekai.gonzalezalberquilla@arm.com# extra things. 22612572Sgabeblack@google.com# 2272223SN/A######################################################################## 2283573Sgblack@eecs.umich.edu 22912517Srekai.gonzalezalberquilla@arm.comhgdir = main.root.Dir(".hg") 23012572Sgabeblack@google.com 2313576Sgblack@eecs.umich.edumercurial_style_message = """ 2323576Sgblack@eecs.umich.eduYou're missing the gem5 style hook, which automatically checks your code 23312517Srekai.gonzalezalberquilla@arm.comagainst the gem5 style rules on hg commit and qrefresh commands. This 23412572Sgabeblack@google.comscript will now install the hook in your .hg/hgrc file. 2353576Sgblack@eecs.umich.eduPress enter to continue, or ctrl-c to abort: """ 2363576Sgblack@eecs.umich.edu 23712517Srekai.gonzalezalberquilla@arm.commercurial_style_hook = """ 23812572Sgabeblack@google.com# The following lines were automatically added by gem5/SConstruct 2393576Sgblack@eecs.umich.edu# to provide the gem5 style-checking hooks 2403576Sgblack@eecs.umich.edu[extensions] 24112517Srekai.gonzalezalberquilla@arm.comstyle = %s/util/style.py 24212572Sgabeblack@google.com 2433576Sgblack@eecs.umich.edu[hooks] 2443576Sgblack@eecs.umich.edupretxncommit.style = python:style.check_style 24512517Srekai.gonzalezalberquilla@arm.compre-qrefresh.style = python:style.check_style 24612572Sgabeblack@google.com# End of SConstruct additions 2473576Sgblack@eecs.umich.edu 2483576Sgblack@eecs.umich.edu""" % (main.root.abspath) 24912517Srekai.gonzalezalberquilla@arm.com 25012572Sgabeblack@google.commercurial_lib_not_found = """ 2513576Sgblack@eecs.umich.eduMercurial libraries cannot be found, ignoring style hook. If 2523576Sgblack@eecs.umich.eduyou are a gem5 developer, please fix this and run the style 25312517Srekai.gonzalezalberquilla@arm.comhook. It is important. 25412572Sgabeblack@google.com""" 2553576Sgblack@eecs.umich.edu 2563576Sgblack@eecs.umich.edu# Check for style hook and prompt for installation if it's not there. 25712517Srekai.gonzalezalberquilla@arm.com# Skip this if --ignore-style was specified, there's no .hg dir to 25812572Sgabeblack@google.com# install a hook in, or there's no interactive terminal to prompt. 2593576Sgblack@eecs.umich.eduif not GetOption('ignore_style') and hgdir.exists() and sys.stdin.isatty(): 2603576Sgblack@eecs.umich.edu style_hook = True 26112517Srekai.gonzalezalberquilla@arm.com try: 26212572Sgabeblack@google.com from mercurial import ui 2633576Sgblack@eecs.umich.edu ui = ui.ui() 2643576Sgblack@eecs.umich.edu ui.readconfig(hgdir.File('hgrc').abspath) 26512517Srekai.gonzalezalberquilla@arm.com style_hook = ui.config('hooks', 'pretxncommit.style', None) and \ 26612572Sgabeblack@google.com ui.config('hooks', 'pre-qrefresh.style', None) 2673576Sgblack@eecs.umich.edu except ImportError: 2683576Sgblack@eecs.umich.edu print mercurial_lib_not_found 26912517Srekai.gonzalezalberquilla@arm.com 27012572Sgabeblack@google.com if not style_hook: 2713576Sgblack@eecs.umich.edu print mercurial_style_message, 2723576Sgblack@eecs.umich.edu # continue unless user does ctrl-c/ctrl-d etc. 27312517Srekai.gonzalezalberquilla@arm.com try: 27412572Sgabeblack@google.com raw_input() 2752223SN/A except: 2763415Sgblack@eecs.umich.edu print "Input exception, exiting scons.\n" 2773578Sgblack@eecs.umich.edu sys.exit(1) 2783578Sgblack@eecs.umich.edu hgrc_path = '%s/.hg/hgrc' % main.root.abspath 2793415Sgblack@eecs.umich.edu print "Adding style hook to", hgrc_path, "\n" 2803415Sgblack@eecs.umich.edu try: 2817741Sgblack@eecs.umich.edu hgrc = open(hgrc_path, 'a') 2827741Sgblack@eecs.umich.edu hgrc.write(mercurial_style_hook) 2833415Sgblack@eecs.umich.edu hgrc.close() 2843578Sgblack@eecs.umich.edu except: 2853578Sgblack@eecs.umich.edu print "Error updating", hgrc_path 2868829Sgblack@eecs.umich.edu sys.exit(1) 2878829Sgblack@eecs.umich.edu 2888829Sgblack@eecs.umich.edu 2898829Sgblack@eecs.umich.edu################################################### 2907741Sgblack@eecs.umich.edu# 2917741Sgblack@eecs.umich.edu# Figure out which configurations to set up based on the path(s) of 2928829Sgblack@eecs.umich.edu# the target(s). 2938829Sgblack@eecs.umich.edu# 2948829Sgblack@eecs.umich.edu################################################### 2953578Sgblack@eecs.umich.edu 2963578Sgblack@eecs.umich.edu# Find default configuration & binary. 2973578Sgblack@eecs.umich.eduDefault(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA/gem5.debug')) 2983578Sgblack@eecs.umich.edu 2993578Sgblack@eecs.umich.edu# helper function: find last occurrence of element in list 3003578Sgblack@eecs.umich.edudef rfind(l, elt, offs = -1): 3013578Sgblack@eecs.umich.edu for i in range(len(l)+offs, 0, -1): 3027741Sgblack@eecs.umich.edu if l[i] == elt: 3037741Sgblack@eecs.umich.edu return i 3043578Sgblack@eecs.umich.edu raise ValueError, "element not found" 3054172Ssaidi@eecs.umich.edu 3064172Ssaidi@eecs.umich.edu# Take a list of paths (or SCons Nodes) and return a list with all 3078829Sgblack@eecs.umich.edu# paths made absolute and ~-expanded. Paths will be interpreted 3088829Sgblack@eecs.umich.edu# relative to the launch directory unless a different root is provided 3093761Sgblack@eecs.umich.edudef makePathListAbsolute(path_list, root=GetLaunchDir()): 3104172Ssaidi@eecs.umich.edu return [abspath(joinpath(root, expanduser(str(p)))) 3114172Ssaidi@eecs.umich.edu for p in path_list] 3124172Ssaidi@eecs.umich.edu 3134172Ssaidi@eecs.umich.edu# Each target must have 'build' in the interior of the path; the 3147720Sgblack@eecs.umich.edu# directory below this will determine the build parameters. For 3153578Sgblack@eecs.umich.edu# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we 3163578Sgblack@eecs.umich.edu# recognize that ALPHA_SE specifies the configuration because it 3173578Sgblack@eecs.umich.edu# follow 'build' in the build path. 3188829Sgblack@eecs.umich.edu 3193928Ssaidi@eecs.umich.edu# The funky assignment to "[:]" is needed to replace the list contents 3207741Sgblack@eecs.umich.edu# in place rather than reassign the symbol to a new list, which 3213578Sgblack@eecs.umich.edu# doesn't work (obviously!). 3227741Sgblack@eecs.umich.eduBUILD_TARGETS[:] = makePathListAbsolute(BUILD_TARGETS) 3233578Sgblack@eecs.umich.edu 3247741Sgblack@eecs.umich.edu# Generate a list of the unique build roots and configs that the 3253578Sgblack@eecs.umich.edu# collected targets reference. 3267741Sgblack@eecs.umich.eduvariant_paths = [] 3278829Sgblack@eecs.umich.edubuild_root = None 3287741Sgblack@eecs.umich.edufor t in BUILD_TARGETS: 3293578Sgblack@eecs.umich.edu path_dirs = t.split('/') 3303578Sgblack@eecs.umich.edu try: 3317741Sgblack@eecs.umich.edu build_top = rfind(path_dirs, 'build', -2) 3324172Ssaidi@eecs.umich.edu except: 3333578Sgblack@eecs.umich.edu print "Error: no non-leaf 'build' dir found on target path", t 3347741Sgblack@eecs.umich.edu Exit(1) 3357720Sgblack@eecs.umich.edu this_build_root = joinpath('/',*path_dirs[:build_top+1]) 3367741Sgblack@eecs.umich.edu if not build_root: 3377720Sgblack@eecs.umich.edu build_root = this_build_root 3383578Sgblack@eecs.umich.edu else: 3397741Sgblack@eecs.umich.edu if this_build_root != build_root: 3408829Sgblack@eecs.umich.edu print "Error: build targets not under same build root\n"\ 3413578Sgblack@eecs.umich.edu " %s\n %s" % (build_root, this_build_root) 3427741Sgblack@eecs.umich.edu Exit(1) 3434172Ssaidi@eecs.umich.edu variant_path = joinpath('/',*path_dirs[:build_top+2]) 3443578Sgblack@eecs.umich.edu if variant_path not in variant_paths: 3457741Sgblack@eecs.umich.edu variant_paths.append(variant_path) 3464172Ssaidi@eecs.umich.edu 3473578Sgblack@eecs.umich.edu# Make sure build_root exists (might not if this is the first build there) 3488829Sgblack@eecs.umich.eduif not isdir(build_root): 3498829Sgblack@eecs.umich.edu mkdir(build_root) 3508829Sgblack@eecs.umich.edumain['BUILDROOT'] = build_root 3518829Sgblack@eecs.umich.edu 3528829Sgblack@eecs.umich.eduExport('main') 3533578Sgblack@eecs.umich.edu 3548829Sgblack@eecs.umich.edumain.SConsignFile(joinpath(build_root, "sconsign")) 3558829Sgblack@eecs.umich.edu 3568829Sgblack@eecs.umich.edu# Default duplicate option is to use hard links, but this messes up 3578829Sgblack@eecs.umich.edu# when you use emacs to edit a file in the target dir, as emacs moves 3588829Sgblack@eecs.umich.edu# file to file~ then copies to file, breaking the link. Symbolic 3593578Sgblack@eecs.umich.edu# (soft) links work better. 3603578Sgblack@eecs.umich.edumain.SetOption('duplicate', 'soft-copy') 3613893Shsul@eecs.umich.edu 3623415Sgblack@eecs.umich.edu# 3633893Shsul@eecs.umich.edu# Set up global sticky variables... these are common to an entire build 3643415Sgblack@eecs.umich.edu# tree (not specific to a particular build like ALPHA_SE) 3653893Shsul@eecs.umich.edu# 3663415Sgblack@eecs.umich.edu 3673415Sgblack@eecs.umich.eduglobal_vars_file = joinpath(build_root, 'variables.global') 3683415Sgblack@eecs.umich.edu 3693420Sgblack@eecs.umich.eduglobal_vars = Variables(global_vars_file, args=ARGUMENTS) 3707741Sgblack@eecs.umich.edu 3713415Sgblack@eecs.umich.eduglobal_vars.AddVariables( 3724172Ssaidi@eecs.umich.edu ('CC', 'C compiler', environ.get('CC', main['CC'])), 3733415Sgblack@eecs.umich.edu ('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])), 3743415Sgblack@eecs.umich.edu ('SWIG', 'SWIG tool', environ.get('SWIG', main['SWIG'])), 3753415Sgblack@eecs.umich.edu ('PROTOC', 'protoc tool', environ.get('PROTOC', 'protoc')), 3767741Sgblack@eecs.umich.edu ('BATCH', 'Use batch pool for build and tests', False), 3777741Sgblack@eecs.umich.edu ('BATCH_CMD', 'Batch pool submission command name', 'qdo'), 3787741Sgblack@eecs.umich.edu ('M5_BUILD_CACHE', 'Cache built objects in this directory', False), 3797741Sgblack@eecs.umich.edu ('EXTRAS', 'Add extra directories to the compilation', '') 3807741Sgblack@eecs.umich.edu ) 3817741Sgblack@eecs.umich.edu 3827741Sgblack@eecs.umich.edu# Update main environment with values from ARGUMENTS & global_vars_file 3837741Sgblack@eecs.umich.eduglobal_vars.Update(main) 3847741Sgblack@eecs.umich.eduhelp_texts["global_vars"] += global_vars.GenerateHelpText(main) 3857741Sgblack@eecs.umich.edu 3868829Sgblack@eecs.umich.edu# Save sticky variable settings back to current variables file 3878829Sgblack@eecs.umich.eduglobal_vars.Save(global_vars_file, main) 3887741Sgblack@eecs.umich.edu 3897741Sgblack@eecs.umich.edu# Parse EXTRAS variable to build list of all directories where we're 3907741Sgblack@eecs.umich.edu# look for sources etc. This list is exported as extras_dir_list. 3917741Sgblack@eecs.umich.edubase_dir = main.srcdir.abspath 3927741Sgblack@eecs.umich.eduif main['EXTRAS']: 3937741Sgblack@eecs.umich.edu extras_dir_list = makePathListAbsolute(main['EXTRAS'].split(':')) 3947741Sgblack@eecs.umich.eduelse: 3957741Sgblack@eecs.umich.edu extras_dir_list = [] 3967741Sgblack@eecs.umich.edu 3977741Sgblack@eecs.umich.eduExport('base_dir') 3987741Sgblack@eecs.umich.eduExport('extras_dir_list') 3998829Sgblack@eecs.umich.edu 4007741Sgblack@eecs.umich.edu# the ext directory should be on the #includes path 4017741Sgblack@eecs.umich.edumain.Append(CPPPATH=[Dir('ext')]) 4027741Sgblack@eecs.umich.edu 4037741Sgblack@eecs.umich.edudef strip_build_path(path, env): 4047741Sgblack@eecs.umich.edu path = str(path) 4057741Sgblack@eecs.umich.edu variant_base = env['BUILDROOT'] + os.path.sep 4067741Sgblack@eecs.umich.edu if path.startswith(variant_base): 4077741Sgblack@eecs.umich.edu path = path[len(variant_base):] 4087741Sgblack@eecs.umich.edu elif path.startswith('build/'): 4097741Sgblack@eecs.umich.edu path = path[6:] 4108829Sgblack@eecs.umich.edu return path 4117741Sgblack@eecs.umich.edu 4127741Sgblack@eecs.umich.edu# Generate a string of the form: 4137741Sgblack@eecs.umich.edu# common/path/prefix/src1, src2 -> tgt1, tgt2 4147741Sgblack@eecs.umich.edu# to print while building. 4157741Sgblack@eecs.umich.educlass Transform(object): 4167741Sgblack@eecs.umich.edu # all specific color settings should be here and nowhere else 4177741Sgblack@eecs.umich.edu tool_color = termcap.Normal 4187741Sgblack@eecs.umich.edu pfx_color = termcap.Yellow 4197741Sgblack@eecs.umich.edu srcs_color = termcap.Yellow + termcap.Bold 4207741Sgblack@eecs.umich.edu arrow_color = termcap.Blue + termcap.Bold 4217741Sgblack@eecs.umich.edu tgts_color = termcap.Yellow + termcap.Bold 4227741Sgblack@eecs.umich.edu 4238829Sgblack@eecs.umich.edu def __init__(self, tool, max_sources=99): 4247741Sgblack@eecs.umich.edu self.format = self.tool_color + (" [%8s] " % tool) \ 4257741Sgblack@eecs.umich.edu + self.pfx_color + "%s" \ 4267741Sgblack@eecs.umich.edu + self.srcs_color + "%s" \ 4277741Sgblack@eecs.umich.edu + self.arrow_color + " -> " \ 4287741Sgblack@eecs.umich.edu + self.tgts_color + "%s" \ 4297741Sgblack@eecs.umich.edu + termcap.Normal 4307741Sgblack@eecs.umich.edu self.max_sources = max_sources 4317741Sgblack@eecs.umich.edu 4327741Sgblack@eecs.umich.edu def __call__(self, target, source, env, for_signature=None): 4337741Sgblack@eecs.umich.edu # truncate source list according to max_sources param 4348829Sgblack@eecs.umich.edu source = source[0:self.max_sources] 4358829Sgblack@eecs.umich.edu def strip(f): 4368829Sgblack@eecs.umich.edu return strip_build_path(str(f), env) 4378829Sgblack@eecs.umich.edu if len(source) > 0: 4388829Sgblack@eecs.umich.edu srcs = map(strip, source) 4398829Sgblack@eecs.umich.edu else: 4407741Sgblack@eecs.umich.edu srcs = [''] 4417741Sgblack@eecs.umich.edu tgts = map(strip, target) 4428829Sgblack@eecs.umich.edu # surprisingly, os.path.commonprefix is a dumb char-by-char string 4437741Sgblack@eecs.umich.edu # operation that has nothing to do with paths. 4448829Sgblack@eecs.umich.edu com_pfx = os.path.commonprefix(srcs + tgts) 4458829Sgblack@eecs.umich.edu com_pfx_len = len(com_pfx) 4468829Sgblack@eecs.umich.edu if com_pfx: 4478829Sgblack@eecs.umich.edu # do some cleanup and sanity checking on common prefix 4488829Sgblack@eecs.umich.edu if com_pfx[-1] == ".": 4497741Sgblack@eecs.umich.edu # prefix matches all but file extension: ok 4508829Sgblack@eecs.umich.edu # back up one to change 'foo.cc -> o' to 'foo.cc -> .o' 4518829Sgblack@eecs.umich.edu com_pfx = com_pfx[0:-1] 4527741Sgblack@eecs.umich.edu elif com_pfx[-1] == "/": 4538829Sgblack@eecs.umich.edu # common prefix is directory path: OK 4547741Sgblack@eecs.umich.edu pass 4557741Sgblack@eecs.umich.edu else: 4567741Sgblack@eecs.umich.edu src0_len = len(srcs[0]) 4577741Sgblack@eecs.umich.edu tgt0_len = len(tgts[0]) 4587741Sgblack@eecs.umich.edu if src0_len == com_pfx_len: 4597741Sgblack@eecs.umich.edu # source is a substring of target, OK 4607741Sgblack@eecs.umich.edu pass 4617741Sgblack@eecs.umich.edu elif tgt0_len == com_pfx_len: 4627741Sgblack@eecs.umich.edu # target is a substring of source, need to back up to 4637741Sgblack@eecs.umich.edu # avoid empty string on RHS of arrow 4647741Sgblack@eecs.umich.edu sep_idx = com_pfx.rfind(".") 4657741Sgblack@eecs.umich.edu if sep_idx != -1: 4667741Sgblack@eecs.umich.edu com_pfx = com_pfx[0:sep_idx] 4677741Sgblack@eecs.umich.edu else: 4687741Sgblack@eecs.umich.edu com_pfx = '' 4697741Sgblack@eecs.umich.edu elif src0_len > com_pfx_len and srcs[0][com_pfx_len] == ".": 4707741Sgblack@eecs.umich.edu # still splitting at file extension: ok 4717741Sgblack@eecs.umich.edu pass 4727741Sgblack@eecs.umich.edu else: 4737741Sgblack@eecs.umich.edu # probably a fluke; ignore it 4743578Sgblack@eecs.umich.edu com_pfx = '' 4753585Sgblack@eecs.umich.edu # recalculate length in case com_pfx was modified 4763603Ssaidi@eecs.umich.edu com_pfx_len = len(com_pfx) 4773595Sgblack@eecs.umich.edu def fmt(files): 4783578Sgblack@eecs.umich.edu f = map(lambda s: s[com_pfx_len:], files) 4793578Sgblack@eecs.umich.edu return ', '.join(f) 4803578Sgblack@eecs.umich.edu return self.format % (com_pfx, fmt(srcs), fmt(tgts)) 4817741Sgblack@eecs.umich.edu 4827741Sgblack@eecs.umich.eduExport('Transform') 4833578Sgblack@eecs.umich.edu 4844172Ssaidi@eecs.umich.edu# enable the regression script to use the termcap 4853578Sgblack@eecs.umich.edumain['TERMCAP'] = termcap 4863578Sgblack@eecs.umich.edu 4873578Sgblack@eecs.umich.eduif GetOption('verbose'): 4883578Sgblack@eecs.umich.edu def MakeAction(action, string, *args, **kwargs): 4897741Sgblack@eecs.umich.edu return Action(action, *args, **kwargs) 4907741Sgblack@eecs.umich.eduelse: 4913578Sgblack@eecs.umich.edu MakeAction = Action 4924172Ssaidi@eecs.umich.edu main['CCCOMSTR'] = Transform("CC") 4933578Sgblack@eecs.umich.edu main['CXXCOMSTR'] = Transform("CXX") 4943578Sgblack@eecs.umich.edu main['ASCOMSTR'] = Transform("AS") 4953578Sgblack@eecs.umich.edu main['SWIGCOMSTR'] = Transform("SWIG") 4963578Sgblack@eecs.umich.edu main['ARCOMSTR'] = Transform("AR", 0) 4973578Sgblack@eecs.umich.edu main['LINKCOMSTR'] = Transform("LINK", 0) 4983578Sgblack@eecs.umich.edu main['RANLIBCOMSTR'] = Transform("RANLIB", 0) 4997741Sgblack@eecs.umich.edu main['M4COMSTR'] = Transform("M4") 50010417Sandreas.hansson@arm.com main['SHCCCOMSTR'] = Transform("SHCC") 5012221SN/A main['SHCXXCOMSTR'] = Transform("SHCXX") 5022680Sktlim@umich.eduExport('MakeAction') 5038750Sgblack@eecs.umich.edu 5048750Sgblack@eecs.umich.edu# Initialize the Link-Time Optimization (LTO) flags 5058750Sgblack@eecs.umich.edumain['LTO_CCFLAGS'] = [] 5062223SN/Amain['LTO_LDFLAGS'] = [] 5072221SN/A 5087741Sgblack@eecs.umich.edu# According to the readme, tcmalloc works best if the compiler doesn't 5097741Sgblack@eecs.umich.edu# assume that we're using the builtin malloc and friends. These flags 5104172Ssaidi@eecs.umich.edu# are compiler-specific, so we need to set them after we detect which 5114172Ssaidi@eecs.umich.edu# compiler we're using. 5128829Sgblack@eecs.umich.edumain['TCMALLOC_CCFLAGS'] = [] 5138829Sgblack@eecs.umich.edu 5143578Sgblack@eecs.umich.eduCXX_version = readCommand([main['CXX'],'--version'], exception=False) 5153578Sgblack@eecs.umich.eduCXX_V = readCommand([main['CXX'],'-V'], exception=False) 5163578Sgblack@eecs.umich.edu 5173578Sgblack@eecs.umich.edumain['GCC'] = CXX_version and CXX_version.find('g++') >= 0 5188829Sgblack@eecs.umich.edumain['CLANG'] = CXX_version and CXX_version.find('clang') >= 0 5193746Sgblack@eecs.umich.eduif main['GCC'] + main['CLANG'] > 1: 5208829Sgblack@eecs.umich.edu print 'Error: How can we have two at the same time?' 5213578Sgblack@eecs.umich.edu Exit(1) 5223578Sgblack@eecs.umich.edu 5233746Sgblack@eecs.umich.edu# Set up default C++ compiler flags 5243578Sgblack@eecs.umich.eduif main['GCC'] or main['CLANG']: 5253578Sgblack@eecs.umich.edu # As gcc and clang share many flags, do the common parts here 5263578Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-pipe']) 5278829Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-fno-strict-aliasing']) 5283595Sgblack@eecs.umich.edu # Enable -Wall and then disable the few warnings that we 5293893Shsul@eecs.umich.edu # consistently violate 5307741Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef']) 5317741Sgblack@eecs.umich.edu # We always compile using C++11, but only gcc >= 4.7 and clang 3.1 5323578Sgblack@eecs.umich.edu # actually use that name, so we stick with c++0x 5333893Shsul@eecs.umich.edu main.Append(CXXFLAGS=['-std=c++0x']) 5343825Ssaidi@eecs.umich.edu # Add selected sanity checks from -Wextra 5357741Sgblack@eecs.umich.edu main.Append(CXXFLAGS=['-Wmissing-field-initializers', 5367741Sgblack@eecs.umich.edu '-Woverloaded-virtual']) 5377741Sgblack@eecs.umich.eduelse: 5383893Shsul@eecs.umich.edu print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal, 5397741Sgblack@eecs.umich.edu print "Don't know what compiler options to use for your compiler." 5403578Sgblack@eecs.umich.edu print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX'] 5413585Sgblack@eecs.umich.edu print termcap.Yellow + ' version:' + termcap.Normal, 5423893Shsul@eecs.umich.edu if not CXX_version: 5435570Snate@binkert.org print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\ 5443578Sgblack@eecs.umich.edu termcap.Normal 5453585Sgblack@eecs.umich.edu else: 5463826Ssaidi@eecs.umich.edu print CXX_version.replace('\n', '<nl>') 5473578Sgblack@eecs.umich.edu print " If you're trying to use a compiler other than GCC" 5487741Sgblack@eecs.umich.edu print " or clang, there appears to be something wrong with your" 5493578Sgblack@eecs.umich.edu print " environment." 5503578Sgblack@eecs.umich.edu print " " 5517720Sgblack@eecs.umich.edu print " If you are trying to use a compiler other than those listed" 5527720Sgblack@eecs.umich.edu print " above you will need to ease fix SConstruct and " 5537720Sgblack@eecs.umich.edu print " src/SConscript to support that compiler." 5547720Sgblack@eecs.umich.edu Exit(1) 5557720Sgblack@eecs.umich.edu 5567720Sgblack@eecs.umich.eduif main['GCC']: 5577720Sgblack@eecs.umich.edu # Check for a supported version of gcc, >= 4.4 is needed for c++0x 5583420Sgblack@eecs.umich.edu # support. See http://gcc.gnu.org/projects/cxx0x.html for details 5592221SN/A gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False) 5607741Sgblack@eecs.umich.edu if compareVersions(gcc_version, "4.4") < 0: 56110417Sandreas.hansson@arm.com print 'Error: gcc version 4.4 or newer required.' 5623523Sgblack@eecs.umich.edu print ' Installed version:', gcc_version 5637741Sgblack@eecs.umich.edu Exit(1) 5647741Sgblack@eecs.umich.edu 5657741Sgblack@eecs.umich.edu main['GCC_VERSION'] = gcc_version 5663595Sgblack@eecs.umich.edu 5674172Ssaidi@eecs.umich.edu # Check for versions with bugs 5684172Ssaidi@eecs.umich.edu if not compareVersions(gcc_version, '4.4.1') or \ 5694172Ssaidi@eecs.umich.edu not compareVersions(gcc_version, '4.4.2'): 5703595Sgblack@eecs.umich.edu print 'Info: Tree vectorizer in GCC 4.4.1 & 4.4.2 is buggy, disabling.' 5718829Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-fno-tree-vectorize']) 5728829Sgblack@eecs.umich.edu 5738829Sgblack@eecs.umich.edu # LTO support is only really working properly from 4.6 and beyond 5748829Sgblack@eecs.umich.edu if compareVersions(gcc_version, '4.6') >= 0: 5753595Sgblack@eecs.umich.edu # Add the appropriate Link-Time Optimization (LTO) flags 5767741Sgblack@eecs.umich.edu # unless LTO is explicitly turned off. Note that these flags 5778829Sgblack@eecs.umich.edu # are only used by the fast target. 5788829Sgblack@eecs.umich.edu if not GetOption('no_lto'): 5798829Sgblack@eecs.umich.edu # Pass the LTO flag when compiling to produce GIMPLE 5808829Sgblack@eecs.umich.edu # output, we merely create the flags here and only append 5818829Sgblack@eecs.umich.edu # them later/ 5828829Sgblack@eecs.umich.edu main['LTO_CCFLAGS'] = ['-flto=%d' % GetOption('num_jobs')] 5833595Sgblack@eecs.umich.edu 5847741Sgblack@eecs.umich.edu # Use the same amount of jobs for LTO as we are running 5854172Ssaidi@eecs.umich.edu # scons with, we hardcode the use of the linker plugin 5863595Sgblack@eecs.umich.edu # which requires either gold or GNU ld >= 2.21 5877741Sgblack@eecs.umich.edu main['LTO_LDFLAGS'] = ['-flto=%d' % GetOption('num_jobs'), 5887741Sgblack@eecs.umich.edu '-fuse-linker-plugin'] 5893746Sgblack@eecs.umich.edu 5903746Sgblack@eecs.umich.edu main.Append(TCMALLOC_CCFLAGS=['-fno-builtin-malloc', '-fno-builtin-calloc', 5913595Sgblack@eecs.umich.edu '-fno-builtin-realloc', '-fno-builtin-free']) 5923595Sgblack@eecs.umich.edu 5937720Sgblack@eecs.umich.eduelif main['CLANG']: 5947720Sgblack@eecs.umich.edu # Check for a supported version of clang, >= 2.9 is needed to 5957720Sgblack@eecs.umich.edu # support similar features as gcc 4.4. See 5967720Sgblack@eecs.umich.edu # http://clang.llvm.org/cxx_status.html for details 5977720Sgblack@eecs.umich.edu clang_version_re = re.compile(".* version (\d+\.\d+)") 5987720Sgblack@eecs.umich.edu clang_version_match = clang_version_re.match(CXX_version) 5997720Sgblack@eecs.umich.edu if (clang_version_match): 6007720Sgblack@eecs.umich.edu clang_version = clang_version_match.groups()[0] 6013595Sgblack@eecs.umich.edu if compareVersions(clang_version, "2.9") < 0: 6027741Sgblack@eecs.umich.edu print 'Error: clang version 2.9 or newer required.' 6037741Sgblack@eecs.umich.edu print ' Installed version:', clang_version 6043523Sgblack@eecs.umich.edu Exit(1) 6053595Sgblack@eecs.umich.edu else: 6063595Sgblack@eecs.umich.edu print 'Error: Unable to determine clang version.' 6073595Sgblack@eecs.umich.edu Exit(1) 6084172Ssaidi@eecs.umich.edu 6093595Sgblack@eecs.umich.edu # clang has a few additional warnings that we disable, 6103523Sgblack@eecs.umich.edu # tautological comparisons are allowed due to unsigned integers 6117741Sgblack@eecs.umich.edu # being compared to constants that happen to be 0, and extraneous 6123523Sgblack@eecs.umich.edu # parantheses are allowed due to Ruby's printing of the AST, 6133523Sgblack@eecs.umich.edu # finally self assignments are allowed as the generated CPU code 6143523Sgblack@eecs.umich.edu # is relying on this 6153523Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-Wno-tautological-compare', 6163523Sgblack@eecs.umich.edu '-Wno-parentheses', 6173523Sgblack@eecs.umich.edu '-Wno-self-assign']) 6183523Sgblack@eecs.umich.edu 6193523Sgblack@eecs.umich.edu main.Append(TCMALLOC_CCFLAGS=['-fno-builtin']) 6203523Sgblack@eecs.umich.edu 6212221SN/A # On Mac OS X/Darwin we need to also use libc++ (part of XCode) as 6222221SN/A # opposed to libstdc++ to make the transition from TR1 to 6237741Sgblack@eecs.umich.edu # C++11. See http://libcxx.llvm.org. However, clang has chosen a 62410417Sandreas.hansson@arm.com # strict implementation of the C++11 standard, and does not allow 62510417Sandreas.hansson@arm.com # incomplete types in template arguments (besides unique_ptr and 6264997Sgblack@eecs.umich.edu # shared_ptr), and the libc++ STL containers create problems in 6278767Sgblack@eecs.umich.edu # combination with the current gem5 code. For now, we stick with 6288767Sgblack@eecs.umich.edu # libstdc++ and use the TR1 namespace. 6298806Sgblack@eecs.umich.edu # if sys.platform == "darwin": 6308806Sgblack@eecs.umich.edu # main.Append(CXXFLAGS=['-stdlib=libc++']) 6318806Sgblack@eecs.umich.edu 6328806Sgblack@eecs.umich.eduelse: 63312461Sgabeblack@google.com print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal, 63412461Sgabeblack@google.com print "Don't know what compiler options to use for your compiler." 63511850Sbrandon.potter@amd.com print termcap.Yellow + ' compiler:' + termcap.Normal, main['CXX'] 63612455Sgabeblack@google.com print termcap.Yellow + ' version:' + termcap.Normal, 63711850Sbrandon.potter@amd.com if not CXX_version: 63812455Sgabeblack@google.com print termcap.Yellow + termcap.Bold + "COMMAND NOT FOUND!" +\ 63912455Sgabeblack@google.com termcap.Normal 64012455Sgabeblack@google.com else: 64111850Sbrandon.potter@amd.com print CXX_version.replace('\n', '<nl>') 64212455Sgabeblack@google.com print " If you're trying to use a compiler other than GCC" 64312455Sgabeblack@google.com print " or clang, there appears to be something wrong with your" 64412455Sgabeblack@google.com print " environment." 64512455Sgabeblack@google.com print " " 64612455Sgabeblack@google.com print " If you are trying to use a compiler other than those listed" 64712455Sgabeblack@google.com print " above you will need to ease fix SConstruct and " 64811850Sbrandon.potter@amd.com print " src/SConscript to support that compiler." 64912455Sgabeblack@google.com Exit(1) 65012455Sgabeblack@google.com 65112455Sgabeblack@google.com# Set up common yacc/bison flags (needed for Ruby) 65211850Sbrandon.potter@amd.commain['YACCFLAGS'] = '-d' 65312455Sgabeblack@google.commain['YACCHXXFILESUFFIX'] = '.hh' 65412455Sgabeblack@google.com 65512455Sgabeblack@google.com# Do this after we save setting back, or else we'll tack on an 65612455Sgabeblack@google.com# extra 'qdo' every time we run scons. 65712455Sgabeblack@google.comif main['BATCH']: 65811850Sbrandon.potter@amd.com main['CC'] = main['BATCH_CMD'] + ' ' + main['CC'] 65912455Sgabeblack@google.com main['CXX'] = main['BATCH_CMD'] + ' ' + main['CXX'] 66012455Sgabeblack@google.com main['AS'] = main['BATCH_CMD'] + ' ' + main['AS'] 66111850Sbrandon.potter@amd.com main['AR'] = main['BATCH_CMD'] + ' ' + main['AR'] 66212455Sgabeblack@google.com main['RANLIB'] = main['BATCH_CMD'] + ' ' + main['RANLIB'] 66312455Sgabeblack@google.com 66412455Sgabeblack@google.comif sys.platform == 'cygwin': 66512455Sgabeblack@google.com # cygwin has some header file issues... 66612461Sgabeblack@google.com main.Append(CCFLAGS=["-Wno-uninitialized"]) 66712461Sgabeblack@google.com 66812461Sgabeblack@google.com# Check for the protobuf compiler 66912461Sgabeblack@google.comprotoc_version = readCommand([main['PROTOC'], '--version'], 67012455Sgabeblack@google.com exception='').split() 67112455Sgabeblack@google.com 67212455Sgabeblack@google.com# First two words should be "libprotoc x.y.z" 67312455Sgabeblack@google.comif len(protoc_version) < 2 or protoc_version[0] != 'libprotoc': 67412455Sgabeblack@google.com print termcap.Yellow + termcap.Bold + \ 67512455Sgabeblack@google.com 'Warning: Protocol buffer compiler (protoc) not found.\n' + \ 67612461Sgabeblack@google.com ' Please install protobuf-compiler for tracing support.' + \ 6774997Sgblack@eecs.umich.edu termcap.Normal 6784997Sgblack@eecs.umich.edu main['PROTOC'] = False 6797741Sgblack@eecs.umich.eduelse: 68010417Sandreas.hansson@arm.com # Based on the availability of the compress stream wrappers, 6814997Sgblack@eecs.umich.edu # require 2.1.0 6828767Sgblack@eecs.umich.edu min_protoc_version = '2.1.0' 6838767Sgblack@eecs.umich.edu if compareVersions(protoc_version[1], min_protoc_version) < 0: 6848806Sgblack@eecs.umich.edu print termcap.Yellow + termcap.Bold + \ 6858806Sgblack@eecs.umich.edu 'Warning: protoc version', min_protoc_version, \ 6868806Sgblack@eecs.umich.edu 'or newer required.\n' + \ 6878806Sgblack@eecs.umich.edu ' Installed version:', protoc_version[1], \ 68812461Sgabeblack@google.com termcap.Normal 68912461Sgabeblack@google.com main['PROTOC'] = False 69012461Sgabeblack@google.com else: 69112461Sgabeblack@google.com # Attempt to determine the appropriate include path and 69211850Sbrandon.potter@amd.com # library path using pkg-config, that means we also need to 69312455Sgabeblack@google.com # check for pkg-config. Note that it is possible to use 69411850Sbrandon.potter@amd.com # protobuf without the involvement of pkg-config. Later on we 69512455Sgabeblack@google.com # check go a library config check and at that point the test 69612455Sgabeblack@google.com # will fail if libprotobuf cannot be found. 69712455Sgabeblack@google.com if readCommand(['pkg-config', '--version'], exception=''): 69811850Sbrandon.potter@amd.com try: 69912455Sgabeblack@google.com # Attempt to establish what linking flags to add for protobuf 70012455Sgabeblack@google.com # using pkg-config 70112455Sgabeblack@google.com main.ParseConfig('pkg-config --cflags --libs-only-L protobuf') 70212455Sgabeblack@google.com except: 70312455Sgabeblack@google.com print termcap.Yellow + termcap.Bold + \ 70412455Sgabeblack@google.com 'Warning: pkg-config could not get protobuf flags.' + \ 70512455Sgabeblack@google.com termcap.Normal 70612455Sgabeblack@google.com 70712455Sgabeblack@google.com# Check for SWIG 70811850Sbrandon.potter@amd.comif not main.has_key('SWIG'): 70912455Sgabeblack@google.com print 'Error: SWIG utility not found.' 71012455Sgabeblack@google.com print ' Please install (see http://www.swig.org) and retry.' 71112455Sgabeblack@google.com Exit(1) 71212455Sgabeblack@google.com 71311850Sbrandon.potter@amd.com# Check for appropriate SWIG version 71412455Sgabeblack@google.comswig_version = readCommand([main['SWIG'], '-version'], exception='').split() 71512455Sgabeblack@google.com# First 3 words should be "SWIG Version x.y.z" 71612455Sgabeblack@google.comif len(swig_version) < 3 or \ 71711850Sbrandon.potter@amd.com swig_version[0] != 'SWIG' or swig_version[1] != 'Version': 71812455Sgabeblack@google.com print 'Error determining SWIG version.' 71912455Sgabeblack@google.com Exit(1) 72012455Sgabeblack@google.com 72112455Sgabeblack@google.commin_swig_version = '1.3.34' 72212455Sgabeblack@google.comif compareVersions(swig_version[2], min_swig_version) < 0: 72312455Sgabeblack@google.com print 'Error: SWIG version', min_swig_version, 'or newer required.' 72411850Sbrandon.potter@amd.com print ' Installed version:', swig_version[2] 72512455Sgabeblack@google.com Exit(1) 72612455Sgabeblack@google.com 72712455Sgabeblack@google.comif swig_version[2] == "2.0.9": 72812455Sgabeblack@google.com print '\n' + termcap.Yellow + termcap.Bold + \ 72912455Sgabeblack@google.com 'Warning: SWIG version 2.0.9 sometimes generates broken code.\n' + \ 73012455Sgabeblack@google.com termcap.Normal + \ 73112455Sgabeblack@google.com 'This problem only affects some platforms and some Python\n' + \ 73212455Sgabeblack@google.com 'versions. See the following SWIG bug report for details:\n' + \ 73312455Sgabeblack@google.com 'http://sourceforge.net/p/swig/bugs/1297/\n' 73412455Sgabeblack@google.com 73512455Sgabeblack@google.com 73611850Sbrandon.potter@amd.com# Set up SWIG flags & scanner 73712455Sgabeblack@google.comswig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS') 73812455Sgabeblack@google.commain.Append(SWIGFLAGS=swig_flags) 73912455Sgabeblack@google.com 74012455Sgabeblack@google.com# filter out all existing swig scanners, they mess up the dependency 74112455Sgabeblack@google.com# stuff for some reason 74211850Sbrandon.potter@amd.comscanners = [] 74312455Sgabeblack@google.comfor scanner in main['SCANNERS']: 74412455Sgabeblack@google.com skeys = scanner.skeys 74512455Sgabeblack@google.com if skeys == '.i': 74612455Sgabeblack@google.com continue 74712455Sgabeblack@google.com 74812455Sgabeblack@google.com if isinstance(skeys, (list, tuple)) and '.i' in skeys: 74911850Sbrandon.potter@amd.com continue 75012455Sgabeblack@google.com 75112455Sgabeblack@google.com scanners.append(scanner) 75212455Sgabeblack@google.com 75312461Sgabeblack@google.com# add the new swig scanner that we like better 75412461Sgabeblack@google.comfrom SCons.Scanner import ClassicCPP as CPPScanner 75512461Sgabeblack@google.comswig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")' 75612461Sgabeblack@google.comscanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re)) 75712455Sgabeblack@google.com 75812455Sgabeblack@google.com# replace the scanners list that has what we want 75912455Sgabeblack@google.commain['SCANNERS'] = scanners 76012455Sgabeblack@google.com 76112455Sgabeblack@google.com# Add a custom Check function to the Configure context so that we can 76212455Sgabeblack@google.com# figure out if the compiler adds leading underscores to global 76312461Sgabeblack@google.com# variables. This is needed for the autogenerated asm files that we 7644997Sgblack@eecs.umich.edu# use for embedding the python code. 7654997Sgblack@eecs.umich.edudef CheckLeading(context): 7667741Sgblack@eecs.umich.edu context.Message("Checking for leading underscore in global variables...") 76710417Sandreas.hansson@arm.com # 1) Define a global variable called x from asm so the C compiler 7683415Sgblack@eecs.umich.edu # won't change the symbol at all. 7698778Sgblack@eecs.umich.edu # 2) Declare that variable. 7708778Sgblack@eecs.umich.edu # 3) Use the variable 7718806Sgblack@eecs.umich.edu # 7728806Sgblack@eecs.umich.edu # If the compiler prepends an underscore, this will successfully 7733415Sgblack@eecs.umich.edu # link because the external symbol 'x' will be called '_x' which 7748806Sgblack@eecs.umich.edu # was defined by the asm statement. If the compiler does not 7753415Sgblack@eecs.umich.edu # prepend an underscore, this will not successfully link because 7768806Sgblack@eecs.umich.edu # '_x' will have been defined by assembly, while the C portion of 7773415Sgblack@eecs.umich.edu # the code will be trying to use 'x' 77811851Sbrandon.potter@amd.com ret = context.TryLink(''' 77911851Sbrandon.potter@amd.com asm(".globl _x; _x: .byte 0"); 7808806Sgblack@eecs.umich.edu extern int x; 7818806Sgblack@eecs.umich.edu int main() { return x; } 78211851Sbrandon.potter@amd.com ''', extension=".c") 7833415Sgblack@eecs.umich.edu context.env.Append(LEADING_UNDERSCORE=ret) 7843415Sgblack@eecs.umich.edu context.Result(ret) 7857741Sgblack@eecs.umich.edu return ret 78610417Sandreas.hansson@arm.com 7873415Sgblack@eecs.umich.edu# Platform-specific configuration. Note again that we assume that all 7888778Sgblack@eecs.umich.edu# builds under a given build root run on the same host platform. 7898778Sgblack@eecs.umich.educonf = Configure(main, 7908806Sgblack@eecs.umich.edu conf_dir = joinpath(build_root, '.scons_config'), 7918806Sgblack@eecs.umich.edu log_file = joinpath(build_root, 'scons_config.log'), 7923415Sgblack@eecs.umich.edu custom_tests = { 'CheckLeading' : CheckLeading }) 7938806Sgblack@eecs.umich.edu 7943415Sgblack@eecs.umich.edu# Check for leading underscores. Don't really need to worry either 7958806Sgblack@eecs.umich.edu# way so don't need to check the return code. 7963415Sgblack@eecs.umich.educonf.CheckLeading() 79711851Sbrandon.potter@amd.com 79811851Sbrandon.potter@amd.com# Check if we should compile a 64 bit binary on Mac OS X/Darwin 7998806Sgblack@eecs.umich.edutry: 8008806Sgblack@eecs.umich.edu import platform 80111851Sbrandon.potter@amd.com uname = platform.uname() 8023415Sgblack@eecs.umich.edu if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: 8033415Sgblack@eecs.umich.edu if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): 8047741Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-arch', 'x86_64']) 80510417Sandreas.hansson@arm.com main.Append(CFLAGS=['-arch', 'x86_64']) 8064111Sgblack@eecs.umich.edu main.Append(LINKFLAGS=['-arch', 'x86_64']) 8078778Sgblack@eecs.umich.edu main.Append(ASFLAGS=['-arch', 'x86_64']) 8088778Sgblack@eecs.umich.eduexcept: 8098806Sgblack@eecs.umich.edu pass 8108806Sgblack@eecs.umich.edu 8114111Sgblack@eecs.umich.edu# Recent versions of scons substitute a "Null" object for Configure() 8128806Sgblack@eecs.umich.edu# when configuration isn't necessary, e.g., if the "--help" option is 8138806Sgblack@eecs.umich.edu# present. Unfortuantely this Null object always returns false, 8148806Sgblack@eecs.umich.edu# breaking all our configuration checks. We replace it with our own 8154111Sgblack@eecs.umich.edu# more optimistic null object that returns True instead. 8168806Sgblack@eecs.umich.eduif not conf: 8174111Sgblack@eecs.umich.edu def NullCheck(*args, **kwargs): 81811851Sbrandon.potter@amd.com return True 81911851Sbrandon.potter@amd.com 8204111Sgblack@eecs.umich.edu class NullConf: 82111877Sbrandon.potter@amd.com def __init__(self, env): 82211877Sbrandon.potter@amd.com self.env = env 8238806Sgblack@eecs.umich.edu def Finish(self): 8248806Sgblack@eecs.umich.edu return self.env 8258806Sgblack@eecs.umich.edu def __getattr__(self, mname): 8268806Sgblack@eecs.umich.edu return NullCheck 8278806Sgblack@eecs.umich.edu 8288806Sgblack@eecs.umich.edu conf = NullConf(main) 8294111Sgblack@eecs.umich.edu 8304111Sgblack@eecs.umich.edu# Find Python include and library directories for embedding the 8312223SN/A# interpreter. For consistency, we will use the same Python 8322221SN/A# installation used to run scons (and thus this script). If you want 833# to link in an alternate version, see above for instructions on how 834# to invoke scons with a different copy of the Python interpreter. 835from distutils import sysconfig 836 837py_getvar = sysconfig.get_config_var 838 839py_debug = getattr(sys, 'pydebug', False) 840py_version = 'python' + py_getvar('VERSION') + (py_debug and "_d" or "") 841 842py_general_include = sysconfig.get_python_inc() 843py_platform_include = sysconfig.get_python_inc(plat_specific=True) 844py_includes = [ py_general_include ] 845if py_platform_include != py_general_include: 846 py_includes.append(py_platform_include) 847 848py_lib_path = [ py_getvar('LIBDIR') ] 849# add the prefix/lib/pythonX.Y/config dir, but only if there is no 850# shared library in prefix/lib/. 851if not py_getvar('Py_ENABLE_SHARED'): 852 py_lib_path.append(py_getvar('LIBPL')) 853 # Python requires the flags in LINKFORSHARED to be added the 854 # linker flags when linking with a statically with Python. Failing 855 # to do so can lead to errors from the Python's dynamic module 856 # loader at start up. 857 main.Append(LINKFLAGS=[py_getvar('LINKFORSHARED').split()]) 858 859py_libs = [] 860for lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split(): 861 if not lib.startswith('-l'): 862 # Python requires some special flags to link (e.g. -framework 863 # common on OS X systems), assume appending preserves order 864 main.Append(LINKFLAGS=[lib]) 865 else: 866 lib = lib[2:] 867 if lib not in py_libs: 868 py_libs.append(lib) 869py_libs.append(py_version) 870 871main.Append(CPPPATH=py_includes) 872main.Append(LIBPATH=py_lib_path) 873 874# Cache build files in the supplied directory. 875if main['M5_BUILD_CACHE']: 876 print 'Using build cache located at', main['M5_BUILD_CACHE'] 877 CacheDir(main['M5_BUILD_CACHE']) 878 879 880# verify that this stuff works 881if not conf.CheckHeader('Python.h', '<>'): 882 print "Error: can't find Python.h header in", py_includes 883 print "Install Python headers (package python-dev on Ubuntu and RedHat)" 884 Exit(1) 885 886for lib in py_libs: 887 if not conf.CheckLib(lib): 888 print "Error: can't find library %s required by python" % lib 889 Exit(1) 890 891# On Solaris you need to use libsocket for socket ops 892if not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): 893 if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): 894 print "Can't find library with socket calls (e.g. accept())" 895 Exit(1) 896 897# Check for zlib. If the check passes, libz will be automatically 898# added to the LIBS environment variable. 899if not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'): 900 print 'Error: did not find needed zlib compression library '\ 901 'and/or zlib.h header file.' 902 print ' Please install zlib and try again.' 903 Exit(1) 904 905# If we have the protobuf compiler, also make sure we have the 906# development libraries. If the check passes, libprotobuf will be 907# automatically added to the LIBS environment variable. After 908# this, we can use the HAVE_PROTOBUF flag to determine if we have 909# got both protoc and libprotobuf available. 910main['HAVE_PROTOBUF'] = main['PROTOC'] and \ 911 conf.CheckLibWithHeader('protobuf', 'google/protobuf/message.h', 912 'C++', 'GOOGLE_PROTOBUF_VERIFY_VERSION;') 913 914# If we have the compiler but not the library, print another warning. 915if main['PROTOC'] and not main['HAVE_PROTOBUF']: 916 print termcap.Yellow + termcap.Bold + \ 917 'Warning: did not find protocol buffer library and/or headers.\n' + \ 918 ' Please install libprotobuf-dev for tracing support.' + \ 919 termcap.Normal 920 921# Check for librt. 922have_posix_clock = \ 923 conf.CheckLibWithHeader(None, 'time.h', 'C', 924 'clock_nanosleep(0,0,NULL,NULL);') or \ 925 conf.CheckLibWithHeader('rt', 'time.h', 'C', 926 'clock_nanosleep(0,0,NULL,NULL);') 927 928if conf.CheckLib('tcmalloc'): 929 main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS']) 930elif conf.CheckLib('tcmalloc_minimal'): 931 main.Append(CCFLAGS=main['TCMALLOC_CCFLAGS']) 932else: 933 print termcap.Yellow + termcap.Bold + \ 934 "You can get a 12% performance improvement by installing tcmalloc "\ 935 "(libgoogle-perftools-dev package on Ubuntu or RedHat)." + \ 936 termcap.Normal 937 938if not have_posix_clock: 939 print "Can't find library for POSIX clocks." 940 941# Check for <fenv.h> (C99 FP environment control) 942have_fenv = conf.CheckHeader('fenv.h', '<>') 943if not have_fenv: 944 print "Warning: Header file <fenv.h> not found." 945 print " This host has no IEEE FP rounding mode control." 946 947###################################################################### 948# 949# Finish the configuration 950# 951main = conf.Finish() 952 953###################################################################### 954# 955# Collect all non-global variables 956# 957 958# Define the universe of supported ISAs 959all_isa_list = [ ] 960Export('all_isa_list') 961 962class CpuModel(object): 963 '''The CpuModel class encapsulates everything the ISA parser needs to 964 know about a particular CPU model.''' 965 966 # Dict of available CPU model objects. Accessible as CpuModel.dict. 967 dict = {} 968 list = [] 969 defaults = [] 970 971 # Constructor. Automatically adds models to CpuModel.dict. 972 def __init__(self, name, filename, includes, strings, default=False): 973 self.name = name # name of model 974 self.filename = filename # filename for output exec code 975 self.includes = includes # include files needed in exec file 976 # The 'strings' dict holds all the per-CPU symbols we can 977 # substitute into templates etc. 978 self.strings = strings 979 980 # This cpu is enabled by default 981 self.default = default 982 983 # Add self to dict 984 if name in CpuModel.dict: 985 raise AttributeError, "CpuModel '%s' already registered" % name 986 CpuModel.dict[name] = self 987 CpuModel.list.append(name) 988 989Export('CpuModel') 990 991# Sticky variables get saved in the variables file so they persist from 992# one invocation to the next (unless overridden, in which case the new 993# value becomes sticky). 994sticky_vars = Variables(args=ARGUMENTS) 995Export('sticky_vars') 996 997# Sticky variables that should be exported 998export_vars = [] 999Export('export_vars') 1000 1001# For Ruby 1002all_protocols = [] 1003Export('all_protocols') 1004protocol_dirs = [] 1005Export('protocol_dirs') 1006slicc_includes = [] 1007Export('slicc_includes') 1008 1009# Walk the tree and execute all SConsopts scripts that wil add to the 1010# above variables 1011if not GetOption('verbose'): 1012 print "Reading SConsopts" 1013for bdir in [ base_dir ] + extras_dir_list: 1014 if not isdir(bdir): 1015 print "Error: directory '%s' does not exist" % bdir 1016 Exit(1) 1017 for root, dirs, files in os.walk(bdir): 1018 if 'SConsopts' in files: 1019 if GetOption('verbose'): 1020 print "Reading", joinpath(root, 'SConsopts') 1021 SConscript(joinpath(root, 'SConsopts')) 1022 1023all_isa_list.sort() 1024 1025sticky_vars.AddVariables( 1026 EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), 1027 ListVariable('CPU_MODELS', 'CPU models', 1028 sorted(n for n,m in CpuModel.dict.iteritems() if m.default), 1029 sorted(CpuModel.list)), 1030 BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger', 1031 False), 1032 BoolVariable('SS_COMPATIBLE_FP', 1033 'Make floating-point results compatible with SimpleScalar', 1034 False), 1035 BoolVariable('USE_SSE2', 1036 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', 1037 False), 1038 BoolVariable('USE_POSIX_CLOCK', 'Use POSIX Clocks', have_posix_clock), 1039 BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), 1040 BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), 1041 EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None', 1042 all_protocols), 1043 ) 1044 1045# These variables get exported to #defines in config/*.hh (see src/SConscript). 1046export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'CP_ANNOTATE', 1047 'USE_POSIX_CLOCK', 'PROTOCOL', 'HAVE_PROTOBUF'] 1048 1049################################################### 1050# 1051# Define a SCons builder for configuration flag headers. 1052# 1053################################################### 1054 1055# This function generates a config header file that #defines the 1056# variable symbol to the current variable setting (0 or 1). The source 1057# operands are the name of the variable and a Value node containing the 1058# value of the variable. 1059def build_config_file(target, source, env): 1060 (variable, value) = [s.get_contents() for s in source] 1061 f = file(str(target[0]), 'w') 1062 print >> f, '#define', variable, value 1063 f.close() 1064 return None 1065 1066# Combine the two functions into a scons Action object. 1067config_action = MakeAction(build_config_file, Transform("CONFIG H", 2)) 1068 1069# The emitter munges the source & target node lists to reflect what 1070# we're really doing. 1071def config_emitter(target, source, env): 1072 # extract variable name from Builder arg 1073 variable = str(target[0]) 1074 # True target is config header file 1075 target = joinpath('config', variable.lower() + '.hh') 1076 val = env[variable] 1077 if isinstance(val, bool): 1078 # Force value to 0/1 1079 val = int(val) 1080 elif isinstance(val, str): 1081 val = '"' + val + '"' 1082 1083 # Sources are variable name & value (packaged in SCons Value nodes) 1084 return ([target], [Value(variable), Value(val)]) 1085 1086config_builder = Builder(emitter = config_emitter, action = config_action) 1087 1088main.Append(BUILDERS = { 'ConfigFile' : config_builder }) 1089 1090# libelf build is shared across all configs in the build root. 1091main.SConscript('ext/libelf/SConscript', 1092 variant_dir = joinpath(build_root, 'libelf')) 1093 1094# gzstream build is shared across all configs in the build root. 1095main.SConscript('ext/gzstream/SConscript', 1096 variant_dir = joinpath(build_root, 'gzstream')) 1097 1098# libfdt build is shared across all configs in the build root. 1099main.SConscript('ext/libfdt/SConscript', 1100 variant_dir = joinpath(build_root, 'libfdt')) 1101 1102################################################### 1103# 1104# This function is used to set up a directory with switching headers 1105# 1106################################################### 1107 1108main['ALL_ISA_LIST'] = all_isa_list 1109def make_switching_dir(dname, switch_headers, env): 1110 # Generate the header. target[0] is the full path of the output 1111 # header to generate. 'source' is a dummy variable, since we get the 1112 # list of ISAs from env['ALL_ISA_LIST']. 1113 def gen_switch_hdr(target, source, env): 1114 fname = str(target[0]) 1115 f = open(fname, 'w') 1116 isa = env['TARGET_ISA'].lower() 1117 print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 1118 f.close() 1119 1120 # Build SCons Action object. 'varlist' specifies env vars that this 1121 # action depends on; when env['ALL_ISA_LIST'] changes these actions 1122 # should get re-executed. 1123 switch_hdr_action = MakeAction(gen_switch_hdr, 1124 Transform("GENERATE"), varlist=['ALL_ISA_LIST']) 1125 1126 # Instantiate actions for each header 1127 for hdr in switch_headers: 1128 env.Command(hdr, [], switch_hdr_action) 1129Export('make_switching_dir') 1130 1131################################################### 1132# 1133# Define build environments for selected configurations. 1134# 1135################################################### 1136 1137for variant_path in variant_paths: 1138 print "Building in", variant_path 1139 1140 # Make a copy of the build-root environment to use for this config. 1141 env = main.Clone() 1142 env['BUILDDIR'] = variant_path 1143 1144 # variant_dir is the tail component of build path, and is used to 1145 # determine the build parameters (e.g., 'ALPHA_SE') 1146 (build_root, variant_dir) = splitpath(variant_path) 1147 1148 # Set env variables according to the build directory config. 1149 sticky_vars.files = [] 1150 # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in 1151 # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke 1152 # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings. 1153 current_vars_file = joinpath(build_root, 'variables', variant_dir) 1154 if isfile(current_vars_file): 1155 sticky_vars.files.append(current_vars_file) 1156 print "Using saved variables file %s" % current_vars_file 1157 else: 1158 # Build dir-specific variables file doesn't exist. 1159 1160 # Make sure the directory is there so we can create it later 1161 opt_dir = dirname(current_vars_file) 1162 if not isdir(opt_dir): 1163 mkdir(opt_dir) 1164 1165 # Get default build variables from source tree. Variables are 1166 # normally determined by name of $VARIANT_DIR, but can be 1167 # overridden by '--default=' arg on command line. 1168 default = GetOption('default') 1169 opts_dir = joinpath(main.root.abspath, 'build_opts') 1170 if default: 1171 default_vars_files = [joinpath(build_root, 'variables', default), 1172 joinpath(opts_dir, default)] 1173 else: 1174 default_vars_files = [joinpath(opts_dir, variant_dir)] 1175 existing_files = filter(isfile, default_vars_files) 1176 if existing_files: 1177 default_vars_file = existing_files[0] 1178 sticky_vars.files.append(default_vars_file) 1179 print "Variables file %s not found,\n using defaults in %s" \ 1180 % (current_vars_file, default_vars_file) 1181 else: 1182 print "Error: cannot find variables file %s or " \ 1183 "default file(s) %s" \ 1184 % (current_vars_file, ' or '.join(default_vars_files)) 1185 Exit(1) 1186 1187 # Apply current variable settings to env 1188 sticky_vars.Update(env) 1189 1190 help_texts["local_vars"] += \ 1191 "Build variables for %s:\n" % variant_dir \ 1192 + sticky_vars.GenerateHelpText(env) 1193 1194 # Process variable settings. 1195 1196 if not have_fenv and env['USE_FENV']: 1197 print "Warning: <fenv.h> not available; " \ 1198 "forcing USE_FENV to False in", variant_dir + "." 1199 env['USE_FENV'] = False 1200 1201 if not env['USE_FENV']: 1202 print "Warning: No IEEE FP rounding mode control in", variant_dir + "." 1203 print " FP results may deviate slightly from other platforms." 1204 1205 if env['EFENCE']: 1206 env.Append(LIBS=['efence']) 1207 1208 # Save sticky variable settings back to current variables file 1209 sticky_vars.Save(current_vars_file, env) 1210 1211 if env['USE_SSE2']: 1212 env.Append(CCFLAGS=['-msse2']) 1213 1214 # The src/SConscript file sets up the build rules in 'env' according 1215 # to the configured variables. It returns a list of environments, 1216 # one for each variant build (debug, opt, etc.) 1217 envList = SConscript('src/SConscript', variant_dir = variant_path, 1218 exports = 'env') 1219 1220 # Set up the regression tests for each build. 1221 for e in envList: 1222 SConscript('tests/SConscript', 1223 variant_dir = joinpath(variant_path, 'tests', e.Label), 1224 exports = { 'env' : e }, duplicate = False) 1225 1226# base help text 1227Help(''' 1228Usage: scons [scons options] [build variables] [target(s)] 1229 1230Extra scons options: 1231%(options)s 1232 1233Global build variables: 1234%(global_vars)s 1235 1236%(local_vars)s 1237''' % help_texts) 1238