SConstruct revision 6814
1955SN/A# -*- mode:python -*- 2955SN/A 37816Ssteve.reinhardt@amd.com# Copyright (c) 2009 The Hewlett-Packard Development Company 45871Snate@binkert.org# Copyright (c) 2004-2005 The Regents of The University of Michigan 51762SN/A# All rights reserved. 6955SN/A# 7955SN/A# Redistribution and use in source and binary forms, with or without 8955SN/A# modification, are permitted provided that the following conditions are 9955SN/A# met: redistributions of source code must retain the above copyright 10955SN/A# notice, this list of conditions and the following disclaimer; 11955SN/A# redistributions in binary form must reproduce the above copyright 12955SN/A# notice, this list of conditions and the following disclaimer in the 13955SN/A# documentation and/or other materials provided with the distribution; 14955SN/A# neither the name of the copyright holders nor the names of its 15955SN/A# contributors may be used to endorse or promote products derived from 16955SN/A# this software without specific prior written permission. 17955SN/A# 18955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29955SN/A# 302665Ssaidi@eecs.umich.edu# Authors: Steve Reinhardt 312665Ssaidi@eecs.umich.edu# Nathan Binkert 325863Snate@binkert.org 33955SN/A################################################### 34955SN/A# 35955SN/A# SCons top-level build description (SConstruct) file. 36955SN/A# 37955SN/A# While in this directory ('m5'), just type 'scons' to build the default 388878Ssteve.reinhardt@amd.com# configuration (see below), or type 'scons build/<CONFIG>/<binary>' 392632Sstever@eecs.umich.edu# to build some other configuration (e.g., 'build/ALPHA_FS/m5.opt' for 408878Ssteve.reinhardt@amd.com# the optimized full-system version). 412632Sstever@eecs.umich.edu# 42955SN/A# You can build M5 in a different directory as long as there is a 438878Ssteve.reinhardt@amd.com# 'build/<CONFIG>' somewhere along the target path. The build system 442632Sstever@eecs.umich.edu# expects that all configs under the same build directory are being 452761Sstever@eecs.umich.edu# built for the same host system. 462632Sstever@eecs.umich.edu# 472632Sstever@eecs.umich.edu# Examples: 482632Sstever@eecs.umich.edu# 492761Sstever@eecs.umich.edu# The following two commands are equivalent. The '-u' option tells 502761Sstever@eecs.umich.edu# scons to search up the directory tree for this SConstruct file. 512761Sstever@eecs.umich.edu# % cd <path-to-src>/m5 ; scons build/ALPHA_FS/m5.debug 528878Ssteve.reinhardt@amd.com# % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug 538878Ssteve.reinhardt@amd.com# 542761Sstever@eecs.umich.edu# The following two commands are equivalent and demonstrate building 552761Sstever@eecs.umich.edu# in a directory outside of the source tree. The '-C' option tells 562761Sstever@eecs.umich.edu# scons to chdir to the specified directory to find this SConstruct 572761Sstever@eecs.umich.edu# file. 582761Sstever@eecs.umich.edu# % cd <path-to-src>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug 598878Ssteve.reinhardt@amd.com# % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug 608878Ssteve.reinhardt@amd.com# 612632Sstever@eecs.umich.edu# You can use 'scons -H' to print scons options. If you're in this 622632Sstever@eecs.umich.edu# 'm5' directory (or use -u or -C to tell scons where to find this 638878Ssteve.reinhardt@amd.com# file), you can use 'scons -h' to print all the M5-specific build 648878Ssteve.reinhardt@amd.com# options as well. 652632Sstever@eecs.umich.edu# 66955SN/A################################################### 67955SN/A 68955SN/A# Check for recent-enough Python and SCons versions. 695863Snate@binkert.orgtry: 705863Snate@binkert.org # Really old versions of scons only take two options for the 715863Snate@binkert.org # function, so check once without the revision and once with the 725863Snate@binkert.org # revision, the first instance will fail for stuff other than 735863Snate@binkert.org # 0.98, and the second will fail for 0.98.0 745863Snate@binkert.org EnsureSConsVersion(0, 98) 755863Snate@binkert.org EnsureSConsVersion(0, 98, 1) 765863Snate@binkert.orgexcept SystemExit, e: 775863Snate@binkert.org print """ 785863Snate@binkert.orgFor more details, see: 795863Snate@binkert.org http://m5sim.org/wiki/index.php/Compiling_M5 808878Ssteve.reinhardt@amd.com""" 815863Snate@binkert.org raise 825863Snate@binkert.org 835863Snate@binkert.org# We ensure the python version early because we have stuff that 845863Snate@binkert.org# requires python 2.4 855863Snate@binkert.orgtry: 865863Snate@binkert.org EnsurePythonVersion(2, 4) 875863Snate@binkert.orgexcept SystemExit, e: 885863Snate@binkert.org print """ 895863Snate@binkert.orgYou can use a non-default installation of the Python interpreter by 905863Snate@binkert.orgeither (1) rearranging your PATH so that scons finds the non-default 915863Snate@binkert.org'python' first or (2) explicitly invoking an alternative interpreter 925863Snate@binkert.orgon the scons script. 935863Snate@binkert.org 945863Snate@binkert.orgFor more details, see: 955863Snate@binkert.org http://m5sim.org/wiki/index.php/Using_a_non-default_Python_installation 968878Ssteve.reinhardt@amd.com""" 975863Snate@binkert.org raise 985863Snate@binkert.org 995863Snate@binkert.org# Global Python includes 1006654Snate@binkert.orgimport os 101955SN/Aimport re 1025396Ssaidi@eecs.umich.eduimport subprocess 1035863Snate@binkert.orgimport sys 1045863Snate@binkert.org 1054202Sbinkertn@umich.edufrom os import mkdir, environ 1065863Snate@binkert.orgfrom os.path import abspath, basename, dirname, expanduser, normpath 1075863Snate@binkert.orgfrom os.path import exists, isdir, isfile 1085863Snate@binkert.orgfrom os.path import join as joinpath, split as splitpath 1095863Snate@binkert.org 110955SN/A# SCons includes 1116654Snate@binkert.orgimport SCons 1125273Sstever@gmail.comimport SCons.Node 1135871Snate@binkert.org 1145273Sstever@gmail.comextra_python_paths = [ 1156655Snate@binkert.org Dir('src/python').srcnode().abspath, # M5 includes 1168878Ssteve.reinhardt@amd.com Dir('ext/ply').srcnode().abspath, # ply is used by several files 1176655Snate@binkert.org ] 1186655Snate@binkert.org 1199219Spower.jg@gmail.comsys.path[1:1] = extra_python_paths 1206655Snate@binkert.org 1215871Snate@binkert.orgfrom m5.util import compareVersions, readCommand 1226654Snate@binkert.org 1238947Sandreas.hansson@arm.com######################################################################## 1245396Ssaidi@eecs.umich.edu# 1258120Sgblack@eecs.umich.edu# Set up the main build environment. 1268120Sgblack@eecs.umich.edu# 1278120Sgblack@eecs.umich.edu######################################################################## 1288120Sgblack@eecs.umich.eduuse_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH', 1298120Sgblack@eecs.umich.edu 'PYTHONPATH', 'RANLIB' ]) 1308120Sgblack@eecs.umich.edu 1318120Sgblack@eecs.umich.eduuse_env = {} 1328120Sgblack@eecs.umich.edufor key,val in os.environ.iteritems(): 1338879Ssteve.reinhardt@amd.com if key in use_vars or key.startswith("M5"): 1348879Ssteve.reinhardt@amd.com use_env[key] = val 1358879Ssteve.reinhardt@amd.com 1368879Ssteve.reinhardt@amd.commain = Environment(ENV=use_env) 1378879Ssteve.reinhardt@amd.commain.root = Dir(".") # The current directory (where this file lives). 1388879Ssteve.reinhardt@amd.commain.srcdir = Dir("src") # The source directory 1398879Ssteve.reinhardt@amd.com 1408879Ssteve.reinhardt@amd.com# add useful python code PYTHONPATH so it can be used by subprocesses 1418879Ssteve.reinhardt@amd.com# as well 1428879Ssteve.reinhardt@amd.commain.AppendENVPath('PYTHONPATH', extra_python_paths) 1438879Ssteve.reinhardt@amd.com 1448879Ssteve.reinhardt@amd.com######################################################################## 1458879Ssteve.reinhardt@amd.com# 1468120Sgblack@eecs.umich.edu# Mercurial Stuff. 1478120Sgblack@eecs.umich.edu# 1488120Sgblack@eecs.umich.edu# If the M5 directory is a mercurial repository, we should do some 1498120Sgblack@eecs.umich.edu# extra things. 1508120Sgblack@eecs.umich.edu# 1518120Sgblack@eecs.umich.edu######################################################################## 1528120Sgblack@eecs.umich.edu 1538120Sgblack@eecs.umich.eduhgdir = main.root.Dir(".hg") 1548120Sgblack@eecs.umich.edu 1558120Sgblack@eecs.umich.edumercurial_style_message = """ 1568120Sgblack@eecs.umich.eduYou're missing the M5 style hook. 1578120Sgblack@eecs.umich.eduPlease install the hook so we can ensure that all code fits a common style. 1588120Sgblack@eecs.umich.edu 1598120Sgblack@eecs.umich.eduAll you'd need to do is add the following lines to your repository .hg/hgrc 1608879Ssteve.reinhardt@amd.comor your personal .hgrc 1618879Ssteve.reinhardt@amd.com---------------- 1628879Ssteve.reinhardt@amd.com 1638879Ssteve.reinhardt@amd.com[extensions] 1648879Ssteve.reinhardt@amd.comstyle = %s/util/style.py 1658879Ssteve.reinhardt@amd.com 1668879Ssteve.reinhardt@amd.com[hooks] 1678879Ssteve.reinhardt@amd.compretxncommit.style = python:style.check_whitespace 1689227Sandreas.hansson@arm.com""" % (main.root) 1699227Sandreas.hansson@arm.com 1708879Ssteve.reinhardt@amd.commercurial_bin_not_found = """ 1718879Ssteve.reinhardt@amd.comMercurial binary cannot be found, unfortunately this means that we 1728879Ssteve.reinhardt@amd.comcannot easily determine the version of M5 that you are running and 1738879Ssteve.reinhardt@amd.comthis makes error messages more difficult to collect. Please consider 1748120Sgblack@eecs.umich.eduinstalling mercurial if you choose to post an error message 1758947Sandreas.hansson@arm.com""" 1767816Ssteve.reinhardt@amd.com 1775871Snate@binkert.orgmercurial_lib_not_found = """ 1785871Snate@binkert.orgMercurial libraries cannot be found, ignoring style hook 1796121Snate@binkert.orgIf you are actually a M5 developer, please fix this and 1805871Snate@binkert.orgrun the style hook. It is important. 1815871Snate@binkert.org""" 1829119Sandreas.hansson@arm.com 1839119Sandreas.hansson@arm.comhg_info = "Unknown" 184955SN/Aif hgdir.exists(): 1855871Snate@binkert.org # 1) Grab repository revision if we know it. 1865871Snate@binkert.org cmd = "hg id -n -i -t -b" 1875871Snate@binkert.org try: 1885871Snate@binkert.org hg_info = readCommand(cmd, cwd=main.root.abspath).strip() 189955SN/A except OSError: 1906121Snate@binkert.org print mercurial_bin_not_found 1918881Smarc.orr@gmail.com 1926121Snate@binkert.org # 2) Ensure that the style hook is in place. 1936121Snate@binkert.org try: 1941533SN/A ui = None 1959239Sandreas.hansson@arm.com if ARGUMENTS.get('IGNORE_STYLE') != 'True': 1969239Sandreas.hansson@arm.com from mercurial import ui 1979239Sandreas.hansson@arm.com ui = ui.ui() 1989239Sandreas.hansson@arm.com except ImportError: 1999239Sandreas.hansson@arm.com print mercurial_lib_not_found 2009239Sandreas.hansson@arm.com 2019239Sandreas.hansson@arm.com if ui is not None: 2029239Sandreas.hansson@arm.com ui.readconfig(hgdir.File('hgrc').abspath) 2039239Sandreas.hansson@arm.com style_hook = ui.config('hooks', 'pretxncommit.style', None) 2049239Sandreas.hansson@arm.com 2059239Sandreas.hansson@arm.com if not style_hook: 2069239Sandreas.hansson@arm.com print mercurial_style_message 2076655Snate@binkert.org sys.exit(1) 2086655Snate@binkert.orgelse: 2096655Snate@binkert.org print ".hg directory not found" 2106655Snate@binkert.org 2115871Snate@binkert.orgmain['HG_INFO'] = hg_info 2125871Snate@binkert.org 2135863Snate@binkert.org################################################### 2145871Snate@binkert.org# 2158878Ssteve.reinhardt@amd.com# Figure out which configurations to set up based on the path(s) of 2165871Snate@binkert.org# the target(s). 2175871Snate@binkert.org# 2185871Snate@binkert.org################################################### 2195863Snate@binkert.org 2206121Snate@binkert.org# Find default configuration & binary. 2215863Snate@binkert.orgDefault(environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug')) 2225871Snate@binkert.org 2238336Ssteve.reinhardt@amd.com# helper function: find last occurrence of element in list 2248336Ssteve.reinhardt@amd.comdef rfind(l, elt, offs = -1): 2258336Ssteve.reinhardt@amd.com for i in range(len(l)+offs, 0, -1): 2268336Ssteve.reinhardt@amd.com if l[i] == elt: 2274678Snate@binkert.org return i 2288336Ssteve.reinhardt@amd.com raise ValueError, "element not found" 2298336Ssteve.reinhardt@amd.com 2308336Ssteve.reinhardt@amd.com# Each target must have 'build' in the interior of the path; the 2314678Snate@binkert.org# directory below this will determine the build parameters. For 2324678Snate@binkert.org# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we 2334678Snate@binkert.org# recognize that ALPHA_SE specifies the configuration because it 2344678Snate@binkert.org# follow 'build' in the bulid path. 2357827Snate@binkert.org 2367827Snate@binkert.org# Generate absolute paths to targets so we can see where the build dir is 2378336Ssteve.reinhardt@amd.comif COMMAND_LINE_TARGETS: 2384678Snate@binkert.org # Ask SCons which directory it was invoked from 2398336Ssteve.reinhardt@amd.com launch_dir = GetLaunchDir() 2408336Ssteve.reinhardt@amd.com # Make targets relative to invocation directory 2418336Ssteve.reinhardt@amd.com abs_targets = [ normpath(joinpath(launch_dir, str(x))) for x in \ 2428336Ssteve.reinhardt@amd.com COMMAND_LINE_TARGETS] 2438336Ssteve.reinhardt@amd.comelse: 2448336Ssteve.reinhardt@amd.com # Default targets are relative to root of tree 2455871Snate@binkert.org abs_targets = [ normpath(joinpath(main.root.abspath, str(x))) for x in \ 2465871Snate@binkert.org DEFAULT_TARGETS] 2478336Ssteve.reinhardt@amd.com 2488336Ssteve.reinhardt@amd.com 2498336Ssteve.reinhardt@amd.com# Generate a list of the unique build roots and configs that the 2508336Ssteve.reinhardt@amd.com# collected targets reference. 2518336Ssteve.reinhardt@amd.comvariant_paths = [] 2525871Snate@binkert.orgbuild_root = None 2538336Ssteve.reinhardt@amd.comfor t in abs_targets: 2548336Ssteve.reinhardt@amd.com path_dirs = t.split('/') 2558336Ssteve.reinhardt@amd.com try: 2568336Ssteve.reinhardt@amd.com build_top = rfind(path_dirs, 'build', -2) 2578336Ssteve.reinhardt@amd.com except: 2584678Snate@binkert.org print "Error: no non-leaf 'build' dir found on target path", t 2595871Snate@binkert.org Exit(1) 2604678Snate@binkert.org this_build_root = joinpath('/',*path_dirs[:build_top+1]) 2618336Ssteve.reinhardt@amd.com if not build_root: 2628336Ssteve.reinhardt@amd.com build_root = this_build_root 2638336Ssteve.reinhardt@amd.com else: 2648336Ssteve.reinhardt@amd.com if this_build_root != build_root: 2658336Ssteve.reinhardt@amd.com print "Error: build targets not under same build root\n"\ 2668336Ssteve.reinhardt@amd.com " %s\n %s" % (build_root, this_build_root) 2678336Ssteve.reinhardt@amd.com Exit(1) 2688336Ssteve.reinhardt@amd.com variant_path = joinpath('/',*path_dirs[:build_top+2]) 2698336Ssteve.reinhardt@amd.com if variant_path not in variant_paths: 2708336Ssteve.reinhardt@amd.com variant_paths.append(variant_path) 2718336Ssteve.reinhardt@amd.com 2728336Ssteve.reinhardt@amd.com# Make sure build_root exists (might not if this is the first build there) 2738336Ssteve.reinhardt@amd.comif not isdir(build_root): 2748336Ssteve.reinhardt@amd.com mkdir(build_root) 2758336Ssteve.reinhardt@amd.com 2768336Ssteve.reinhardt@amd.comExport('main') 2778336Ssteve.reinhardt@amd.com 2785871Snate@binkert.orgmain.SConsignFile(joinpath(build_root, "sconsign")) 2796121Snate@binkert.org 280955SN/A# Default duplicate option is to use hard links, but this messes up 281955SN/A# when you use emacs to edit a file in the target dir, as emacs moves 2822632Sstever@eecs.umich.edu# file to file~ then copies to file, breaking the link. Symbolic 2832632Sstever@eecs.umich.edu# (soft) links work better. 284955SN/Amain.SetOption('duplicate', 'soft-copy') 285955SN/A 286955SN/A# 287955SN/A# Set up global sticky variables... these are common to an entire build 2888878Ssteve.reinhardt@amd.com# tree (not specific to a particular build like ALPHA_SE) 289955SN/A# 2902632Sstever@eecs.umich.edu 2912632Sstever@eecs.umich.edu# Variable validators & converters for global sticky variables 2922632Sstever@eecs.umich.edudef PathListMakeAbsolute(val): 2932632Sstever@eecs.umich.edu if not val: 2942632Sstever@eecs.umich.edu return val 2952632Sstever@eecs.umich.edu f = lambda p: abspath(expanduser(p)) 2962632Sstever@eecs.umich.edu return ':'.join(map(f, val.split(':'))) 2978268Ssteve.reinhardt@amd.com 2988268Ssteve.reinhardt@amd.comdef PathListAllExist(key, val, env): 2998268Ssteve.reinhardt@amd.com if not val: 3008268Ssteve.reinhardt@amd.com return 3018268Ssteve.reinhardt@amd.com paths = val.split(':') 3028268Ssteve.reinhardt@amd.com for path in paths: 3038268Ssteve.reinhardt@amd.com if not isdir(path): 3042632Sstever@eecs.umich.edu raise SCons.Errors.UserError("Path does not exist: '%s'" % path) 3052632Sstever@eecs.umich.edu 3062632Sstever@eecs.umich.eduglobal_sticky_vars_file = joinpath(build_root, 'variables.global') 3072632Sstever@eecs.umich.edu 3088268Ssteve.reinhardt@amd.comglobal_sticky_vars = Variables(global_sticky_vars_file, args=ARGUMENTS) 3092632Sstever@eecs.umich.edu 3108268Ssteve.reinhardt@amd.comglobal_sticky_vars.AddVariables( 3118268Ssteve.reinhardt@amd.com ('CC', 'C compiler', environ.get('CC', main['CC'])), 3128268Ssteve.reinhardt@amd.com ('CXX', 'C++ compiler', environ.get('CXX', main['CXX'])), 3138268Ssteve.reinhardt@amd.com ('BATCH', 'Use batch pool for build and tests', False), 3143718Sstever@eecs.umich.edu ('BATCH_CMD', 'Batch pool submission command name', 'qdo'), 3152634Sstever@eecs.umich.edu ('EXTRAS', 'Add Extra directories to the compilation', '', 3162634Sstever@eecs.umich.edu PathListAllExist, PathListMakeAbsolute), 3175863Snate@binkert.org BoolVariable('RUBY', 'Build with Ruby', False), 3182638Sstever@eecs.umich.edu ) 3198268Ssteve.reinhardt@amd.com 3202632Sstever@eecs.umich.edu# base help text 3212632Sstever@eecs.umich.eduhelp_text = ''' 3222632Sstever@eecs.umich.eduUsage: scons [scons options] [build options] [target(s)] 3232632Sstever@eecs.umich.edu 3242632Sstever@eecs.umich.eduGlobal sticky options: 3251858SN/A''' 3263716Sstever@eecs.umich.edu 3272638Sstever@eecs.umich.edu# Update main environment with values from ARGUMENTS & global_sticky_vars_file 3282638Sstever@eecs.umich.eduglobal_sticky_vars.Update(main) 3292638Sstever@eecs.umich.edu 3302638Sstever@eecs.umich.eduhelp_text += global_sticky_vars.GenerateHelpText(main) 3312638Sstever@eecs.umich.edu 3322638Sstever@eecs.umich.edu# Save sticky variable settings back to current variables file 3332638Sstever@eecs.umich.eduglobal_sticky_vars.Save(global_sticky_vars_file, main) 3345863Snate@binkert.org 3355863Snate@binkert.org# Parse EXTRAS variable to build list of all directories where we're 3365863Snate@binkert.org# look for sources etc. This list is exported as base_dir_list. 337955SN/Abase_dir = main.srcdir.abspath 3385341Sstever@gmail.comif main['EXTRAS']: 3395341Sstever@gmail.com extras_dir_list = main['EXTRAS'].split(':') 3405863Snate@binkert.orgelse: 3417756SAli.Saidi@ARM.com extras_dir_list = [] 3425341Sstever@gmail.com 3436121Snate@binkert.orgExport('base_dir') 3444494Ssaidi@eecs.umich.eduExport('extras_dir_list') 3456121Snate@binkert.org 3461105SN/A# the ext directory should be on the #includes path 3472667Sstever@eecs.umich.edumain.Append(CPPPATH=[Dir('ext')]) 3482667Sstever@eecs.umich.edu 3492667Sstever@eecs.umich.eduCXX_version = readCommand([main['CXX'],'--version'], exception=False) 3502667Sstever@eecs.umich.eduCXX_V = readCommand([main['CXX'],'-V'], exception=False) 3516121Snate@binkert.org 3522667Sstever@eecs.umich.edumain['GCC'] = CXX_version and CXX_version.find('g++') >= 0 3535341Sstever@gmail.commain['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0 3545863Snate@binkert.orgmain['ICC'] = CXX_V and CXX_V.find('Intel') >= 0 3555341Sstever@gmail.comif main['GCC'] + main['SUNCC'] + main['ICC'] > 1: 3565341Sstever@gmail.com print 'Error: How can we have two at the same time?' 3575341Sstever@gmail.com Exit(1) 3588120Sgblack@eecs.umich.edu 3595341Sstever@gmail.com# Set up default C++ compiler flags 3608120Sgblack@eecs.umich.eduif main['GCC']: 3615341Sstever@gmail.com main.Append(CCFLAGS='-pipe') 3628120Sgblack@eecs.umich.edu main.Append(CCFLAGS='-fno-strict-aliasing') 3636121Snate@binkert.org main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef']) 3646121Snate@binkert.org main.Append(CXXFLAGS='-Wno-deprecated') 3658980Ssteve.reinhardt@amd.comelif main['ICC']: 3665397Ssaidi@eecs.umich.edu pass #Fix me... add warning flags once we clean up icc warnings 3675397Ssaidi@eecs.umich.eduelif main['SUNCC']: 3687727SAli.Saidi@ARM.com main.Append(CCFLAGS='-Qoption ccfe') 3698268Ssteve.reinhardt@amd.com main.Append(CCFLAGS='-features=gcc') 3706168Snate@binkert.org main.Append(CCFLAGS='-features=extensions') 3715341Sstever@gmail.com main.Append(CCFLAGS='-library=stlport4') 3728120Sgblack@eecs.umich.edu main.Append(CCFLAGS='-xar') 3738120Sgblack@eecs.umich.edu #main.Append(CCFLAGS='-instances=semiexplicit') 3748120Sgblack@eecs.umich.eduelse: 3756814Sgblack@eecs.umich.edu print 'Error: Don\'t know what compiler options to use for your compiler.' 3765863Snate@binkert.org print ' Please fix SConstruct and src/SConscript and try again.' 3778120Sgblack@eecs.umich.edu Exit(1) 3785341Sstever@gmail.com 3795863Snate@binkert.org# Set up common yacc/bison flags (needed for Ruby) 3808268Ssteve.reinhardt@amd.commain['YACCFLAGS'] = '-d' 3816121Snate@binkert.orgmain['YACCHXXFILESUFFIX'] = '.hh' 3826121Snate@binkert.org 3838268Ssteve.reinhardt@amd.com# Do this after we save setting back, or else we'll tack on an 3845742Snate@binkert.org# extra 'qdo' every time we run scons. 3855742Snate@binkert.orgif main['BATCH']: 3865341Sstever@gmail.com main['CC'] = main['BATCH_CMD'] + ' ' + main['CC'] 3875742Snate@binkert.org main['CXX'] = main['BATCH_CMD'] + ' ' + main['CXX'] 3885742Snate@binkert.org main['AS'] = main['BATCH_CMD'] + ' ' + main['AS'] 3895341Sstever@gmail.com main['AR'] = main['BATCH_CMD'] + ' ' + main['AR'] 3906017Snate@binkert.org main['RANLIB'] = main['BATCH_CMD'] + ' ' + main['RANLIB'] 3916121Snate@binkert.org 3926017Snate@binkert.orgif sys.platform == 'cygwin': 3937816Ssteve.reinhardt@amd.com # cygwin has some header file issues... 3947756SAli.Saidi@ARM.com main.Append(CCFLAGS="-Wno-uninitialized") 3957756SAli.Saidi@ARM.com 3967756SAli.Saidi@ARM.com# Check for SWIG 3977756SAli.Saidi@ARM.comif not main.has_key('SWIG'): 3987756SAli.Saidi@ARM.com print 'Error: SWIG utility not found.' 3997756SAli.Saidi@ARM.com print ' Please install (see http://www.swig.org) and retry.' 4007756SAli.Saidi@ARM.com Exit(1) 4017756SAli.Saidi@ARM.com 4027816Ssteve.reinhardt@amd.com# Check for appropriate SWIG version 4037816Ssteve.reinhardt@amd.comswig_version = readCommand(('swig', '-version'), exception='').split() 4047816Ssteve.reinhardt@amd.com# First 3 words should be "SWIG Version x.y.z" 4057816Ssteve.reinhardt@amd.comif len(swig_version) < 3 or \ 4067816Ssteve.reinhardt@amd.com swig_version[0] != 'SWIG' or swig_version[1] != 'Version': 4077816Ssteve.reinhardt@amd.com print 'Error determining SWIG version.' 4087816Ssteve.reinhardt@amd.com Exit(1) 4097816Ssteve.reinhardt@amd.com 4107816Ssteve.reinhardt@amd.commin_swig_version = '1.3.28' 4117816Ssteve.reinhardt@amd.comif compareVersions(swig_version[2], min_swig_version) < 0: 4127756SAli.Saidi@ARM.com print 'Error: SWIG version', min_swig_version, 'or newer required.' 4137816Ssteve.reinhardt@amd.com print ' Installed version:', swig_version[2] 4147816Ssteve.reinhardt@amd.com Exit(1) 4157816Ssteve.reinhardt@amd.com 4167816Ssteve.reinhardt@amd.com# Set up SWIG flags & scanner 4177816Ssteve.reinhardt@amd.comswig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS') 4187816Ssteve.reinhardt@amd.commain.Append(SWIGFLAGS=swig_flags) 4197816Ssteve.reinhardt@amd.com 4207816Ssteve.reinhardt@amd.com# filter out all existing swig scanners, they mess up the dependency 4217816Ssteve.reinhardt@amd.com# stuff for some reason 4227816Ssteve.reinhardt@amd.comscanners = [] 4237816Ssteve.reinhardt@amd.comfor scanner in main['SCANNERS']: 4247816Ssteve.reinhardt@amd.com skeys = scanner.skeys 4257816Ssteve.reinhardt@amd.com if skeys == '.i': 4267816Ssteve.reinhardt@amd.com continue 4277816Ssteve.reinhardt@amd.com 4287816Ssteve.reinhardt@amd.com if isinstance(skeys, (list, tuple)) and '.i' in skeys: 4297816Ssteve.reinhardt@amd.com continue 4307816Ssteve.reinhardt@amd.com 4317816Ssteve.reinhardt@amd.com scanners.append(scanner) 4327816Ssteve.reinhardt@amd.com 4337816Ssteve.reinhardt@amd.com# add the new swig scanner that we like better 4347816Ssteve.reinhardt@amd.comfrom SCons.Scanner import ClassicCPP as CPPScanner 4357816Ssteve.reinhardt@amd.comswig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")' 4367816Ssteve.reinhardt@amd.comscanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re)) 4377816Ssteve.reinhardt@amd.com 4387816Ssteve.reinhardt@amd.com# replace the scanners list that has what we want 4397816Ssteve.reinhardt@amd.commain['SCANNERS'] = scanners 4407816Ssteve.reinhardt@amd.com 4417816Ssteve.reinhardt@amd.com# Add a custom Check function to the Configure context so that we can 4427816Ssteve.reinhardt@amd.com# figure out if the compiler adds leading underscores to global 4437816Ssteve.reinhardt@amd.com# variables. This is needed for the autogenerated asm files that we 4447816Ssteve.reinhardt@amd.com# use for embedding the python code. 4457816Ssteve.reinhardt@amd.comdef CheckLeading(context): 4467816Ssteve.reinhardt@amd.com context.Message("Checking for leading underscore in global variables...") 4477816Ssteve.reinhardt@amd.com # 1) Define a global variable called x from asm so the C compiler 4487816Ssteve.reinhardt@amd.com # won't change the symbol at all. 4497816Ssteve.reinhardt@amd.com # 2) Declare that variable. 4507816Ssteve.reinhardt@amd.com # 3) Use the variable 4517816Ssteve.reinhardt@amd.com # 4527816Ssteve.reinhardt@amd.com # If the compiler prepends an underscore, this will successfully 4537816Ssteve.reinhardt@amd.com # link because the external symbol 'x' will be called '_x' which 4547816Ssteve.reinhardt@amd.com # was defined by the asm statement. If the compiler does not 4557816Ssteve.reinhardt@amd.com # prepend an underscore, this will not successfully link because 4567816Ssteve.reinhardt@amd.com # '_x' will have been defined by assembly, while the C portion of 4577816Ssteve.reinhardt@amd.com # the code will be trying to use 'x' 4587816Ssteve.reinhardt@amd.com ret = context.TryLink(''' 4597816Ssteve.reinhardt@amd.com asm(".globl _x; _x: .byte 0"); 4607816Ssteve.reinhardt@amd.com extern int x; 4617816Ssteve.reinhardt@amd.com int main() { return x; } 4627816Ssteve.reinhardt@amd.com ''', extension=".c") 4637816Ssteve.reinhardt@amd.com context.env.Append(LEADING_UNDERSCORE=ret) 4647816Ssteve.reinhardt@amd.com context.Result(ret) 4657816Ssteve.reinhardt@amd.com return ret 4667816Ssteve.reinhardt@amd.com 4677816Ssteve.reinhardt@amd.com# Platform-specific configuration. Note again that we assume that all 4687816Ssteve.reinhardt@amd.com# builds under a given build root run on the same host platform. 4697816Ssteve.reinhardt@amd.comconf = Configure(main, 4707816Ssteve.reinhardt@amd.com conf_dir = joinpath(build_root, '.scons_config'), 4717816Ssteve.reinhardt@amd.com log_file = joinpath(build_root, 'scons_config.log'), 4727816Ssteve.reinhardt@amd.com custom_tests = { 'CheckLeading' : CheckLeading }) 4737816Ssteve.reinhardt@amd.com 4748947Sandreas.hansson@arm.com# Check for leading underscores. Don't really need to worry either 4758947Sandreas.hansson@arm.com# way so don't need to check the return code. 4767756SAli.Saidi@ARM.comconf.CheckLeading() 4778120Sgblack@eecs.umich.edu 4787756SAli.Saidi@ARM.com# Check if we should compile a 64 bit binary on Mac OS X/Darwin 4797756SAli.Saidi@ARM.comtry: 4807756SAli.Saidi@ARM.com import platform 4817756SAli.Saidi@ARM.com uname = platform.uname() 4827816Ssteve.reinhardt@amd.com if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: 4837816Ssteve.reinhardt@amd.com if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): 4847816Ssteve.reinhardt@amd.com main.Append(CCFLAGS='-arch x86_64') 4857816Ssteve.reinhardt@amd.com main.Append(CFLAGS='-arch x86_64') 4867816Ssteve.reinhardt@amd.com main.Append(LINKFLAGS='-arch x86_64') 4877816Ssteve.reinhardt@amd.com main.Append(ASFLAGS='-arch x86_64') 4887816Ssteve.reinhardt@amd.comexcept: 4897816Ssteve.reinhardt@amd.com pass 4907816Ssteve.reinhardt@amd.com 4917816Ssteve.reinhardt@amd.com# Recent versions of scons substitute a "Null" object for Configure() 4927756SAli.Saidi@ARM.com# when configuration isn't necessary, e.g., if the "--help" option is 4937756SAli.Saidi@ARM.com# present. Unfortuantely this Null object always returns false, 4949227Sandreas.hansson@arm.com# breaking all our configuration checks. We replace it with our own 4959227Sandreas.hansson@arm.com# more optimistic null object that returns True instead. 4969227Sandreas.hansson@arm.comif not conf: 4979227Sandreas.hansson@arm.com def NullCheck(*args, **kwargs): 4986654Snate@binkert.org return True 4996654Snate@binkert.org 5005871Snate@binkert.org class NullConf: 5016121Snate@binkert.org def __init__(self, env): 5026121Snate@binkert.org self.env = env 5036121Snate@binkert.org def Finish(self): 5048946Sandreas.hansson@arm.com return self.env 5058737Skoansin.tan@gmail.com def __getattr__(self, mname): 5063940Ssaidi@eecs.umich.edu return NullCheck 5073918Ssaidi@eecs.umich.edu 5083918Ssaidi@eecs.umich.edu conf = NullConf(main) 5091858SN/A 5106121Snate@binkert.org# Find Python include and library directories for embedding the 5117739Sgblack@eecs.umich.edu# interpreter. For consistency, we will use the same Python 5127739Sgblack@eecs.umich.edu# installation used to run scons (and thus this script). If you want 5136143Snate@binkert.org# to link in an alternate version, see above for instructions on how 5147618SAli.Saidi@arm.com# to invoke scons with a different copy of the Python interpreter. 5157618SAli.Saidi@arm.comfrom distutils import sysconfig 5167618SAli.Saidi@arm.com 5177618SAli.Saidi@arm.compy_getvar = sysconfig.get_config_var 5188614Sgblack@eecs.umich.edu 5197618SAli.Saidi@arm.compy_version = 'python' + py_getvar('VERSION') 5207618SAli.Saidi@arm.com 5217618SAli.Saidi@arm.compy_general_include = sysconfig.get_python_inc() 5227739Sgblack@eecs.umich.edupy_platform_include = sysconfig.get_python_inc(plat_specific=True) 5239224Sandreas.hansson@arm.compy_includes = [ py_general_include ] 5249224Sandreas.hansson@arm.comif py_platform_include != py_general_include: 5259224Sandreas.hansson@arm.com py_includes.append(py_platform_include) 5268946Sandreas.hansson@arm.com 5279227Sandreas.hansson@arm.compy_lib_path = [ py_getvar('LIBDIR') ] 5289227Sandreas.hansson@arm.com# add the prefix/lib/pythonX.Y/config dir, but only if there is no 5299227Sandreas.hansson@arm.com# shared library in prefix/lib/. 5309227Sandreas.hansson@arm.comif not py_getvar('Py_ENABLE_SHARED'): 5319227Sandreas.hansson@arm.com py_lib_path.append(py_getvar('LIBPL')) 5329227Sandreas.hansson@arm.com 5339227Sandreas.hansson@arm.compy_libs = [] 5349227Sandreas.hansson@arm.comfor lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split(): 5359227Sandreas.hansson@arm.com assert lib.startswith('-l') 5369227Sandreas.hansson@arm.com lib = lib[2:] 5379227Sandreas.hansson@arm.com if lib not in py_libs: 5389227Sandreas.hansson@arm.com py_libs.append(lib) 5399227Sandreas.hansson@arm.compy_libs.append(py_version) 5409227Sandreas.hansson@arm.com 5419227Sandreas.hansson@arm.commain.Append(CPPPATH=py_includes) 5429227Sandreas.hansson@arm.commain.Append(LIBPATH=py_lib_path) 5439227Sandreas.hansson@arm.com 5449227Sandreas.hansson@arm.com# verify that this stuff works 5456121Snate@binkert.orgif not conf.CheckHeader('Python.h', '<>'): 5463940Ssaidi@eecs.umich.edu print "Error: can't find Python.h header in", py_includes 5476121Snate@binkert.org Exit(1) 5487739Sgblack@eecs.umich.edu 5497739Sgblack@eecs.umich.edufor lib in py_libs: 5507739Sgblack@eecs.umich.edu if not conf.CheckLib(lib): 5517739Sgblack@eecs.umich.edu print "Error: can't find library %s required by python" % lib 5527739Sgblack@eecs.umich.edu Exit(1) 5537739Sgblack@eecs.umich.edu 5548737Skoansin.tan@gmail.com# On Solaris you need to use libsocket for socket ops 5558737Skoansin.tan@gmail.comif not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): 5568737Skoansin.tan@gmail.com if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): 5578737Skoansin.tan@gmail.com print "Can't find library with socket calls (e.g. accept())" 5588737Skoansin.tan@gmail.com Exit(1) 5598737Skoansin.tan@gmail.com 5608737Skoansin.tan@gmail.com# Check for zlib. If the check passes, libz will be automatically 5618737Skoansin.tan@gmail.com# added to the LIBS environment variable. 5628737Skoansin.tan@gmail.comif not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'): 5638737Skoansin.tan@gmail.com print 'Error: did not find needed zlib compression library '\ 5648737Skoansin.tan@gmail.com 'and/or zlib.h header file.' 5658737Skoansin.tan@gmail.com print ' Please install zlib and try again.' 5668737Skoansin.tan@gmail.com Exit(1) 5678737Skoansin.tan@gmail.com 5688737Skoansin.tan@gmail.com# Check for <fenv.h> (C99 FP environment control) 5698737Skoansin.tan@gmail.comhave_fenv = conf.CheckHeader('fenv.h', '<>') 5708737Skoansin.tan@gmail.comif not have_fenv: 5718737Skoansin.tan@gmail.com print "Warning: Header file <fenv.h> not found." 5728946Sandreas.hansson@arm.com print " This host has no IEEE FP rounding mode control." 5738946Sandreas.hansson@arm.com 5748946Sandreas.hansson@arm.com###################################################################### 5758946Sandreas.hansson@arm.com# 5769224Sandreas.hansson@arm.com# Check for mysql. 5779224Sandreas.hansson@arm.com# 5788946Sandreas.hansson@arm.commysql_config = WhereIs('mysql_config') 5798946Sandreas.hansson@arm.comhave_mysql = bool(mysql_config) 5803918Ssaidi@eecs.umich.edu 5819068SAli.Saidi@ARM.com# Check MySQL version. 5829068SAli.Saidi@ARM.comif have_mysql: 5839068SAli.Saidi@ARM.com mysql_version = readCommand(mysql_config + ' --version') 5849068SAli.Saidi@ARM.com min_mysql_version = '4.1' 5859068SAli.Saidi@ARM.com if compareVersions(mysql_version, min_mysql_version) < 0: 5869068SAli.Saidi@ARM.com print 'Warning: MySQL', min_mysql_version, 'or newer required.' 5879068SAli.Saidi@ARM.com print ' Version', mysql_version, 'detected.' 5889068SAli.Saidi@ARM.com have_mysql = False 5899068SAli.Saidi@ARM.com 5909068SAli.Saidi@ARM.com# Set up mysql_config commands. 5919068SAli.Saidi@ARM.comif have_mysql: 5929068SAli.Saidi@ARM.com mysql_config_include = mysql_config + ' --include' 5939068SAli.Saidi@ARM.com if os.system(mysql_config_include + ' > /dev/null') != 0: 5949068SAli.Saidi@ARM.com # older mysql_config versions don't support --include, use 5959068SAli.Saidi@ARM.com # --cflags instead 5969068SAli.Saidi@ARM.com mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g' 5973918Ssaidi@eecs.umich.edu # This seems to work in all versions 5983918Ssaidi@eecs.umich.edu mysql_config_libs = mysql_config + ' --libs' 5996157Snate@binkert.org 6006157Snate@binkert.org###################################################################### 6016157Snate@binkert.org# 6026157Snate@binkert.org# Finish the configuration 6035397Ssaidi@eecs.umich.edu# 6045397Ssaidi@eecs.umich.edumain = conf.Finish() 6056121Snate@binkert.org 6066121Snate@binkert.org###################################################################### 6076121Snate@binkert.org# 6086121Snate@binkert.org# Collect all non-global variables 6096121Snate@binkert.org# 6106121Snate@binkert.org 6115397Ssaidi@eecs.umich.edu# Define the universe of supported ISAs 6121851SN/Aall_isa_list = [ ] 6131851SN/AExport('all_isa_list') 6147739Sgblack@eecs.umich.edu 615955SN/A# Define the universe of supported CPU models 6163053Sstever@eecs.umich.eduall_cpu_list = [ ] 6176121Snate@binkert.orgdefault_cpus = [ ] 6183053Sstever@eecs.umich.eduExport('all_cpu_list', 'default_cpus') 6193053Sstever@eecs.umich.edu 6203053Sstever@eecs.umich.edu# Sticky variables get saved in the variables file so they persist from 6213053Sstever@eecs.umich.edu# one invocation to the next (unless overridden, in which case the new 6223053Sstever@eecs.umich.edu# value becomes sticky). 6239072Sandreas.hansson@arm.comsticky_vars = Variables(args=ARGUMENTS) 6243053Sstever@eecs.umich.eduExport('sticky_vars') 6254742Sstever@eecs.umich.edu 6264742Sstever@eecs.umich.edu# Sticky variables that should be exported 6273053Sstever@eecs.umich.eduexport_vars = [] 6283053Sstever@eecs.umich.eduExport('export_vars') 6293053Sstever@eecs.umich.edu 6308960Ssteve.reinhardt@amd.com# Non-sticky variables only apply to the current build. 6316654Snate@binkert.orgnonsticky_vars = Variables(args=ARGUMENTS) 6323053Sstever@eecs.umich.eduExport('nonsticky_vars') 6333053Sstever@eecs.umich.edu 6343053Sstever@eecs.umich.edu# Walk the tree and execute all SConsopts scripts that wil add to the 6353053Sstever@eecs.umich.edu# above variables 6362667Sstever@eecs.umich.edufor bdir in [ base_dir ] + extras_dir_list: 6374554Sbinkertn@umich.edu for root, dirs, files in os.walk(bdir): 6386121Snate@binkert.org if 'SConsopts' in files: 6392667Sstever@eecs.umich.edu print "Reading", joinpath(root, 'SConsopts') 6404554Sbinkertn@umich.edu SConscript(joinpath(root, 'SConsopts')) 6414554Sbinkertn@umich.edu 6424554Sbinkertn@umich.eduall_isa_list.sort() 6436121Snate@binkert.orgall_cpu_list.sort() 6444554Sbinkertn@umich.edudefault_cpus.sort() 6454554Sbinkertn@umich.edu 6464554Sbinkertn@umich.edusticky_vars.AddVariables( 6474781Snate@binkert.org EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), 6484554Sbinkertn@umich.edu BoolVariable('FULL_SYSTEM', 'Full-system support', False), 6494554Sbinkertn@umich.edu ListVariable('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list), 6502667Sstever@eecs.umich.edu BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False), 6514554Sbinkertn@umich.edu BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging', 6524554Sbinkertn@umich.edu False), 6534554Sbinkertn@umich.edu BoolVariable('FAST_ALLOC_STATS', 'Enable fast object allocator statistics', 6544554Sbinkertn@umich.edu False), 6552667Sstever@eecs.umich.edu BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger', 6564554Sbinkertn@umich.edu False), 6572667Sstever@eecs.umich.edu BoolVariable('SS_COMPATIBLE_FP', 6584554Sbinkertn@umich.edu 'Make floating-point results compatible with SimpleScalar', 6596121Snate@binkert.org False), 6602667Sstever@eecs.umich.edu BoolVariable('USE_SSE2', 6615522Snate@binkert.org 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', 6625522Snate@binkert.org False), 6635522Snate@binkert.org BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql), 6645522Snate@binkert.org BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), 6655522Snate@binkert.org BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False), 6665522Snate@binkert.org BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), 6675522Snate@binkert.org ) 6685522Snate@binkert.org 6695522Snate@binkert.orgnonsticky_vars.AddVariables( 6705522Snate@binkert.org BoolVariable('update_ref', 'Update test reference outputs', False) 6715522Snate@binkert.org ) 6725522Snate@binkert.org 6735522Snate@binkert.org# These variables get exported to #defines in config/*.hh (see src/SConscript). 6745522Snate@binkert.orgexport_vars += ['FULL_SYSTEM', 'USE_FENV', 'USE_MYSQL', 6755522Snate@binkert.org 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', 'FAST_ALLOC_STATS', 6765522Snate@binkert.org 'SS_COMPATIBLE_FP', 'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE'] 6775522Snate@binkert.org 6785522Snate@binkert.org################################################### 6795522Snate@binkert.org# 6805522Snate@binkert.org# Define a SCons builder for configuration flag headers. 6815522Snate@binkert.org# 6825522Snate@binkert.org################################################### 6835522Snate@binkert.org 6845522Snate@binkert.org# This function generates a config header file that #defines the 6855522Snate@binkert.org# variable symbol to the current variable setting (0 or 1). The source 6865522Snate@binkert.org# operands are the name of the variable and a Value node containing the 6872638Sstever@eecs.umich.edu# value of the variable. 6882638Sstever@eecs.umich.edudef build_config_file(target, source, env): 6896121Snate@binkert.org (variable, value) = [s.get_contents() for s in source] 6903716Sstever@eecs.umich.edu f = file(str(target[0]), 'w') 6915522Snate@binkert.org print >> f, '#define', variable, value 6925522Snate@binkert.org f.close() 6935522Snate@binkert.org return None 6945522Snate@binkert.org 6955522Snate@binkert.org# Generate the message to be printed when building the config file. 6965522Snate@binkert.orgdef build_config_file_string(target, source, env): 6971858SN/A (variable, value) = [s.get_contents() for s in source] 6985227Ssaidi@eecs.umich.edu return "Defining %s as %s in %s." % (variable, value, target[0]) 6995227Ssaidi@eecs.umich.edu 7005227Ssaidi@eecs.umich.edu# Combine the two functions into a scons Action object. 7015227Ssaidi@eecs.umich.educonfig_action = Action(build_config_file, build_config_file_string) 7026654Snate@binkert.org 7036654Snate@binkert.org# The emitter munges the source & target node lists to reflect what 7047769SAli.Saidi@ARM.com# we're really doing. 7057769SAli.Saidi@ARM.comdef config_emitter(target, source, env): 7067769SAli.Saidi@ARM.com # extract variable name from Builder arg 7077769SAli.Saidi@ARM.com variable = str(target[0]) 7085227Ssaidi@eecs.umich.edu # True target is config header file 7095227Ssaidi@eecs.umich.edu target = joinpath('config', variable.lower() + '.hh') 7105227Ssaidi@eecs.umich.edu val = env[variable] 7115204Sstever@gmail.com if isinstance(val, bool): 7125204Sstever@gmail.com # Force value to 0/1 7135204Sstever@gmail.com val = int(val) 7145204Sstever@gmail.com elif isinstance(val, str): 7155204Sstever@gmail.com val = '"' + val + '"' 7165204Sstever@gmail.com 7175204Sstever@gmail.com # Sources are variable name & value (packaged in SCons Value nodes) 7185204Sstever@gmail.com return ([target], [Value(variable), Value(val)]) 7195204Sstever@gmail.com 7205204Sstever@gmail.comconfig_builder = Builder(emitter = config_emitter, action = config_action) 7215204Sstever@gmail.com 7225204Sstever@gmail.commain.Append(BUILDERS = { 'ConfigFile' : config_builder }) 7235204Sstever@gmail.com 7245204Sstever@gmail.com# libelf build is shared across all configs in the build root. 7255204Sstever@gmail.commain.SConscript('ext/libelf/SConscript', 7265204Sstever@gmail.com variant_dir = joinpath(build_root, 'libelf')) 7275204Sstever@gmail.com 7286121Snate@binkert.org# gzstream build is shared across all configs in the build root. 7295204Sstever@gmail.commain.SConscript('ext/gzstream/SConscript', 7303118Sstever@eecs.umich.edu variant_dir = joinpath(build_root, 'gzstream')) 7313118Sstever@eecs.umich.edu 7323118Sstever@eecs.umich.edu################################################### 7333118Sstever@eecs.umich.edu# 7343118Sstever@eecs.umich.edu# This function is used to set up a directory with switching headers 7355863Snate@binkert.org# 7363118Sstever@eecs.umich.edu################################################### 7375863Snate@binkert.org 7383118Sstever@eecs.umich.edumain['ALL_ISA_LIST'] = all_isa_list 7397457Snate@binkert.orgdef make_switching_dir(dname, switch_headers, env): 7407457Snate@binkert.org # Generate the header. target[0] is the full path of the output 7415863Snate@binkert.org # header to generate. 'source' is a dummy variable, since we get the 7425863Snate@binkert.org # list of ISAs from env['ALL_ISA_LIST']. 7435863Snate@binkert.org def gen_switch_hdr(target, source, env): 7445863Snate@binkert.org fname = str(target[0]) 7455863Snate@binkert.org f = open(fname, 'w') 7465863Snate@binkert.org isa = env['TARGET_ISA'].lower() 7475863Snate@binkert.org print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 7486003Snate@binkert.org f.close() 7495863Snate@binkert.org 7505863Snate@binkert.org # String to print when generating header 7515863Snate@binkert.org def gen_switch_hdr_string(target, source, env): 7526120Snate@binkert.org return "Generating switch header " + str(target[0]) 7535863Snate@binkert.org 7545863Snate@binkert.org # Build SCons Action object. 'varlist' specifies env vars that this 7555863Snate@binkert.org # action depends on; when env['ALL_ISA_LIST'] changes these actions 7568655Sandreas.hansson@arm.com # should get re-executed. 7578655Sandreas.hansson@arm.com switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, 7588655Sandreas.hansson@arm.com varlist=['ALL_ISA_LIST']) 7598655Sandreas.hansson@arm.com 7608655Sandreas.hansson@arm.com # Instantiate actions for each header 7618655Sandreas.hansson@arm.com for hdr in switch_headers: 7628655Sandreas.hansson@arm.com env.Command(hdr, [], switch_hdr_action) 7638655Sandreas.hansson@arm.comExport('make_switching_dir') 7646120Snate@binkert.org 7655863Snate@binkert.org################################################### 7666121Snate@binkert.org# 7676121Snate@binkert.org# Define build environments for selected configurations. 7685863Snate@binkert.org# 7697727SAli.Saidi@ARM.com################################################### 7707727SAli.Saidi@ARM.com 7717727SAli.Saidi@ARM.comfor variant_path in variant_paths: 7727727SAli.Saidi@ARM.com print "Building in", variant_path 7737727SAli.Saidi@ARM.com 7747727SAli.Saidi@ARM.com # Make a copy of the build-root environment to use for this config. 7755863Snate@binkert.org env = main.Clone() 7763118Sstever@eecs.umich.edu env['BUILDDIR'] = variant_path 7775863Snate@binkert.org 7789239Sandreas.hansson@arm.com # variant_dir is the tail component of build path, and is used to 7793118Sstever@eecs.umich.edu # determine the build parameters (e.g., 'ALPHA_SE') 7803118Sstever@eecs.umich.edu (build_root, variant_dir) = splitpath(variant_path) 7815863Snate@binkert.org 7825863Snate@binkert.org # Set env variables according to the build directory config. 7835863Snate@binkert.org sticky_vars.files = [] 7845863Snate@binkert.org # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in 7853118Sstever@eecs.umich.edu # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke 7863483Ssaidi@eecs.umich.edu # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings. 7873494Ssaidi@eecs.umich.edu current_vars_file = joinpath(build_root, 'variables', variant_dir) 7883494Ssaidi@eecs.umich.edu if isfile(current_vars_file): 7893483Ssaidi@eecs.umich.edu sticky_vars.files.append(current_vars_file) 7903483Ssaidi@eecs.umich.edu print "Using saved variables file %s" % current_vars_file 7913483Ssaidi@eecs.umich.edu else: 7923053Sstever@eecs.umich.edu # Build dir-specific variables file doesn't exist. 7933053Sstever@eecs.umich.edu 7943918Ssaidi@eecs.umich.edu # Make sure the directory is there so we can create it later 7953053Sstever@eecs.umich.edu opt_dir = dirname(current_vars_file) 7963053Sstever@eecs.umich.edu if not isdir(opt_dir): 7973053Sstever@eecs.umich.edu mkdir(opt_dir) 7983053Sstever@eecs.umich.edu 7993053Sstever@eecs.umich.edu # Get default build variables from source tree. Variables are 8007840Snate@binkert.org # normally determined by name of $VARIANT_DIR, but can be 8017865Sgblack@eecs.umich.edu # overriden by 'default=' arg on command line. 8027865Sgblack@eecs.umich.edu default_vars_file = joinpath('build_opts', 8037865Sgblack@eecs.umich.edu ARGUMENTS.get('default', variant_dir)) 8047865Sgblack@eecs.umich.edu if isfile(default_vars_file): 8057865Sgblack@eecs.umich.edu sticky_vars.files.append(default_vars_file) 8067840Snate@binkert.org print "Variables file %s not found,\n using defaults in %s" \ 8079045SAli.Saidi@ARM.com % (current_vars_file, default_vars_file) 8089045SAli.Saidi@ARM.com else: 8099045SAli.Saidi@ARM.com print "Error: cannot find variables file %s or %s" \ 8109045SAli.Saidi@ARM.com % (current_vars_file, default_vars_file) 8119045SAli.Saidi@ARM.com Exit(1) 8129045SAli.Saidi@ARM.com 8139071Sandreas.hansson@arm.com # Apply current variable settings to env 8149071Sandreas.hansson@arm.com sticky_vars.Update(env) 8159045SAli.Saidi@ARM.com nonsticky_vars.Update(env) 8167840Snate@binkert.org 8177840Snate@binkert.org help_text += "\nSticky variables for %s:\n" % variant_dir \ 8187840Snate@binkert.org + sticky_vars.GenerateHelpText(env) \ 8191858SN/A + "\nNon-sticky variables for %s:\n" % variant_dir \ 8201858SN/A + nonsticky_vars.GenerateHelpText(env) 8211858SN/A 8221858SN/A # Process variable settings. 8231858SN/A 8241858SN/A if not have_fenv and env['USE_FENV']: 8255863Snate@binkert.org print "Warning: <fenv.h> not available; " \ 8265863Snate@binkert.org "forcing USE_FENV to False in", variant_dir + "." 8275863Snate@binkert.org env['USE_FENV'] = False 8285863Snate@binkert.org 8296121Snate@binkert.org if not env['USE_FENV']: 8301858SN/A print "Warning: No IEEE FP rounding mode control in", variant_dir + "." 8315863Snate@binkert.org print " FP results may deviate slightly from other platforms." 8325863Snate@binkert.org 8335863Snate@binkert.org if env['EFENCE']: 8345863Snate@binkert.org env.Append(LIBS=['efence']) 8355863Snate@binkert.org 8362139SN/A if env['USE_MYSQL']: 8374202Sbinkertn@umich.edu if not have_mysql: 8384202Sbinkertn@umich.edu print "Warning: MySQL not available; " \ 8392139SN/A "forcing USE_MYSQL to False in", variant_dir + "." 8406994Snate@binkert.org env['USE_MYSQL'] = False 8416994Snate@binkert.org else: 8426994Snate@binkert.org print "Compiling in", variant_dir, "with MySQL support." 8436994Snate@binkert.org env.ParseConfig(mysql_config_libs) 8446994Snate@binkert.org env.ParseConfig(mysql_config_include) 8456994Snate@binkert.org 8466994Snate@binkert.org # Save sticky variable settings back to current variables file 8476994Snate@binkert.org sticky_vars.Save(current_vars_file, env) 8486994Snate@binkert.org 8496994Snate@binkert.org if env['USE_SSE2']: 8506994Snate@binkert.org env.Append(CCFLAGS='-msse2') 8516994Snate@binkert.org 8526994Snate@binkert.org # The src/SConscript file sets up the build rules in 'env' according 8536994Snate@binkert.org # to the configured variables. It returns a list of environments, 8546994Snate@binkert.org # one for each variant build (debug, opt, etc.) 8556994Snate@binkert.org envList = SConscript('src/SConscript', variant_dir = variant_path, 8566994Snate@binkert.org exports = 'env') 8576994Snate@binkert.org 8586994Snate@binkert.org # Set up the regression tests for each build. 8596994Snate@binkert.org for e in envList: 8606994Snate@binkert.org SConscript('tests/SConscript', 8616994Snate@binkert.org variant_dir = joinpath(variant_path, 'tests', e.Label), 8626994Snate@binkert.org exports = { 'env' : e }, duplicate = False) 8636994Snate@binkert.org 8646994Snate@binkert.orgHelp(help_text) 8656994Snate@binkert.org