SConstruct revision 4202
1955SN/A# -*- mode:python -*- 2955SN/A 31762SN/A# Copyright (c) 2004-2005 The Regents of The University of Michigan 4955SN/A# All rights reserved. 5955SN/A# 6955SN/A# Redistribution and use in source and binary forms, with or without 7955SN/A# modification, are permitted provided that the following conditions are 8955SN/A# met: redistributions of source code must retain the above copyright 9955SN/A# notice, this list of conditions and the following disclaimer; 10955SN/A# redistributions in binary form must reproduce the above copyright 11955SN/A# notice, this list of conditions and the following disclaimer in the 12955SN/A# documentation and/or other materials provided with the distribution; 13955SN/A# neither the name of the copyright holders nor the names of its 14955SN/A# contributors may be used to endorse or promote products derived from 15955SN/A# this software without specific prior written permission. 16955SN/A# 17955SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18955SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19955SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20955SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21955SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22955SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23955SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24955SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25955SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26955SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27955SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu# 294762Snate@binkert.org# Authors: Steve Reinhardt 30955SN/A 315522Snate@binkert.org################################################### 326143Snate@binkert.org# 334762Snate@binkert.org# SCons top-level build description (SConstruct) file. 345522Snate@binkert.org# 35955SN/A# While in this directory ('m5'), just type 'scons' to build the default 365522Snate@binkert.org# configuration (see below), or type 'scons build/<CONFIG>/<binary>' 3711974Sgabeblack@google.com# to build some other configuration (e.g., 'build/ALPHA_FS/m5.opt' for 38955SN/A# the optimized full-system version). 395522Snate@binkert.org# 404202Sbinkertn@umich.edu# You can build M5 in a different directory as long as there is a 415742Snate@binkert.org# 'build/<CONFIG>' somewhere along the target path. The build system 42955SN/A# expects that all configs under the same build directory are being 434381Sbinkertn@umich.edu# built for the same host system. 444381Sbinkertn@umich.edu# 4512246Sgabeblack@google.com# Examples: 4612246Sgabeblack@google.com# 478334Snate@binkert.org# The following two commands are equivalent. The '-u' option tells 48955SN/A# scons to search up the directory tree for this SConstruct file. 49955SN/A# % cd <path-to-src>/m5 ; scons build/ALPHA_FS/m5.debug 504202Sbinkertn@umich.edu# % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug 51955SN/A# 524382Sbinkertn@umich.edu# The following two commands are equivalent and demonstrate building 534382Sbinkertn@umich.edu# in a directory outside of the source tree. The '-C' option tells 544382Sbinkertn@umich.edu# scons to chdir to the specified directory to find this SConstruct 556654Snate@binkert.org# file. 565517Snate@binkert.org# % cd <path-to-src>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug 578614Sgblack@eecs.umich.edu# % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug 587674Snate@binkert.org# 596143Snate@binkert.org# You can use 'scons -H' to print scons options. If you're in this 606143Snate@binkert.org# 'm5' directory (or use -u or -C to tell scons where to find this 616143Snate@binkert.org# file), you can use 'scons -h' to print all the M5-specific build 6212302Sgabeblack@google.com# options as well. 6312302Sgabeblack@google.com# 6412302Sgabeblack@google.com################################################### 6512302Sgabeblack@google.com 6612302Sgabeblack@google.comimport sys 6712302Sgabeblack@google.comimport os 6812302Sgabeblack@google.comimport subprocess 6912302Sgabeblack@google.com 7012302Sgabeblack@google.comfrom os.path import join as joinpath 7112302Sgabeblack@google.com 7212302Sgabeblack@google.com# Check for recent-enough Python and SCons versions. If your system's 7312302Sgabeblack@google.com# default installation of Python is not recent enough, you can use a 7412302Sgabeblack@google.com# non-default installation of the Python interpreter by either (1) 7512302Sgabeblack@google.com# rearranging your PATH so that scons finds the non-default 'python' 7612302Sgabeblack@google.com# first or (2) explicitly invoking an alternative interpreter on the 7712302Sgabeblack@google.com# scons script, e.g., "/usr/local/bin/python2.4 `which scons` [args]". 7812302Sgabeblack@google.comEnsurePythonVersion(2,4) 7912302Sgabeblack@google.com 8012302Sgabeblack@google.com# Ironically, SCons 0.96 dies if you give EnsureSconsVersion a 8112302Sgabeblack@google.com# 3-element version number. 8212302Sgabeblack@google.commin_scons_version = (0,96,91) 8312302Sgabeblack@google.comtry: 8412302Sgabeblack@google.com EnsureSConsVersion(*min_scons_version) 8512302Sgabeblack@google.comexcept: 8612302Sgabeblack@google.com print "Error checking current SCons version." 8712302Sgabeblack@google.com print "SCons", ".".join(map(str,min_scons_version)), "or greater required." 8812302Sgabeblack@google.com Exit(2) 8912302Sgabeblack@google.com 9012302Sgabeblack@google.com 9111983Sgabeblack@google.com# The absolute path to the current directory (where this file lives). 926143Snate@binkert.orgROOT = Dir('.').abspath 938233Snate@binkert.org 9412302Sgabeblack@google.com# Path to the M5 source tree. 956143Snate@binkert.orgSRCDIR = joinpath(ROOT, 'src') 966143Snate@binkert.org 9712302Sgabeblack@google.com# tell python where to find m5 python code 984762Snate@binkert.orgsys.path.append(joinpath(ROOT, 'src/python')) 996143Snate@binkert.org 1008233Snate@binkert.org################################################### 1018233Snate@binkert.org# 10212302Sgabeblack@google.com# Figure out which configurations to set up based on the path(s) of 10312302Sgabeblack@google.com# the target(s). 1046143Snate@binkert.org# 10512302Sgabeblack@google.com################################################### 10612302Sgabeblack@google.com 10712302Sgabeblack@google.com# Find default configuration & binary. 10812302Sgabeblack@google.comDefault(os.environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug')) 10912302Sgabeblack@google.com 11012302Sgabeblack@google.com# helper function: find last occurrence of element in list 11112302Sgabeblack@google.comdef rfind(l, elt, offs = -1): 11212302Sgabeblack@google.com for i in range(len(l)+offs, 0, -1): 11312302Sgabeblack@google.com if l[i] == elt: 11412302Sgabeblack@google.com return i 1158233Snate@binkert.org raise ValueError, "element not found" 1166143Snate@binkert.org 1176143Snate@binkert.org# helper function: compare dotted version numbers. 1186143Snate@binkert.org# E.g., compare_version('1.3.25', '1.4.1') 1196143Snate@binkert.org# returns -1, 0, 1 if v1 is <, ==, > v2 1206143Snate@binkert.orgdef compare_versions(v1, v2): 1216143Snate@binkert.org # Convert dotted strings to lists 1226143Snate@binkert.org v1 = map(int, v1.split('.')) 1236143Snate@binkert.org v2 = map(int, v2.split('.')) 1246143Snate@binkert.org # Compare corresponding elements of lists 1257065Snate@binkert.org for n1,n2 in zip(v1, v2): 1266143Snate@binkert.org if n1 < n2: return -1 1278233Snate@binkert.org if n1 > n2: return 1 1288233Snate@binkert.org # all corresponding values are equal... see if one has extra values 1298233Snate@binkert.org if len(v1) < len(v2): return -1 1308233Snate@binkert.org if len(v1) > len(v2): return 1 1318233Snate@binkert.org return 0 1328233Snate@binkert.org 1338233Snate@binkert.org# Each target must have 'build' in the interior of the path; the 1348233Snate@binkert.org# directory below this will determine the build parameters. For 1358233Snate@binkert.org# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we 1368233Snate@binkert.org# recognize that ALPHA_SE specifies the configuration because it 1378233Snate@binkert.org# follow 'build' in the bulid path. 1388233Snate@binkert.org 1398233Snate@binkert.org# Generate absolute paths to targets so we can see where the build dir is 1408233Snate@binkert.orgif COMMAND_LINE_TARGETS: 1418233Snate@binkert.org # Ask SCons which directory it was invoked from 1428233Snate@binkert.org launch_dir = GetLaunchDir() 1438233Snate@binkert.org # Make targets relative to invocation directory 1448233Snate@binkert.org abs_targets = map(lambda x: os.path.normpath(joinpath(launch_dir, str(x))), 1458233Snate@binkert.org COMMAND_LINE_TARGETS) 1468233Snate@binkert.orgelse: 1478233Snate@binkert.org # Default targets are relative to root of tree 1486143Snate@binkert.org abs_targets = map(lambda x: os.path.normpath(joinpath(ROOT, str(x))), 1496143Snate@binkert.org DEFAULT_TARGETS) 1506143Snate@binkert.org 1516143Snate@binkert.org 1526143Snate@binkert.org# Generate a list of the unique build roots and configs that the 1536143Snate@binkert.org# collected targets reference. 1549982Satgutier@umich.edubuild_paths = [] 1556143Snate@binkert.orgbuild_root = None 15612302Sgabeblack@google.comfor t in abs_targets: 15712302Sgabeblack@google.com path_dirs = t.split('/') 15812302Sgabeblack@google.com try: 15912302Sgabeblack@google.com build_top = rfind(path_dirs, 'build', -2) 16012302Sgabeblack@google.com except: 16112302Sgabeblack@google.com print "Error: no non-leaf 'build' dir found on target path", t 16212302Sgabeblack@google.com Exit(1) 16312302Sgabeblack@google.com this_build_root = joinpath('/',*path_dirs[:build_top+1]) 16411983Sgabeblack@google.com if not build_root: 16511983Sgabeblack@google.com build_root = this_build_root 16611983Sgabeblack@google.com else: 16712302Sgabeblack@google.com if this_build_root != build_root: 16812302Sgabeblack@google.com print "Error: build targets not under same build root\n"\ 16912302Sgabeblack@google.com " %s\n %s" % (build_root, this_build_root) 17012302Sgabeblack@google.com Exit(1) 17112302Sgabeblack@google.com build_path = joinpath('/',*path_dirs[:build_top+2]) 17212302Sgabeblack@google.com if build_path not in build_paths: 17311983Sgabeblack@google.com build_paths.append(build_path) 1746143Snate@binkert.org 17512305Sgabeblack@google.com################################################### 17612302Sgabeblack@google.com# 17712302Sgabeblack@google.com# Set up the default build environment. This environment is copied 17812302Sgabeblack@google.com# and modified according to each selected configuration. 1796143Snate@binkert.org# 1806143Snate@binkert.org################################################### 1816143Snate@binkert.org 1825522Snate@binkert.orgenv = Environment(ENV = os.environ, # inherit user's environment vars 1836143Snate@binkert.org ROOT = ROOT, 1846143Snate@binkert.org SRCDIR = SRCDIR) 1856143Snate@binkert.orgExport('env') 1869982Satgutier@umich.edu 18712302Sgabeblack@google.com#Parse CC/CXX early so that we use the correct compiler for 18812302Sgabeblack@google.com# to test for dependencies/versions/libraries/includes 18912302Sgabeblack@google.comif ARGUMENTS.get('CC', None): 1906143Snate@binkert.org env['CC'] = ARGUMENTS.get('CC') 1916143Snate@binkert.org 1926143Snate@binkert.orgif ARGUMENTS.get('CXX', None): 1936143Snate@binkert.org env['CXX'] = ARGUMENTS.get('CXX') 1945522Snate@binkert.org 1955522Snate@binkert.orgenv.SConsignFile(joinpath(build_root,"sconsign")) 1965522Snate@binkert.org 1975522Snate@binkert.org# Default duplicate option is to use hard links, but this messes up 1985604Snate@binkert.org# when you use emacs to edit a file in the target dir, as emacs moves 1995604Snate@binkert.org# file to file~ then copies to file, breaking the link. Symbolic 2006143Snate@binkert.org# (soft) links work better. 2016143Snate@binkert.orgenv.SetOption('duplicate', 'soft-copy') 2024762Snate@binkert.org 2034762Snate@binkert.org# I waffle on this setting... it does avoid a few painful but 2046143Snate@binkert.org# unnecessary builds, but it also seems to make trivial builds take 2056727Ssteve.reinhardt@amd.com# noticeably longer. 2066727Ssteve.reinhardt@amd.comif False: 2076727Ssteve.reinhardt@amd.com env.TargetSignatures('content') 2084762Snate@binkert.org 2096143Snate@binkert.org# M5_PLY is used by isa_parser.py to find the PLY package. 2106143Snate@binkert.orgenv.Append(ENV = { 'M5_PLY' : Dir('ext/ply') }) 2116143Snate@binkert.orgenv['GCC'] = False 2126143Snate@binkert.orgenv['SUNCC'] = False 2136727Ssteve.reinhardt@amd.comenv['ICC'] = False 2146143Snate@binkert.orgenv['GCC'] = subprocess.Popen(env['CXX'] + ' --version', shell=True, 2157674Snate@binkert.org stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 2167674Snate@binkert.org close_fds=True).communicate()[0].find('GCC') >= 0 2175604Snate@binkert.orgenv['SUNCC'] = subprocess.Popen(env['CXX'] + ' -V', shell=True, 2186143Snate@binkert.org stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 2196143Snate@binkert.org close_fds=True).communicate()[0].find('Sun C++') >= 0 2206143Snate@binkert.orgenv['ICC'] = subprocess.Popen(env['CXX'] + ' -V', shell=True, 2214762Snate@binkert.org stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 2226143Snate@binkert.org close_fds=True).communicate()[0].find('Intel') >= 0 2234762Snate@binkert.orgif env['GCC'] + env['SUNCC'] + env['ICC'] > 1: 2244762Snate@binkert.org print 'Error: How can we have two at the same time?' 2254762Snate@binkert.org Exit(1) 2266143Snate@binkert.org 2276143Snate@binkert.org 2284762Snate@binkert.org# Set up default C++ compiler flags 22912302Sgabeblack@google.comif env['GCC']: 23012302Sgabeblack@google.com env.Append(CCFLAGS='-pipe') 2318233Snate@binkert.org env.Append(CCFLAGS='-fno-strict-aliasing') 23212302Sgabeblack@google.com env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef')) 2336143Snate@binkert.orgelif env['ICC']: 2346143Snate@binkert.org pass #Fix me... add warning flags once we clean up icc warnings 2354762Snate@binkert.orgelif env['SUNCC']: 2366143Snate@binkert.org env.Append(CCFLAGS='-Qoption ccfe') 2374762Snate@binkert.org env.Append(CCFLAGS='-features=gcc') 2389396Sandreas.hansson@arm.com env.Append(CCFLAGS='-features=extensions') 2399396Sandreas.hansson@arm.com env.Append(CCFLAGS='-library=stlport4') 2409396Sandreas.hansson@arm.com env.Append(CCFLAGS='-xar') 24112302Sgabeblack@google.com# env.Append(CCFLAGS='-instances=semiexplicit') 24212302Sgabeblack@google.comelse: 24312302Sgabeblack@google.com print 'Error: Don\'t know what compiler options to use for your compiler.' 2449396Sandreas.hansson@arm.com print ' Please fix SConstruct and src/SConscript and try again.' 2459396Sandreas.hansson@arm.com Exit(1) 2469396Sandreas.hansson@arm.com 2479396Sandreas.hansson@arm.comif sys.platform == 'cygwin': 2489396Sandreas.hansson@arm.com # cygwin has some header file issues... 2499396Sandreas.hansson@arm.com env.Append(CCFLAGS=Split("-Wno-uninitialized")) 2509396Sandreas.hansson@arm.comenv.Append(CPPPATH=[Dir('ext/dnet')]) 2519930Sandreas.hansson@arm.com 2529930Sandreas.hansson@arm.com# Check for SWIG 2539396Sandreas.hansson@arm.comif not env.has_key('SWIG'): 2548235Snate@binkert.org print 'Error: SWIG utility not found.' 2558235Snate@binkert.org print ' Please install (see http://www.swig.org) and retry.' 2566143Snate@binkert.org Exit(1) 2578235Snate@binkert.org 2589003SAli.Saidi@ARM.com# Check for appropriate SWIG version 2598235Snate@binkert.orgswig_version = os.popen('swig -version').read().split() 2608235Snate@binkert.org# First 3 words should be "SWIG Version x.y.z" 26112302Sgabeblack@google.comif swig_version[0] != 'SWIG' or swig_version[1] != 'Version': 2628235Snate@binkert.org print 'Error determining SWIG version.' 26312302Sgabeblack@google.com Exit(1) 2648235Snate@binkert.org 2658235Snate@binkert.orgmin_swig_version = '1.3.28' 26612302Sgabeblack@google.comif compare_versions(swig_version[2], min_swig_version) < 0: 2678235Snate@binkert.org print 'Error: SWIG version', min_swig_version, 'or newer required.' 2688235Snate@binkert.org print ' Installed version:', swig_version[2] 2698235Snate@binkert.org Exit(1) 2708235Snate@binkert.org 2719003SAli.Saidi@ARM.com# Set up SWIG flags & scanner 2728235Snate@binkert.orgenv.Append(SWIGFLAGS=Split('-c++ -python -modern $_CPPINCFLAGS')) 2735584Snate@binkert.org 2744382Sbinkertn@umich.eduimport SCons.Scanner 2754202Sbinkertn@umich.edu 2764382Sbinkertn@umich.eduswig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")' 2774382Sbinkertn@umich.edu 2789396Sandreas.hansson@arm.comswig_scanner = SCons.Scanner.ClassicCPP("SwigScan", ".i", "CPPPATH", 2795584Snate@binkert.org swig_inc_re) 2804382Sbinkertn@umich.edu 2814382Sbinkertn@umich.eduenv.Append(SCANNERS = swig_scanner) 2824382Sbinkertn@umich.edu 2838232Snate@binkert.org# Platform-specific configuration. Note again that we assume that all 2845192Ssaidi@eecs.umich.edu# builds under a given build root run on the same host platform. 2858232Snate@binkert.orgconf = Configure(env, 2868232Snate@binkert.org conf_dir = joinpath(build_root, '.scons_config'), 2878232Snate@binkert.org log_file = joinpath(build_root, 'scons_config.log')) 2885192Ssaidi@eecs.umich.edu 2898232Snate@binkert.org# Find Python include and library directories for embedding the 2905192Ssaidi@eecs.umich.edu# interpreter. For consistency, we will use the same Python 2915799Snate@binkert.org# installation used to run scons (and thus this script). If you want 2928232Snate@binkert.org# to link in an alternate version, see above for instructions on how 2935192Ssaidi@eecs.umich.edu# to invoke scons with a different copy of the Python interpreter. 2945192Ssaidi@eecs.umich.edu 2955192Ssaidi@eecs.umich.edu# Get brief Python version name (e.g., "python2.4") for locating 2968232Snate@binkert.org# include & library files 2975192Ssaidi@eecs.umich.edupy_version_name = 'python' + sys.version[:3] 2988232Snate@binkert.org 2995192Ssaidi@eecs.umich.edu# include path, e.g. /usr/local/include/python2.4 3005192Ssaidi@eecs.umich.edupy_header_path = joinpath(sys.exec_prefix, 'include', py_version_name) 3015192Ssaidi@eecs.umich.eduenv.Append(CPPPATH = py_header_path) 3025192Ssaidi@eecs.umich.edu# verify that it works 3034382Sbinkertn@umich.eduif not conf.CheckHeader('Python.h', '<>'): 3044382Sbinkertn@umich.edu print "Error: can't find Python.h header in", py_header_path 3054382Sbinkertn@umich.edu Exit(1) 3062667Sstever@eecs.umich.edu 3072667Sstever@eecs.umich.edu# add library path too if it's not in the default place 3082667Sstever@eecs.umich.edupy_lib_path = None 3092667Sstever@eecs.umich.eduif sys.exec_prefix != '/usr': 3102667Sstever@eecs.umich.edu py_lib_path = joinpath(sys.exec_prefix, 'lib') 3112667Sstever@eecs.umich.eduelif sys.platform == 'cygwin': 3125742Snate@binkert.org # cygwin puts the .dll in /bin for some reason 3135742Snate@binkert.org py_lib_path = '/bin' 3145742Snate@binkert.orgif py_lib_path: 3155793Snate@binkert.org env.Append(LIBPATH = py_lib_path) 3168334Snate@binkert.org print 'Adding', py_lib_path, 'to LIBPATH for', py_version_name 3175793Snate@binkert.orgif not conf.CheckLib(py_version_name): 3185793Snate@binkert.org print "Error: can't find Python library", py_version_name 3195793Snate@binkert.org Exit(1) 3204382Sbinkertn@umich.edu 3214762Snate@binkert.org# On Solaris you need to use libsocket for socket ops 3225344Sstever@gmail.comif not conf.CheckLibWithHeader(None, 'sys/socket.h', 'C++', 'accept(0,0,0);'): 3234382Sbinkertn@umich.edu if not conf.CheckLibWithHeader('socket', 'sys/socket.h', 'C++', 'accept(0,0,0);'): 3245341Sstever@gmail.com print "Can't find library with socket calls (e.g. accept())" 3255742Snate@binkert.org Exit(1) 3265742Snate@binkert.org 3275742Snate@binkert.org# Check for zlib. If the check passes, libz will be automatically 3285742Snate@binkert.org# added to the LIBS environment variable. 3295742Snate@binkert.orgif not conf.CheckLibWithHeader('z', 'zlib.h', 'C++','zlibVersion();'): 3304762Snate@binkert.org print 'Error: did not find needed zlib compression library '\ 3315742Snate@binkert.org 'and/or zlib.h header file.' 3325742Snate@binkert.org print ' Please install zlib and try again.' 33311984Sgabeblack@google.com Exit(1) 3347722Sgblack@eecs.umich.edu 3355742Snate@binkert.org# Check for <fenv.h> (C99 FP environment control) 3365742Snate@binkert.orghave_fenv = conf.CheckHeader('fenv.h', '<>') 3375742Snate@binkert.orgif not have_fenv: 3389930Sandreas.hansson@arm.com print "Warning: Header file <fenv.h> not found." 3399930Sandreas.hansson@arm.com print " This host has no IEEE FP rounding mode control." 3409930Sandreas.hansson@arm.com 3419930Sandreas.hansson@arm.com# Check for mysql. 3429930Sandreas.hansson@arm.commysql_config = WhereIs('mysql_config') 3435742Snate@binkert.orghave_mysql = mysql_config != None 3448242Sbradley.danofsky@amd.com 3458242Sbradley.danofsky@amd.com# Check MySQL version. 3468242Sbradley.danofsky@amd.comif have_mysql: 3478242Sbradley.danofsky@amd.com mysql_version = os.popen(mysql_config + ' --version').read() 3485341Sstever@gmail.com min_mysql_version = '4.1' 3495742Snate@binkert.org if compare_versions(mysql_version, min_mysql_version) < 0: 3507722Sgblack@eecs.umich.edu print 'Warning: MySQL', min_mysql_version, 'or newer required.' 3514773Snate@binkert.org print ' Version', mysql_version, 'detected.' 3526108Snate@binkert.org have_mysql = False 3531858SN/A 3541085SN/A# Set up mysql_config commands. 3556658Snate@binkert.orgif have_mysql: 3566658Snate@binkert.org mysql_config_include = mysql_config + ' --include' 3577673Snate@binkert.org if os.system(mysql_config_include + ' > /dev/null') != 0: 3586658Snate@binkert.org # older mysql_config versions don't support --include, use 3596658Snate@binkert.org # --cflags instead 36011308Santhony.gutierrez@amd.com mysql_config_include = mysql_config + ' --cflags | sed s/\\\'//g' 3616658Snate@binkert.org # This seems to work in all versions 36211308Santhony.gutierrez@amd.com mysql_config_libs = mysql_config + ' --libs' 3636658Snate@binkert.org 3646658Snate@binkert.orgenv = conf.Finish() 3657673Snate@binkert.org 3667673Snate@binkert.org# Define the universe of supported ISAs 3677673Snate@binkert.orgall_isa_list = [ ] 3687673Snate@binkert.orgExport('all_isa_list') 3697673Snate@binkert.org 3707673Snate@binkert.org# Define the universe of supported CPU models 3717673Snate@binkert.orgall_cpu_list = [ ] 37210467Sandreas.hansson@arm.comdefault_cpus = [ ] 3736658Snate@binkert.orgExport('all_cpu_list', 'default_cpus') 3747673Snate@binkert.org 37510467Sandreas.hansson@arm.com# Sticky options get saved in the options file so they persist from 37610467Sandreas.hansson@arm.com# one invocation to the next (unless overridden, in which case the new 37710467Sandreas.hansson@arm.com# value becomes sticky). 37810467Sandreas.hansson@arm.comsticky_opts = Options(args=ARGUMENTS) 37910467Sandreas.hansson@arm.comExport('sticky_opts') 38010467Sandreas.hansson@arm.com 38110467Sandreas.hansson@arm.com# Non-sticky options only apply to the current build. 38210467Sandreas.hansson@arm.comnonsticky_opts = Options(args=ARGUMENTS) 38310467Sandreas.hansson@arm.comExport('nonsticky_opts') 38410467Sandreas.hansson@arm.com 38510467Sandreas.hansson@arm.com# Walk the tree and execute all SConsopts scripts that wil add to the 3867673Snate@binkert.org# above options 3877673Snate@binkert.orgfor root, dirs, files in os.walk('.'): 3887673Snate@binkert.org if 'SConsopts' in files: 3897673Snate@binkert.org SConscript(os.path.join(root, 'SConsopts')) 3907673Snate@binkert.org 3919048SAli.Saidi@ARM.comall_isa_list.sort() 3927673Snate@binkert.orgall_cpu_list.sort() 3937673Snate@binkert.orgdefault_cpus.sort() 3947673Snate@binkert.org 3957673Snate@binkert.orgsticky_opts.AddOptions( 3966658Snate@binkert.org EnumOption('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list), 3977756SAli.Saidi@ARM.com BoolOption('FULL_SYSTEM', 'Full-system support', False), 3987816Ssteve.reinhardt@amd.com # There's a bug in scons 0.96.1 that causes ListOptions with list 3996658Snate@binkert.org # values (more than one value) not to be able to be restored from 40011308Santhony.gutierrez@amd.com # a saved option file. If this causes trouble then upgrade to 40111308Santhony.gutierrez@amd.com # scons 0.96.90 or later. 40211308Santhony.gutierrez@amd.com ListOption('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list), 40311308Santhony.gutierrez@amd.com BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False), 40411308Santhony.gutierrez@amd.com BoolOption('EFENCE', 'Link with Electric Fence malloc debugger', 40511308Santhony.gutierrez@amd.com False), 40611308Santhony.gutierrez@amd.com BoolOption('SS_COMPATIBLE_FP', 40711308Santhony.gutierrez@amd.com 'Make floating-point results compatible with SimpleScalar', 40811308Santhony.gutierrez@amd.com False), 40911308Santhony.gutierrez@amd.com BoolOption('USE_SSE2', 41011308Santhony.gutierrez@amd.com 'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts', 41111308Santhony.gutierrez@amd.com False), 41211308Santhony.gutierrez@amd.com BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql), 41311308Santhony.gutierrez@amd.com BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv), 41411308Santhony.gutierrez@amd.com BoolOption('USE_CHECKER', 'Use checker for detailed CPU models', False), 41511308Santhony.gutierrez@amd.com ('CC', 'C compiler', os.environ.get('CC', env['CC'])), 41611308Santhony.gutierrez@amd.com ('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])), 41711308Santhony.gutierrez@amd.com BoolOption('BATCH', 'Use batch pool for build and tests', False), 41811308Santhony.gutierrez@amd.com ('BATCH_CMD', 'Batch pool submission command name', 'qdo'), 41911308Santhony.gutierrez@amd.com ('PYTHONHOME', 42011308Santhony.gutierrez@amd.com 'Override the default PYTHONHOME for this system (use with caution)', 42111308Santhony.gutierrez@amd.com '%s:%s' % (sys.prefix, sys.exec_prefix)) 42211308Santhony.gutierrez@amd.com ) 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.comnonsticky_opts.AddOptions( 42511308Santhony.gutierrez@amd.com BoolOption('update_ref', 'Update test reference outputs', False) 42611308Santhony.gutierrez@amd.com ) 42711308Santhony.gutierrez@amd.com 42811308Santhony.gutierrez@amd.com# These options get exported to #defines in config/*.hh (see src/SConscript). 42911308Santhony.gutierrez@amd.comenv.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \ 43011308Santhony.gutierrez@amd.com 'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \ 43111308Santhony.gutierrez@amd.com 'USE_CHECKER', 'PYTHONHOME', 'TARGET_ISA'] 43211308Santhony.gutierrez@amd.com 43311308Santhony.gutierrez@amd.com# Define a handy 'no-op' action 43411308Santhony.gutierrez@amd.comdef no_action(target, source, env): 43511308Santhony.gutierrez@amd.com return 0 43611308Santhony.gutierrez@amd.com 43711308Santhony.gutierrez@amd.comenv.NoAction = Action(no_action, None) 43811308Santhony.gutierrez@amd.com 43911308Santhony.gutierrez@amd.com################################################### 44011308Santhony.gutierrez@amd.com# 44111308Santhony.gutierrez@amd.com# Define a SCons builder for configuration flag headers. 44211308Santhony.gutierrez@amd.com# 44311308Santhony.gutierrez@amd.com################################################### 44411308Santhony.gutierrez@amd.com 4454382Sbinkertn@umich.edu# This function generates a config header file that #defines the 4464382Sbinkertn@umich.edu# option symbol to the current option setting (0 or 1). The source 4474762Snate@binkert.org# operands are the name of the option and a Value node containing the 4484762Snate@binkert.org# value of the option. 4494762Snate@binkert.orgdef build_config_file(target, source, env): 4506654Snate@binkert.org (option, value) = [s.get_contents() for s in source] 4516654Snate@binkert.org f = file(str(target[0]), 'w') 4525517Snate@binkert.org print >> f, '#define', option, value 4535517Snate@binkert.org f.close() 4545517Snate@binkert.org return None 4555517Snate@binkert.org 4565517Snate@binkert.org# Generate the message to be printed when building the config file. 4575517Snate@binkert.orgdef build_config_file_string(target, source, env): 4585517Snate@binkert.org (option, value) = [s.get_contents() for s in source] 4595517Snate@binkert.org return "Defining %s as %s in %s." % (option, value, target[0]) 4605517Snate@binkert.org 4615517Snate@binkert.org# Combine the two functions into a scons Action object. 4625517Snate@binkert.orgconfig_action = Action(build_config_file, build_config_file_string) 4635517Snate@binkert.org 4645517Snate@binkert.org# The emitter munges the source & target node lists to reflect what 4655517Snate@binkert.org# we're really doing. 4665517Snate@binkert.orgdef config_emitter(target, source, env): 4675517Snate@binkert.org # extract option name from Builder arg 4685517Snate@binkert.org option = str(target[0]) 4696654Snate@binkert.org # True target is config header file 4705517Snate@binkert.org target = joinpath('config', option.lower() + '.hh') 4715517Snate@binkert.org val = env[option] 4725517Snate@binkert.org if isinstance(val, bool): 4735517Snate@binkert.org # Force value to 0/1 4745517Snate@binkert.org val = int(val) 47511802Sandreas.sandberg@arm.com elif isinstance(val, str): 4765517Snate@binkert.org val = '"' + val + '"' 4775517Snate@binkert.org 4786143Snate@binkert.org # Sources are option name & value (packaged in SCons Value nodes) 4796654Snate@binkert.org return ([target], [Value(option), Value(val)]) 4805517Snate@binkert.org 4815517Snate@binkert.orgconfig_builder = Builder(emitter = config_emitter, action = config_action) 4825517Snate@binkert.org 4835517Snate@binkert.orgenv.Append(BUILDERS = { 'ConfigFile' : config_builder }) 4845517Snate@binkert.org 4855517Snate@binkert.org################################################### 4865517Snate@binkert.org# 4875517Snate@binkert.org# Define a SCons builder for copying files. This is used by the 4885517Snate@binkert.org# Python zipfile code in src/python/SConscript, but is placed up here 4895517Snate@binkert.org# since it's potentially more generally applicable. 4905517Snate@binkert.org# 4915517Snate@binkert.org################################################### 4925517Snate@binkert.org 4935517Snate@binkert.orgcopy_builder = Builder(action = Copy("$TARGET", "$SOURCE")) 4946654Snate@binkert.org 4956654Snate@binkert.orgenv.Append(BUILDERS = { 'CopyFile' : copy_builder }) 4965517Snate@binkert.org 4975517Snate@binkert.org################################################### 4986143Snate@binkert.org# 4996143Snate@binkert.org# Define a simple SCons builder to concatenate files. 5006143Snate@binkert.org# 5016727Ssteve.reinhardt@amd.com# Used to append the Python zip archive to the executable. 5025517Snate@binkert.org# 5036727Ssteve.reinhardt@amd.com################################################### 5045517Snate@binkert.org 5055517Snate@binkert.orgconcat_builder = Builder(action = Action(['cat $SOURCES > $TARGET', 5065517Snate@binkert.org 'chmod +x $TARGET'])) 5076654Snate@binkert.org 5086654Snate@binkert.orgenv.Append(BUILDERS = { 'Concat' : concat_builder }) 5097673Snate@binkert.org 5106654Snate@binkert.org 5116654Snate@binkert.org# base help text 5126654Snate@binkert.orghelp_text = ''' 5136654Snate@binkert.orgUsage: scons [scons options] [build options] [target(s)] 5145517Snate@binkert.org 5155517Snate@binkert.org''' 5165517Snate@binkert.org 5176143Snate@binkert.org# libelf build is shared across all configs in the build root. 5185517Snate@binkert.orgenv.SConscript('ext/libelf/SConscript', 5194762Snate@binkert.org build_dir = joinpath(build_root, 'libelf'), 5205517Snate@binkert.org exports = 'env') 5215517Snate@binkert.org 5226143Snate@binkert.org################################################### 5236143Snate@binkert.org# 5245517Snate@binkert.org# This function is used to set up a directory with switching headers 5255517Snate@binkert.org# 5265517Snate@binkert.org################################################### 5275517Snate@binkert.org 5285517Snate@binkert.orgenv['ALL_ISA_LIST'] = all_isa_list 5295517Snate@binkert.orgdef make_switching_dir(dirname, switch_headers, env): 5305517Snate@binkert.org # Generate the header. target[0] is the full path of the output 5315517Snate@binkert.org # header to generate. 'source' is a dummy variable, since we get the 5325517Snate@binkert.org # list of ISAs from env['ALL_ISA_LIST']. 5336143Snate@binkert.org def gen_switch_hdr(target, source, env): 5345517Snate@binkert.org fname = str(target[0]) 5356654Snate@binkert.org basename = os.path.basename(fname) 5366654Snate@binkert.org f = open(fname, 'w') 5376654Snate@binkert.org f.write('#include "arch/isa_specific.hh"\n') 5386654Snate@binkert.org cond = '#if' 5396654Snate@binkert.org for isa in all_isa_list: 5406654Snate@binkert.org f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n' 5414762Snate@binkert.org % (cond, isa.upper(), dirname, isa, basename)) 5424762Snate@binkert.org cond = '#elif' 5434762Snate@binkert.org f.write('#else\n#error "THE_ISA not set"\n#endif\n') 5444762Snate@binkert.org f.close() 5454762Snate@binkert.org return 0 5467675Snate@binkert.org 54710584Sandreas.hansson@arm.com # String to print when generating header 5484762Snate@binkert.org def gen_switch_hdr_string(target, source, env): 5494762Snate@binkert.org return "Generating switch header " + str(target[0]) 5504762Snate@binkert.org 5514762Snate@binkert.org # Build SCons Action object. 'varlist' specifies env vars that this 5524382Sbinkertn@umich.edu # action depends on; when env['ALL_ISA_LIST'] changes these actions 5534382Sbinkertn@umich.edu # should get re-executed. 5545517Snate@binkert.org switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, 5556654Snate@binkert.org varlist=['ALL_ISA_LIST']) 5565517Snate@binkert.org 5578126Sgblack@eecs.umich.edu # Instantiate actions for each header 5586654Snate@binkert.org for hdr in switch_headers: 5597673Snate@binkert.org env.Command(hdr, [], switch_hdr_action) 5606654Snate@binkert.orgExport('make_switching_dir') 56111802Sandreas.sandberg@arm.com 5626654Snate@binkert.org################################################### 5636654Snate@binkert.org# 5646654Snate@binkert.org# Define build environments for selected configurations. 5656654Snate@binkert.org# 56611802Sandreas.sandberg@arm.com################################################### 5676669Snate@binkert.org 56811802Sandreas.sandberg@arm.com# rename base env 5696669Snate@binkert.orgbase_env = env 5706669Snate@binkert.org 5716669Snate@binkert.orgfor build_path in build_paths: 5726669Snate@binkert.org print "Building in", build_path 5736654Snate@binkert.org # build_dir is the tail component of build path, and is used to 5747673Snate@binkert.org # determine the build parameters (e.g., 'ALPHA_SE') 5755517Snate@binkert.org (build_root, build_dir) = os.path.split(build_path) 5768126Sgblack@eecs.umich.edu # Make a copy of the build-root environment to use for this config. 5775798Snate@binkert.org env = base_env.Copy() 5787756SAli.Saidi@ARM.com 5797816Ssteve.reinhardt@amd.com # Set env options according to the build directory config. 5805798Snate@binkert.org sticky_opts.files = [] 5815798Snate@binkert.org # Options for $BUILD_ROOT/$BUILD_DIR are stored in 5825517Snate@binkert.org # $BUILD_ROOT/options/$BUILD_DIR so you can nuke 5835517Snate@binkert.org # $BUILD_ROOT/$BUILD_DIR without losing your options settings. 5847673Snate@binkert.org current_opts_file = joinpath(build_root, 'options', build_dir) 5855517Snate@binkert.org if os.path.isfile(current_opts_file): 5865517Snate@binkert.org sticky_opts.files.append(current_opts_file) 5877673Snate@binkert.org print "Using saved options file %s" % current_opts_file 5887673Snate@binkert.org else: 5895517Snate@binkert.org # Build dir-specific options file doesn't exist. 5905798Snate@binkert.org 5915798Snate@binkert.org # Make sure the directory is there so we can create it later 5928333Snate@binkert.org opt_dir = os.path.dirname(current_opts_file) 5937816Ssteve.reinhardt@amd.com if not os.path.isdir(opt_dir): 5945798Snate@binkert.org os.mkdir(opt_dir) 5955798Snate@binkert.org 5964762Snate@binkert.org # Get default build options from source tree. Options are 5974762Snate@binkert.org # normally determined by name of $BUILD_DIR, but can be 5984762Snate@binkert.org # overriden by 'default=' arg on command line. 5994762Snate@binkert.org default_opts_file = joinpath('build_opts', 6004762Snate@binkert.org ARGUMENTS.get('default', build_dir)) 6018596Ssteve.reinhardt@amd.com if os.path.isfile(default_opts_file): 6025517Snate@binkert.org sticky_opts.files.append(default_opts_file) 6035517Snate@binkert.org print "Options file %s not found,\n using defaults in %s" \ 60411997Sgabeblack@google.com % (current_opts_file, default_opts_file) 6055517Snate@binkert.org else: 6065517Snate@binkert.org print "Error: cannot find options file %s or %s" \ 6077673Snate@binkert.org % (current_opts_file, default_opts_file) 6088596Ssteve.reinhardt@amd.com Exit(1) 6097673Snate@binkert.org 6105517Snate@binkert.org # Apply current option settings to env 61110458Sandreas.hansson@arm.com sticky_opts.Update(env) 61210458Sandreas.hansson@arm.com nonsticky_opts.Update(env) 61310458Sandreas.hansson@arm.com 61410458Sandreas.hansson@arm.com help_text += "Sticky options for %s:\n" % build_dir \ 61510458Sandreas.hansson@arm.com + sticky_opts.GenerateHelpText(env) \ 61610458Sandreas.hansson@arm.com + "\nNon-sticky options for %s:\n" % build_dir \ 61710458Sandreas.hansson@arm.com + nonsticky_opts.GenerateHelpText(env) 61810458Sandreas.hansson@arm.com 61910458Sandreas.hansson@arm.com # Process option settings. 62010458Sandreas.hansson@arm.com 62110458Sandreas.hansson@arm.com if not have_fenv and env['USE_FENV']: 62210458Sandreas.hansson@arm.com print "Warning: <fenv.h> not available; " \ 6235517Snate@binkert.org "forcing USE_FENV to False in", build_dir + "." 62411996Sgabeblack@google.com env['USE_FENV'] = False 6255517Snate@binkert.org 62611997Sgabeblack@google.com if not env['USE_FENV']: 62711996Sgabeblack@google.com print "Warning: No IEEE FP rounding mode control in", build_dir + "." 6285517Snate@binkert.org print " FP results may deviate slightly from other platforms." 6295517Snate@binkert.org 6307673Snate@binkert.org if env['EFENCE']: 6317673Snate@binkert.org env.Append(LIBS=['efence']) 63211996Sgabeblack@google.com 63311988Sandreas.sandberg@arm.com if env['USE_MYSQL']: 6347673Snate@binkert.org if not have_mysql: 6355517Snate@binkert.org print "Warning: MySQL not available; " \ 6368596Ssteve.reinhardt@amd.com "forcing USE_MYSQL to False in", build_dir + "." 6375517Snate@binkert.org env['USE_MYSQL'] = False 6385517Snate@binkert.org else: 63911997Sgabeblack@google.com print "Compiling in", build_dir, "with MySQL support." 6405517Snate@binkert.org env.ParseConfig(mysql_config_libs) 6415517Snate@binkert.org env.ParseConfig(mysql_config_include) 6427673Snate@binkert.org 6437673Snate@binkert.org # Save sticky option settings back to current options file 6447673Snate@binkert.org sticky_opts.Save(current_opts_file, env) 6455517Snate@binkert.org 64611988Sandreas.sandberg@arm.com # Do this after we save setting back, or else we'll tack on an 64711997Sgabeblack@google.com # extra 'qdo' every time we run scons. 6488596Ssteve.reinhardt@amd.com if env['BATCH']: 6498596Ssteve.reinhardt@amd.com env['CC'] = env['BATCH_CMD'] + ' ' + env['CC'] 6508596Ssteve.reinhardt@amd.com env['CXX'] = env['BATCH_CMD'] + ' ' + env['CXX'] 65111988Sandreas.sandberg@arm.com 6528596Ssteve.reinhardt@amd.com if env['USE_SSE2']: 6538596Ssteve.reinhardt@amd.com env.Append(CCFLAGS='-msse2') 6548596Ssteve.reinhardt@amd.com 6554762Snate@binkert.org # The src/SConscript file sets up the build rules in 'env' according 6566143Snate@binkert.org # to the configured options. It returns a list of environments, 6576143Snate@binkert.org # one for each variant build (debug, opt, etc.) 6586143Snate@binkert.org envList = SConscript('src/SConscript', build_dir = build_path, 6594762Snate@binkert.org exports = 'env') 6604762Snate@binkert.org 6614762Snate@binkert.org # Set up the regression tests for each build. 6627756SAli.Saidi@ARM.com for e in envList: 6638596Ssteve.reinhardt@amd.com SConscript('tests/SConscript', 6644762Snate@binkert.org build_dir = joinpath(build_path, 'tests', e.Label), 6654762Snate@binkert.org exports = { 'env' : e }, duplicate = False) 66610458Sandreas.hansson@arm.com 66710458Sandreas.hansson@arm.comHelp(help_text) 66810458Sandreas.hansson@arm.com 66910458Sandreas.hansson@arm.com 67010458Sandreas.hansson@arm.com################################################### 67110458Sandreas.hansson@arm.com# 67210458Sandreas.hansson@arm.com# Let SCons do its thing. At this point SCons will use the defined 67310458Sandreas.hansson@arm.com# build environments to build the requested targets. 67410458Sandreas.hansson@arm.com# 67510458Sandreas.hansson@arm.com################################################### 67610458Sandreas.hansson@arm.com 67710458Sandreas.hansson@arm.com