SConstruct revision 7739
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 ('M5_BUILD_CACHE', 'Cache built objects in this directory', False), 3162634Sstever@eecs.umich.edu ('EXTRAS', 'Add Extra directories to the compilation', '', 3175863Snate@binkert.org PathListAllExist, PathListMakeAbsolute), 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.com # Read the GCC version to check for versions with bugs 3665397Ssaidi@eecs.umich.edu # Note CCVERSION doesn't work here because it is run with the CC 3675397Ssaidi@eecs.umich.edu # before we override it from the command line 3687727SAli.Saidi@ARM.com gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False) 3698268Ssteve.reinhardt@amd.com if not compareVersions(gcc_version, '4.4.1') or \ 3706168Snate@binkert.org not compareVersions(gcc_version, '4.4.2'): 3715341Sstever@gmail.com print 'Info: Tree vectorizer in GCC 4.4.1 & 4.4.2 is buggy, disabling.' 3728120Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-fno-tree-vectorize']) 3738120Sgblack@eecs.umich.eduelif main['ICC']: 3748120Sgblack@eecs.umich.edu pass #Fix me... add warning flags once we clean up icc warnings 3756814Sgblack@eecs.umich.eduelif main['SUNCC']: 3765863Snate@binkert.org main.Append(CCFLAGS=['-Qoption ccfe']) 3778120Sgblack@eecs.umich.edu main.Append(CCFLAGS=['-features=gcc']) 3785341Sstever@gmail.com main.Append(CCFLAGS=['-features=extensions']) 3795863Snate@binkert.org main.Append(CCFLAGS=['-library=stlport4']) 3808268Ssteve.reinhardt@amd.com main.Append(CCFLAGS=['-xar']) 3816121Snate@binkert.org #main.Append(CCFLAGS=['-instances=semiexplicit']) 3826121Snate@binkert.orgelse: 3838268Ssteve.reinhardt@amd.com print 'Error: Don\'t know what compiler options to use for your compiler.' 3845742Snate@binkert.org print ' Please fix SConstruct and src/SConscript and try again.' 3855742Snate@binkert.org Exit(1) 3865341Sstever@gmail.com 3875742Snate@binkert.org# Set up common yacc/bison flags (needed for Ruby) 3885742Snate@binkert.orgmain['YACCFLAGS'] = '-d' 3895341Sstever@gmail.commain['YACCHXXFILESUFFIX'] = '.hh' 3906017Snate@binkert.org 3916121Snate@binkert.org# Do this after we save setting back, or else we'll tack on an 3926017Snate@binkert.org# extra 'qdo' every time we run scons. 3937816Ssteve.reinhardt@amd.comif main['BATCH']: 3947756SAli.Saidi@ARM.com main['CC'] = main['BATCH_CMD'] + ' ' + main['CC'] 3957756SAli.Saidi@ARM.com main['CXX'] = main['BATCH_CMD'] + ' ' + main['CXX'] 3967756SAli.Saidi@ARM.com main['AS'] = main['BATCH_CMD'] + ' ' + main['AS'] 3977756SAli.Saidi@ARM.com main['AR'] = main['BATCH_CMD'] + ' ' + main['AR'] 3987756SAli.Saidi@ARM.com main['RANLIB'] = main['BATCH_CMD'] + ' ' + main['RANLIB'] 3997756SAli.Saidi@ARM.com 4007756SAli.Saidi@ARM.comif sys.platform == 'cygwin': 4017756SAli.Saidi@ARM.com # cygwin has some header file issues... 4027816Ssteve.reinhardt@amd.com main.Append(CCFLAGS=["-Wno-uninitialized"]) 4037816Ssteve.reinhardt@amd.com 4047816Ssteve.reinhardt@amd.com# Check for SWIG 4057816Ssteve.reinhardt@amd.comif not main.has_key('SWIG'): 4067816Ssteve.reinhardt@amd.com print 'Error: SWIG utility not found.' 4077816Ssteve.reinhardt@amd.com print ' Please install (see http://www.swig.org) and retry.' 4087816Ssteve.reinhardt@amd.com Exit(1) 4097816Ssteve.reinhardt@amd.com 4107816Ssteve.reinhardt@amd.com# Check for appropriate SWIG version 4117816Ssteve.reinhardt@amd.comswig_version = readCommand(('swig', '-version'), exception='').split() 4127756SAli.Saidi@ARM.com# First 3 words should be "SWIG Version x.y.z" 4137816Ssteve.reinhardt@amd.comif len(swig_version) < 3 or \ 4147816Ssteve.reinhardt@amd.com swig_version[0] != 'SWIG' or swig_version[1] != 'Version': 4157816Ssteve.reinhardt@amd.com print 'Error determining SWIG version.' 4167816Ssteve.reinhardt@amd.com Exit(1) 4177816Ssteve.reinhardt@amd.com 4187816Ssteve.reinhardt@amd.commin_swig_version = '1.3.28' 4197816Ssteve.reinhardt@amd.comif compareVersions(swig_version[2], min_swig_version) < 0: 4207816Ssteve.reinhardt@amd.com print 'Error: SWIG version', min_swig_version, 'or newer required.' 4217816Ssteve.reinhardt@amd.com print ' Installed version:', swig_version[2] 4227816Ssteve.reinhardt@amd.com Exit(1) 4237816Ssteve.reinhardt@amd.com 4247816Ssteve.reinhardt@amd.com# Set up SWIG flags & scanner 4257816Ssteve.reinhardt@amd.comswig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS') 4267816Ssteve.reinhardt@amd.commain.Append(SWIGFLAGS=swig_flags) 4277816Ssteve.reinhardt@amd.com 4287816Ssteve.reinhardt@amd.com# filter out all existing swig scanners, they mess up the dependency 4297816Ssteve.reinhardt@amd.com# stuff for some reason 4307816Ssteve.reinhardt@amd.comscanners = [] 4317816Ssteve.reinhardt@amd.comfor scanner in main['SCANNERS']: 4327816Ssteve.reinhardt@amd.com skeys = scanner.skeys 4337816Ssteve.reinhardt@amd.com if skeys == '.i': 4347816Ssteve.reinhardt@amd.com continue 4357816Ssteve.reinhardt@amd.com 4367816Ssteve.reinhardt@amd.com if isinstance(skeys, (list, tuple)) and '.i' in skeys: 4377816Ssteve.reinhardt@amd.com continue 4387816Ssteve.reinhardt@amd.com 4397816Ssteve.reinhardt@amd.com scanners.append(scanner) 4407816Ssteve.reinhardt@amd.com 4417816Ssteve.reinhardt@amd.com# add the new swig scanner that we like better 4427816Ssteve.reinhardt@amd.comfrom SCons.Scanner import ClassicCPP as CPPScanner 4437816Ssteve.reinhardt@amd.comswig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")' 4447816Ssteve.reinhardt@amd.comscanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re)) 4457816Ssteve.reinhardt@amd.com 4467816Ssteve.reinhardt@amd.com# replace the scanners list that has what we want 4477816Ssteve.reinhardt@amd.commain['SCANNERS'] = scanners 4487816Ssteve.reinhardt@amd.com 4497816Ssteve.reinhardt@amd.com# Add a custom Check function to the Configure context so that we can 4507816Ssteve.reinhardt@amd.com# figure out if the compiler adds leading underscores to global 4517816Ssteve.reinhardt@amd.com# variables. This is needed for the autogenerated asm files that we 4527816Ssteve.reinhardt@amd.com# use for embedding the python code. 4537816Ssteve.reinhardt@amd.comdef CheckLeading(context): 4547816Ssteve.reinhardt@amd.com context.Message("Checking for leading underscore in global variables...") 4557816Ssteve.reinhardt@amd.com # 1) Define a global variable called x from asm so the C compiler 4567816Ssteve.reinhardt@amd.com # won't change the symbol at all. 4577816Ssteve.reinhardt@amd.com # 2) Declare that variable. 4587816Ssteve.reinhardt@amd.com # 3) Use the variable 4597816Ssteve.reinhardt@amd.com # 4607816Ssteve.reinhardt@amd.com # If the compiler prepends an underscore, this will successfully 4617816Ssteve.reinhardt@amd.com # link because the external symbol 'x' will be called '_x' which 4627816Ssteve.reinhardt@amd.com # was defined by the asm statement. If the compiler does not 4637816Ssteve.reinhardt@amd.com # prepend an underscore, this will not successfully link because 4647816Ssteve.reinhardt@amd.com # '_x' will have been defined by assembly, while the C portion of 4657816Ssteve.reinhardt@amd.com # the code will be trying to use 'x' 4667816Ssteve.reinhardt@amd.com ret = context.TryLink(''' 4677816Ssteve.reinhardt@amd.com asm(".globl _x; _x: .byte 0"); 4687816Ssteve.reinhardt@amd.com extern int x; 4697816Ssteve.reinhardt@amd.com int main() { return x; } 4707816Ssteve.reinhardt@amd.com ''', extension=".c") 4717816Ssteve.reinhardt@amd.com context.env.Append(LEADING_UNDERSCORE=ret) 4727816Ssteve.reinhardt@amd.com context.Result(ret) 4737816Ssteve.reinhardt@amd.com return ret 4748947Sandreas.hansson@arm.com 4758947Sandreas.hansson@arm.com# Platform-specific configuration. Note again that we assume that all 4767756SAli.Saidi@ARM.com# builds under a given build root run on the same host platform. 4778120Sgblack@eecs.umich.educonf = Configure(main, 4787756SAli.Saidi@ARM.com conf_dir = joinpath(build_root, '.scons_config'), 4797756SAli.Saidi@ARM.com log_file = joinpath(build_root, 'scons_config.log'), 4807756SAli.Saidi@ARM.com custom_tests = { 'CheckLeading' : CheckLeading }) 4817756SAli.Saidi@ARM.com 4827816Ssteve.reinhardt@amd.com# Check for leading underscores. Don't really need to worry either 4837816Ssteve.reinhardt@amd.com# way so don't need to check the return code. 4847816Ssteve.reinhardt@amd.comconf.CheckLeading() 4857816Ssteve.reinhardt@amd.com 4867816Ssteve.reinhardt@amd.com# Check if we should compile a 64 bit binary on Mac OS X/Darwin 4877816Ssteve.reinhardt@amd.comtry: 4887816Ssteve.reinhardt@amd.com import platform 4897816Ssteve.reinhardt@amd.com uname = platform.uname() 4907816Ssteve.reinhardt@amd.com if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0: 4917816Ssteve.reinhardt@amd.com if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]): 4927756SAli.Saidi@ARM.com main.Append(CCFLAGS=['-arch x86_64']) 4937756SAli.Saidi@ARM.com main.Append(CFLAGS=['-arch x86_64']) 4949227Sandreas.hansson@arm.com main.Append(LINKFLAGS=['-arch x86_64']) 4959227Sandreas.hansson@arm.com main.Append(ASFLAGS=['-arch x86_64']) 4969227Sandreas.hansson@arm.comexcept: 4979227Sandreas.hansson@arm.com pass 4986654Snate@binkert.org 4996654Snate@binkert.org# Recent versions of scons substitute a "Null" object for Configure() 5005871Snate@binkert.org# when configuration isn't necessary, e.g., if the "--help" option is 5016121Snate@binkert.org# present. Unfortuantely this Null object always returns false, 5026121Snate@binkert.org# breaking all our configuration checks. We replace it with our own 5036121Snate@binkert.org# more optimistic null object that returns True instead. 5048946Sandreas.hansson@arm.comif not conf: 5058737Skoansin.tan@gmail.com def NullCheck(*args, **kwargs): 5063940Ssaidi@eecs.umich.edu return True 5073918Ssaidi@eecs.umich.edu 5083918Ssaidi@eecs.umich.edu class NullConf: 5091858SN/A def __init__(self, env): 5106121Snate@binkert.org self.env = env 5117739Sgblack@eecs.umich.edu def Finish(self): 5127739Sgblack@eecs.umich.edu return self.env 5136143Snate@binkert.org def __getattr__(self, mname): 5147618SAli.Saidi@arm.com return NullCheck 5157618SAli.Saidi@arm.com 5167618SAli.Saidi@arm.com conf = NullConf(main) 5177618SAli.Saidi@arm.com 5188614Sgblack@eecs.umich.edu# Find Python include and library directories for embedding the 5197618SAli.Saidi@arm.com# interpreter. For consistency, we will use the same Python 5207618SAli.Saidi@arm.com# installation used to run scons (and thus this script). If you want 5217618SAli.Saidi@arm.com# to link in an alternate version, see above for instructions on how 5227739Sgblack@eecs.umich.edu# to invoke scons with a different copy of the Python interpreter. 5239224Sandreas.hansson@arm.comfrom distutils import sysconfig 5249224Sandreas.hansson@arm.com 5259224Sandreas.hansson@arm.compy_getvar = sysconfig.get_config_var 5268946Sandreas.hansson@arm.com 5279227Sandreas.hansson@arm.compy_debug = getattr(sys, 'pydebug', False) 5289227Sandreas.hansson@arm.compy_version = 'python' + py_getvar('VERSION') + (py_debug and "_d" or "") 5299227Sandreas.hansson@arm.com 5309227Sandreas.hansson@arm.compy_general_include = sysconfig.get_python_inc() 5319227Sandreas.hansson@arm.compy_platform_include = sysconfig.get_python_inc(plat_specific=True) 5329227Sandreas.hansson@arm.compy_includes = [ py_general_include ] 5339227Sandreas.hansson@arm.comif py_platform_include != py_general_include: 5349227Sandreas.hansson@arm.com py_includes.append(py_platform_include) 5359227Sandreas.hansson@arm.com 5369227Sandreas.hansson@arm.compy_lib_path = [ py_getvar('LIBDIR') ] 5379227Sandreas.hansson@arm.com# add the prefix/lib/pythonX.Y/config dir, but only if there is no 5389227Sandreas.hansson@arm.com# shared library in prefix/lib/. 5399227Sandreas.hansson@arm.comif not py_getvar('Py_ENABLE_SHARED'): 5409227Sandreas.hansson@arm.com py_lib_path.append(py_getvar('LIBPL')) 5419227Sandreas.hansson@arm.com 5429227Sandreas.hansson@arm.compy_libs = [] 5439227Sandreas.hansson@arm.comfor lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split(): 5449227Sandreas.hansson@arm.com assert lib.startswith('-l') 5456121Snate@binkert.org lib = lib[2:] 5463940Ssaidi@eecs.umich.edu if lib not in py_libs: 5476121Snate@binkert.org py_libs.append(lib) 5487739Sgblack@eecs.umich.edupy_libs.append(py_version) 5497739Sgblack@eecs.umich.edu 5507739Sgblack@eecs.umich.edumain.Append(CPPPATH=py_includes) 5517739Sgblack@eecs.umich.edumain.Append(LIBPATH=py_lib_path) 5527739Sgblack@eecs.umich.edu 5537739Sgblack@eecs.umich.edu# Cache build files in the supplied directory. 5548737Skoansin.tan@gmail.comif main['M5_BUILD_CACHE']: 5558737Skoansin.tan@gmail.com print 'Using build cache located at', main['M5_BUILD_CACHE'] 5568737Skoansin.tan@gmail.com CacheDir(main['M5_BUILD_CACHE']) 5578737Skoansin.tan@gmail.com 5588737Skoansin.tan@gmail.com 5598737Skoansin.tan@gmail.com# verify that this stuff works 5608737Skoansin.tan@gmail.comif not conf.CheckHeader('Python.h', '<>'): 5618737Skoansin.tan@gmail.com print "Error: can't find Python.h header in", py_includes 5628737Skoansin.tan@gmail.com Exit(1) 5638737Skoansin.tan@gmail.com 5648737Skoansin.tan@gmail.comfor lib in py_libs: 5658737Skoansin.tan@gmail.com if not conf.CheckLib(lib): 5668737Skoansin.tan@gmail.com print "Error: can't find library %s required by python" % lib 5678737Skoansin.tan@gmail.com Exit(1) 5688737Skoansin.tan@gmail.com 5698737Skoansin.tan@gmail.com# On Solaris you need to use libsocket for socket ops 5708737Skoansin.tan@gmail.comif not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): 5718737Skoansin.tan@gmail.com if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): 5728946Sandreas.hansson@arm.com print "Can't find library with socket calls (e.g. accept())" 5738946Sandreas.hansson@arm.com Exit(1) 5748946Sandreas.hansson@arm.com 5758946Sandreas.hansson@arm.com# Check for zlib. If the check passes, libz will be automatically 5769224Sandreas.hansson@arm.com# added to the LIBS environment variable. 5779224Sandreas.hansson@arm.comif not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'): 5788946Sandreas.hansson@arm.com print 'Error: did not find needed zlib compression library '\ 5798946Sandreas.hansson@arm.com 'and/or zlib.h header file.' 5803918Ssaidi@eecs.umich.edu print ' Please install zlib and try again.' 5819068SAli.Saidi@ARM.com Exit(1) 5829068SAli.Saidi@ARM.com 5839068SAli.Saidi@ARM.com# Check for <fenv.h> (C99 FP environment control) 5849068SAli.Saidi@ARM.comhave_fenv = conf.CheckHeader('fenv.h', '<>') 5859068SAli.Saidi@ARM.comif not have_fenv: 5869068SAli.Saidi@ARM.com print "Warning: Header file <fenv.h> not found." 5879068SAli.Saidi@ARM.com print " This host has no IEEE FP rounding mode control." 5889068SAli.Saidi@ARM.com 5899068SAli.Saidi@ARM.com###################################################################### 5909068SAli.Saidi@ARM.com# 5919068SAli.Saidi@ARM.com# Check for mysql. 5929068SAli.Saidi@ARM.com# 5939068SAli.Saidi@ARM.commysql_config = WhereIs('mysql_config') 5949068SAli.Saidi@ARM.comhave_mysql = bool(mysql_config) 5959068SAli.Saidi@ARM.com 5969068SAli.Saidi@ARM.com# Check MySQL version. 5973918Ssaidi@eecs.umich.eduif have_mysql: 5983918Ssaidi@eecs.umich.edu mysql_version = readCommand(mysql_config + ' --version') 5996157Snate@binkert.org min_mysql_version = '4.1' 6006157Snate@binkert.org if compareVersions(mysql_version, min_mysql_version) < 0: 6016157Snate@binkert.org print 'Warning: MySQL', min_mysql_version, 'or newer required.' 6026157Snate@binkert.org print ' Version', mysql_version, 'detected.' 6035397Ssaidi@eecs.umich.edu have_mysql = False 6045397Ssaidi@eecs.umich.edu 6056121Snate@binkert.org# Set up mysql_config commands. 6066121Snate@binkert.orgif have_mysql: 6076121Snate@binkert.org mysql_config_include = mysql_config + ' --include' 6086121Snate@binkert.org if os.system(mysql_config_include + ' > /dev/null') != 0: 6096121Snate@binkert.org # older mysql_config versions don't support --include, use 6106121Snate@binkert.org # --cflags instead 6115397Ssaidi@eecs.umich.edu mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g' 6121851SN/A # This seems to work in all versions 6131851SN/A mysql_config_libs = mysql_config + ' --libs' 6147739Sgblack@eecs.umich.edu 615955SN/A###################################################################### 6163053Sstever@eecs.umich.edu# 6176121Snate@binkert.org# Finish the configuration 6183053Sstever@eecs.umich.edu# 6193053Sstever@eecs.umich.edumain = conf.Finish() 6203053Sstever@eecs.umich.edu 6213053Sstever@eecs.umich.edu###################################################################### 6223053Sstever@eecs.umich.edu# 6239072Sandreas.hansson@arm.com# Collect all non-global variables 6243053Sstever@eecs.umich.edu# 6254742Sstever@eecs.umich.edu 6264742Sstever@eecs.umich.edu# Define the universe of supported ISAs 6273053Sstever@eecs.umich.eduall_isa_list = [ ] 6283053Sstever@eecs.umich.eduExport('all_isa_list') 6293053Sstever@eecs.umich.edu 6308960Ssteve.reinhardt@amd.comclass CpuModel(object): 6316654Snate@binkert.org '''The CpuModel class encapsulates everything the ISA parser needs to 6323053Sstever@eecs.umich.edu know about a particular CPU model.''' 6333053Sstever@eecs.umich.edu 6343053Sstever@eecs.umich.edu # Dict of available CPU model objects. Accessible as CpuModel.dict. 6353053Sstever@eecs.umich.edu dict = {} 6362667Sstever@eecs.umich.edu list = [] 6374554Sbinkertn@umich.edu defaults = [] 6386121Snate@binkert.org 6392667Sstever@eecs.umich.edu # Constructor. Automatically adds models to CpuModel.dict. 6404554Sbinkertn@umich.edu def __init__(self, name, filename, includes, strings, default=False): 6414554Sbinkertn@umich.edu self.name = name # name of model 6424554Sbinkertn@umich.edu self.filename = filename # filename for output exec code 6436121Snate@binkert.org self.includes = includes # include files needed in exec file 6444554Sbinkertn@umich.edu # The 'strings' dict holds all the per-CPU symbols we can 6454554Sbinkertn@umich.edu # substitute into templates etc. 6464554Sbinkertn@umich.edu self.strings = strings 6474781Snate@binkert.org 6484554Sbinkertn@umich.edu # This cpu is enabled by default 6494554Sbinkertn@umich.edu self.default = default 6502667Sstever@eecs.umich.edu 6514554Sbinkertn@umich.edu # Add self to dict 6524554Sbinkertn@umich.edu if name in CpuModel.dict: 6534554Sbinkertn@umich.edu raise AttributeError, "CpuModel '%s' already registered" % name 6544554Sbinkertn@umich.edu CpuModel.dict[name] = self 6552667Sstever@eecs.umich.edu CpuModel.list.append(name) 6564554Sbinkertn@umich.edu 6572667Sstever@eecs.umich.eduExport('CpuModel') 6584554Sbinkertn@umich.edu 6596121Snate@binkert.org# Sticky variables get saved in the variables file so they persist from 6602667Sstever@eecs.umich.edu# one invocation to the next (unless overridden, in which case the new 6615522Snate@binkert.org# value becomes sticky). 6625522Snate@binkert.orgsticky_vars = Variables(args=ARGUMENTS) 6635522Snate@binkert.orgExport('sticky_vars') 6645522Snate@binkert.org 6655522Snate@binkert.org# Sticky variables that should be exported 6665522Snate@binkert.orgexport_vars = [] 6675522Snate@binkert.orgExport('export_vars') 6685522Snate@binkert.org 6695522Snate@binkert.org# Non-sticky variables only apply to the current build. 6705522Snate@binkert.orgnonsticky_vars = Variables(args=ARGUMENTS) 6715522Snate@binkert.orgExport('nonsticky_vars') 6725522Snate@binkert.org 6735522Snate@binkert.org# Walk the tree and execute all SConsopts scripts that wil add to the 6745522Snate@binkert.org# above variables 6755522Snate@binkert.orgfor bdir in [ base_dir ] + extras_dir_list: 6765522Snate@binkert.org for root, dirs, files in os.walk(bdir): 6775522Snate@binkert.org if 'SConsopts' in files: 6785522Snate@binkert.org print "Reading", joinpath(root, 'SConsopts') 6795522Snate@binkert.org SConscript(joinpath(root, 'SConsopts')) 6805522Snate@binkert.org 6815522Snate@binkert.orgall_isa_list.sort() 6825522Snate@binkert.org 6835522Snate@binkert.orgsticky_vars.AddVariables( 6845522Snate@binkert.org EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), 6855522Snate@binkert.org BoolVariable('FULL_SYSTEM', 'Full-system support', False), 6865522Snate@binkert.org ListVariable('CPU_MODELS', 'CPU models', 6872638Sstever@eecs.umich.edu sorted(n for n,m in CpuModel.dict.iteritems() if m.default), 6882638Sstever@eecs.umich.edu sorted(CpuModel.list)), 6896121Snate@binkert.org BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False), 6903716Sstever@eecs.umich.edu BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging', 6915522Snate@binkert.org False), 6925522Snate@binkert.org BoolVariable('FAST_ALLOC_STATS', 'Enable fast object allocator statistics', 6935522Snate@binkert.org False), 6945522Snate@binkert.org BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger', 6955522Snate@binkert.org False), 6965522Snate@binkert.org BoolVariable('SS_COMPATIBLE_FP', 6971858SN/A 'Make floating-point results compatible with SimpleScalar', 6985227Ssaidi@eecs.umich.edu False), 6995227Ssaidi@eecs.umich.edu BoolVariable('USE_SSE2', 7005227Ssaidi@eecs.umich.edu 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', 7015227Ssaidi@eecs.umich.edu False), 7026654Snate@binkert.org BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql), 7036654Snate@binkert.org BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), 7047769SAli.Saidi@ARM.com BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False), 7057769SAli.Saidi@ARM.com BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False), 7067769SAli.Saidi@ARM.com BoolVariable('RUBY', 'Build with Ruby', False), 7077769SAli.Saidi@ARM.com ) 7085227Ssaidi@eecs.umich.edu 7095227Ssaidi@eecs.umich.edunonsticky_vars.AddVariables( 7105227Ssaidi@eecs.umich.edu BoolVariable('update_ref', 'Update test reference outputs', False) 7115204Sstever@gmail.com ) 7125204Sstever@gmail.com 7135204Sstever@gmail.com# These variables get exported to #defines in config/*.hh (see src/SConscript). 7145204Sstever@gmail.comexport_vars += ['FULL_SYSTEM', 'USE_FENV', 'USE_MYSQL', 7155204Sstever@gmail.com 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', 'FAST_ALLOC_STATS', 7165204Sstever@gmail.com 'SS_COMPATIBLE_FP', 'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE'] 7175204Sstever@gmail.com 7185204Sstever@gmail.com################################################### 7195204Sstever@gmail.com# 7205204Sstever@gmail.com# Define a SCons builder for configuration flag headers. 7215204Sstever@gmail.com# 7225204Sstever@gmail.com################################################### 7235204Sstever@gmail.com 7245204Sstever@gmail.com# This function generates a config header file that #defines the 7255204Sstever@gmail.com# variable symbol to the current variable setting (0 or 1). The source 7265204Sstever@gmail.com# operands are the name of the variable and a Value node containing the 7275204Sstever@gmail.com# value of the variable. 7286121Snate@binkert.orgdef build_config_file(target, source, env): 7295204Sstever@gmail.com (variable, value) = [s.get_contents() for s in source] 7303118Sstever@eecs.umich.edu f = file(str(target[0]), 'w') 7313118Sstever@eecs.umich.edu print >> f, '#define', variable, value 7323118Sstever@eecs.umich.edu f.close() 7333118Sstever@eecs.umich.edu return None 7343118Sstever@eecs.umich.edu 7355863Snate@binkert.org# Generate the message to be printed when building the config file. 7363118Sstever@eecs.umich.edudef build_config_file_string(target, source, env): 7375863Snate@binkert.org (variable, value) = [s.get_contents() for s in source] 7383118Sstever@eecs.umich.edu return "Defining %s as %s in %s." % (variable, value, target[0]) 7397457Snate@binkert.org 7407457Snate@binkert.org# Combine the two functions into a scons Action object. 7415863Snate@binkert.orgconfig_action = Action(build_config_file, build_config_file_string) 7425863Snate@binkert.org 7435863Snate@binkert.org# The emitter munges the source & target node lists to reflect what 7445863Snate@binkert.org# we're really doing. 7455863Snate@binkert.orgdef config_emitter(target, source, env): 7465863Snate@binkert.org # extract variable name from Builder arg 7475863Snate@binkert.org variable = str(target[0]) 7486003Snate@binkert.org # True target is config header file 7495863Snate@binkert.org target = joinpath('config', variable.lower() + '.hh') 7505863Snate@binkert.org val = env[variable] 7515863Snate@binkert.org if isinstance(val, bool): 7526120Snate@binkert.org # Force value to 0/1 7535863Snate@binkert.org val = int(val) 7545863Snate@binkert.org elif isinstance(val, str): 7555863Snate@binkert.org val = '"' + val + '"' 7568655Sandreas.hansson@arm.com 7578655Sandreas.hansson@arm.com # Sources are variable name & value (packaged in SCons Value nodes) 7588655Sandreas.hansson@arm.com return ([target], [Value(variable), Value(val)]) 7598655Sandreas.hansson@arm.com 7608655Sandreas.hansson@arm.comconfig_builder = Builder(emitter = config_emitter, action = config_action) 7618655Sandreas.hansson@arm.com 7628655Sandreas.hansson@arm.commain.Append(BUILDERS = { 'ConfigFile' : config_builder }) 7638655Sandreas.hansson@arm.com 7646120Snate@binkert.org# libelf build is shared across all configs in the build root. 7655863Snate@binkert.orgmain.SConscript('ext/libelf/SConscript', 7666121Snate@binkert.org variant_dir = joinpath(build_root, 'libelf')) 7676121Snate@binkert.org 7685863Snate@binkert.org# gzstream build is shared across all configs in the build root. 7697727SAli.Saidi@ARM.commain.SConscript('ext/gzstream/SConscript', 7707727SAli.Saidi@ARM.com variant_dir = joinpath(build_root, 'gzstream')) 7717727SAli.Saidi@ARM.com 7727727SAli.Saidi@ARM.com################################################### 7737727SAli.Saidi@ARM.com# 7747727SAli.Saidi@ARM.com# This function is used to set up a directory with switching headers 7755863Snate@binkert.org# 7763118Sstever@eecs.umich.edu################################################### 7775863Snate@binkert.org 7789239Sandreas.hansson@arm.commain['ALL_ISA_LIST'] = all_isa_list 7793118Sstever@eecs.umich.edudef make_switching_dir(dname, switch_headers, env): 7803118Sstever@eecs.umich.edu # Generate the header. target[0] is the full path of the output 7815863Snate@binkert.org # header to generate. 'source' is a dummy variable, since we get the 7825863Snate@binkert.org # list of ISAs from env['ALL_ISA_LIST']. 7835863Snate@binkert.org def gen_switch_hdr(target, source, env): 7845863Snate@binkert.org fname = str(target[0]) 7853118Sstever@eecs.umich.edu f = open(fname, 'w') 7863483Ssaidi@eecs.umich.edu isa = env['TARGET_ISA'].lower() 7873494Ssaidi@eecs.umich.edu print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname)) 7883494Ssaidi@eecs.umich.edu f.close() 7893483Ssaidi@eecs.umich.edu 7903483Ssaidi@eecs.umich.edu # String to print when generating header 7913483Ssaidi@eecs.umich.edu def gen_switch_hdr_string(target, source, env): 7923053Sstever@eecs.umich.edu return "Generating switch header " + str(target[0]) 7933053Sstever@eecs.umich.edu 7943918Ssaidi@eecs.umich.edu # Build SCons Action object. 'varlist' specifies env vars that this 7953053Sstever@eecs.umich.edu # action depends on; when env['ALL_ISA_LIST'] changes these actions 7963053Sstever@eecs.umich.edu # should get re-executed. 7973053Sstever@eecs.umich.edu switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, 7983053Sstever@eecs.umich.edu varlist=['ALL_ISA_LIST']) 7993053Sstever@eecs.umich.edu 8007840Snate@binkert.org # Instantiate actions for each header 8017865Sgblack@eecs.umich.edu for hdr in switch_headers: 8027865Sgblack@eecs.umich.edu env.Command(hdr, [], switch_hdr_action) 8037865Sgblack@eecs.umich.eduExport('make_switching_dir') 8047865Sgblack@eecs.umich.edu 8057865Sgblack@eecs.umich.edu################################################### 8067840Snate@binkert.org# 8079045SAli.Saidi@ARM.com# Define build environments for selected configurations. 8089045SAli.Saidi@ARM.com# 8099045SAli.Saidi@ARM.com################################################### 8109045SAli.Saidi@ARM.com 8119045SAli.Saidi@ARM.comfor variant_path in variant_paths: 8129045SAli.Saidi@ARM.com print "Building in", variant_path 8139071Sandreas.hansson@arm.com 8149071Sandreas.hansson@arm.com # Make a copy of the build-root environment to use for this config. 8159045SAli.Saidi@ARM.com env = main.Clone() 8167840Snate@binkert.org env['BUILDDIR'] = variant_path 8177840Snate@binkert.org 8187840Snate@binkert.org # variant_dir is the tail component of build path, and is used to 8191858SN/A # determine the build parameters (e.g., 'ALPHA_SE') 8201858SN/A (build_root, variant_dir) = splitpath(variant_path) 8211858SN/A 8221858SN/A # Set env variables according to the build directory config. 8231858SN/A sticky_vars.files = [] 8241858SN/A # Variables for $BUILD_ROOT/$VARIANT_DIR are stored in 8255863Snate@binkert.org # $BUILD_ROOT/variables/$VARIANT_DIR so you can nuke 8265863Snate@binkert.org # $BUILD_ROOT/$VARIANT_DIR without losing your variables settings. 8275863Snate@binkert.org current_vars_file = joinpath(build_root, 'variables', variant_dir) 8285863Snate@binkert.org if isfile(current_vars_file): 8296121Snate@binkert.org sticky_vars.files.append(current_vars_file) 8301858SN/A print "Using saved variables file %s" % current_vars_file 8315863Snate@binkert.org else: 8325863Snate@binkert.org # Build dir-specific variables file doesn't exist. 8335863Snate@binkert.org 8345863Snate@binkert.org # Make sure the directory is there so we can create it later 8355863Snate@binkert.org opt_dir = dirname(current_vars_file) 8362139SN/A if not isdir(opt_dir): 8374202Sbinkertn@umich.edu mkdir(opt_dir) 8384202Sbinkertn@umich.edu 8392139SN/A # Get default build variables from source tree. Variables are 8406994Snate@binkert.org # normally determined by name of $VARIANT_DIR, but can be 8416994Snate@binkert.org # overriden by 'default=' arg on command line. 8426994Snate@binkert.org default_vars_file = joinpath('build_opts', 8436994Snate@binkert.org ARGUMENTS.get('default', variant_dir)) 8446994Snate@binkert.org if isfile(default_vars_file): 8456994Snate@binkert.org sticky_vars.files.append(default_vars_file) 8466994Snate@binkert.org print "Variables file %s not found,\n using defaults in %s" \ 8476994Snate@binkert.org % (current_vars_file, default_vars_file) 8486994Snate@binkert.org else: 8496994Snate@binkert.org print "Error: cannot find variables file %s or %s" \ 8506994Snate@binkert.org % (current_vars_file, default_vars_file) 8516994Snate@binkert.org Exit(1) 8526994Snate@binkert.org 8536994Snate@binkert.org # Apply current variable settings to env 8546994Snate@binkert.org sticky_vars.Update(env) 8556994Snate@binkert.org nonsticky_vars.Update(env) 8566994Snate@binkert.org 8576994Snate@binkert.org help_text += "\nSticky variables for %s:\n" % variant_dir \ 8586994Snate@binkert.org + sticky_vars.GenerateHelpText(env) \ 8596994Snate@binkert.org + "\nNon-sticky variables for %s:\n" % variant_dir \ 8606994Snate@binkert.org + nonsticky_vars.GenerateHelpText(env) 8616994Snate@binkert.org 8626994Snate@binkert.org # Process variable settings. 8636994Snate@binkert.org 8646994Snate@binkert.org if not have_fenv and env['USE_FENV']: 8656994Snate@binkert.org print "Warning: <fenv.h> not available; " \ 8666994Snate@binkert.org "forcing USE_FENV to False in", variant_dir + "." 8676994Snate@binkert.org env['USE_FENV'] = False 8682155SN/A 8695863Snate@binkert.org if not env['USE_FENV']: 8701869SN/A print "Warning: No IEEE FP rounding mode control in", variant_dir + "." 8711869SN/A print " FP results may deviate slightly from other platforms." 8725863Snate@binkert.org 8735863Snate@binkert.org if env['EFENCE']: 8744202Sbinkertn@umich.edu env.Append(LIBS=['efence']) 8756108Snate@binkert.org 8766108Snate@binkert.org if env['USE_MYSQL']: 8776108Snate@binkert.org if not have_mysql: 8786108Snate@binkert.org print "Warning: MySQL not available; " \ 8799219Spower.jg@gmail.com "forcing USE_MYSQL to False in", variant_dir + "." 8809219Spower.jg@gmail.com env['USE_MYSQL'] = False 8819219Spower.jg@gmail.com else: 8829219Spower.jg@gmail.com print "Compiling in", variant_dir, "with MySQL support." 8839219Spower.jg@gmail.com env.ParseConfig(mysql_config_libs) 8849219Spower.jg@gmail.com env.ParseConfig(mysql_config_include) 8859219Spower.jg@gmail.com 8869219Spower.jg@gmail.com # Save sticky variable settings back to current variables file 8874202Sbinkertn@umich.edu sticky_vars.Save(current_vars_file, env) 8885863Snate@binkert.org 8898474Sgblack@eecs.umich.edu if env['USE_SSE2']: 8908474Sgblack@eecs.umich.edu env.Append(CCFLAGS=['-msse2']) 8915742Snate@binkert.org 8928268Ssteve.reinhardt@amd.com # The src/SConscript file sets up the build rules in 'env' according 8938268Ssteve.reinhardt@amd.com # to the configured variables. It returns a list of environments, 8948268Ssteve.reinhardt@amd.com # one for each variant build (debug, opt, etc.) 8955742Snate@binkert.org envList = SConscript('src/SConscript', variant_dir = variant_path, 8965341Sstever@gmail.com exports = 'env') 8978474Sgblack@eecs.umich.edu 8988474Sgblack@eecs.umich.edu # Set up the regression tests for each build. 8995342Sstever@gmail.com for e in envList: 9004202Sbinkertn@umich.edu SConscript('tests/SConscript', 9014202Sbinkertn@umich.edu variant_dir = joinpath(variant_path, 'tests', e.Label), 9024202Sbinkertn@umich.edu exports = { 'env' : e }, duplicate = False) 9035863Snate@binkert.org 9045863Snate@binkert.orgHelp(help_text) 9056994Snate@binkert.org