SConscript revision 4550
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# 292665Ssaidi@eecs.umich.edu# Authors: Steve Reinhardt 30955SN/A 31955SN/Aimport os 32955SN/Aimport sys 334382Sbinkertn@umich.eduimport zipfile 344202Sbinkertn@umich.edu 354382Sbinkertn@umich.edufrom os.path import basename 364202Sbinkertn@umich.edufrom os.path import join as joinpath 37955SN/A 384381Sbinkertn@umich.eduimport SCons 394381Sbinkertn@umich.edu 40955SN/A# This file defines how to build a particular configuration of M5 41955SN/A# based on variable settings in the 'env' build environment. 42955SN/A 434202Sbinkertn@umich.eduImport('*') 44955SN/A 454382Sbinkertn@umich.edu# Children need to see the environment 464382Sbinkertn@umich.eduExport('env') 474382Sbinkertn@umich.edu 484382Sbinkertn@umich.edu######################################################################## 494382Sbinkertn@umich.edu# Code for adding source files 504382Sbinkertn@umich.edu# 514202Sbinkertn@umich.edusources = [] 524381Sbinkertn@umich.edudef Source(source): 534381Sbinkertn@umich.edu if isinstance(source, SCons.Node.FS.File): 544381Sbinkertn@umich.edu sources.append(source) 554381Sbinkertn@umich.edu else: 564381Sbinkertn@umich.edu sources.append(File(source)) 57955SN/A 584382Sbinkertn@umich.edu# Children should have access 594202Sbinkertn@umich.eduExport('Source') 60955SN/A 614382Sbinkertn@umich.edu######################################################################## 624382Sbinkertn@umich.edu# Code for adding python objects 634382Sbinkertn@umich.edu# 644382Sbinkertn@umich.edupy_sources = [] 654382Sbinkertn@umich.edupy_source_packages = {} 664382Sbinkertn@umich.edudef PySource(package, source): 674382Sbinkertn@umich.edu if not isinstance(source, SCons.Node.FS.File): 684382Sbinkertn@umich.edu source = File(source) 694382Sbinkertn@umich.edu py_source_packages[source] = package 704382Sbinkertn@umich.edu py_sources.append(source) 714382Sbinkertn@umich.edu 724382Sbinkertn@umich.edusim_objects = [] 734382Sbinkertn@umich.edudef SimObject(source): 744382Sbinkertn@umich.edu if not isinstance(source, SCons.Node.FS.File): 754382Sbinkertn@umich.edu source = File(source) 764382Sbinkertn@umich.edu PySource('m5.objects', source) 774382Sbinkertn@umich.edu modname = basename(str(source)) 784382Sbinkertn@umich.edu sim_objects.append(modname) 794382Sbinkertn@umich.edu 804382Sbinkertn@umich.eduswig_sources = [] 814382Sbinkertn@umich.eduswig_source_packages = {} 824382Sbinkertn@umich.edudef SwigSource(package, source): 834382Sbinkertn@umich.edu if not isinstance(source, SCons.Node.FS.File): 844382Sbinkertn@umich.edu source = File(source) 854382Sbinkertn@umich.edu swig_source_packages[source] = package 864382Sbinkertn@umich.edu swig_sources.append(source) 874382Sbinkertn@umich.edu 884382Sbinkertn@umich.edu# Children should have access 894382Sbinkertn@umich.eduExport('PySource') 904382Sbinkertn@umich.eduExport('SimObject') 914382Sbinkertn@umich.eduExport('SwigSource') 924382Sbinkertn@umich.edu 934382Sbinkertn@umich.edu######################################################################## 944382Sbinkertn@umich.edu# 954382Sbinkertn@umich.edu# Set some compiler variables 964382Sbinkertn@umich.edu# 974382Sbinkertn@umich.edu 982667Sstever@eecs.umich.edu# Include file paths are rooted in this directory. SCons will 992667Sstever@eecs.umich.edu# automatically expand '.' to refer to both the source directory and 1002667Sstever@eecs.umich.edu# the corresponding build directory to pick up generated include 1012667Sstever@eecs.umich.edu# files. 1022667Sstever@eecs.umich.eduenv.Append(CPPPATH=Dir('.')) 1032667Sstever@eecs.umich.edu 1042037SN/A# Add a flag defining what THE_ISA should be for all compilation 1052037SN/Aenv.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) 1062037SN/A 1074382Sbinkertn@umich.edu######################################################################## 1084202Sbinkertn@umich.edu# Walk the tree and execute all SConscripts 1094382Sbinkertn@umich.edu# 1104202Sbinkertn@umich.eduscripts = [] 1114202Sbinkertn@umich.edusrcdir = env['SRCDIR'] 1124202Sbinkertn@umich.edufor root, dirs, files in os.walk(srcdir, topdown=True): 1134202Sbinkertn@umich.edu if root == srcdir: 1144202Sbinkertn@umich.edu # we don't want to recurse back into this SConscript 1154202Sbinkertn@umich.edu continue 1164202Sbinkertn@umich.edu 1174202Sbinkertn@umich.edu if 'SConscript' in files: 1184202Sbinkertn@umich.edu # strip off the srcdir part since scons will try to find the 1194202Sbinkertn@umich.edu # script in the build directory 1204202Sbinkertn@umich.edu base = root[len(srcdir) + 1:] 1214202Sbinkertn@umich.edu SConscript(joinpath(base, 'SConscript')) 1221858SN/A 1231858SN/Afor opt in env.ExportOptions: 1241858SN/A env.ConfigFile(opt) 1251085SN/A 1264382Sbinkertn@umich.edu######################################################################## 1274382Sbinkertn@umich.edu# 1284382Sbinkertn@umich.edu# Deal with python/swig, object code. Collect .py files and 1294382Sbinkertn@umich.edu# generating a zip archive that is appended to the m5 binary. 1304382Sbinkertn@umich.edu# 1314382Sbinkertn@umich.edu 1324382Sbinkertn@umich.edu# Generate Python file that contains a dict specifying the current 1334382Sbinkertn@umich.edu# build_env flags. 1344382Sbinkertn@umich.edudef MakeDefinesPyFile(target, source, env): 1354382Sbinkertn@umich.edu f = file(str(target[0]), 'w') 1364382Sbinkertn@umich.edu print >>f, "m5_build_env = ", source[0] 1374382Sbinkertn@umich.edu f.close() 1384382Sbinkertn@umich.edu 1394382Sbinkertn@umich.eduoptionDict = dict([(opt, env[opt]) for opt in env.ExportOptions]) 1404382Sbinkertn@umich.eduenv.Command('python/m5/defines.py', Value(optionDict), MakeDefinesPyFile) 1414382Sbinkertn@umich.eduPySource('m5', 'python/m5/defines.py') 1424382Sbinkertn@umich.edu 1434382Sbinkertn@umich.edudef MakeInfoPyFile(target, source, env): 1444382Sbinkertn@umich.edu f = file(str(target[0]), 'w') 1454382Sbinkertn@umich.edu for src in source: 1464382Sbinkertn@umich.edu data = ''.join(file(src.srcnode().abspath, 'r').xreadlines()) 1474382Sbinkertn@umich.edu print >>f, "%s = %s" % (src, repr(data)) 1484382Sbinkertn@umich.edu f.close() 1494382Sbinkertn@umich.edu 1504382Sbinkertn@umich.eduenv.Command('python/m5/info.py', 1514382Sbinkertn@umich.edu [ '#/AUTHORS', '#/LICENSE', '#/README', '#/RELEASE_NOTES' ], 1524382Sbinkertn@umich.edu MakeInfoPyFile) 1534382Sbinkertn@umich.eduPySource('m5', 'python/m5/info.py') 1544382Sbinkertn@umich.edu 1554382Sbinkertn@umich.edudef MakeObjectsInitFile(target, source, env): 1564382Sbinkertn@umich.edu f = file(str(target[0]), 'w') 1574382Sbinkertn@umich.edu print >>f, 'from m5.SimObject import *' 1584382Sbinkertn@umich.edu for src_path in source: 1594382Sbinkertn@umich.edu src_file = basename(src_path.get_contents()) 1604382Sbinkertn@umich.edu assert(src_file.endswith('.py')) 1614382Sbinkertn@umich.edu src_module = src_file[:-3] 1624382Sbinkertn@umich.edu print >>f, 'from %s import *' % src_module 1634382Sbinkertn@umich.edu f.close() 1644382Sbinkertn@umich.edu 1654382Sbinkertn@umich.eduenv.Command('python/m5/objects/__init__.py', 1664382Sbinkertn@umich.edu [ Value(o) for o in sim_objects], 1674382Sbinkertn@umich.edu MakeObjectsInitFile) 1684382Sbinkertn@umich.eduPySource('m5.objects', 'python/m5/objects/__init__.py') 1694382Sbinkertn@umich.edu 1704382Sbinkertn@umich.eduswig_modules = [] 1714382Sbinkertn@umich.edufor source in swig_sources: 1724382Sbinkertn@umich.edu source.rfile() # Hack to cause the symlink to the .i file to be created 1734382Sbinkertn@umich.edu package = swig_source_packages[source] 1744382Sbinkertn@umich.edu filename = str(source) 1754382Sbinkertn@umich.edu module = basename(filename) 1764382Sbinkertn@umich.edu 1774382Sbinkertn@umich.edu assert(module.endswith('.i')) 1784382Sbinkertn@umich.edu module = module[:-2] 1794382Sbinkertn@umich.edu cc_file = 'swig/%s_wrap.cc' % module 1804382Sbinkertn@umich.edu py_file = 'm5/internal/%s.py' % module 1814382Sbinkertn@umich.edu 1824382Sbinkertn@umich.edu env.Command([cc_file, py_file], source, 1834382Sbinkertn@umich.edu '$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' 1844382Sbinkertn@umich.edu '-o ${TARGETS[0]} $SOURCES') 1854382Sbinkertn@umich.edu env.Depends(py_file, source) 1864382Sbinkertn@umich.edu env.Depends(cc_file, source) 1874382Sbinkertn@umich.edu 1884382Sbinkertn@umich.edu swig_modules.append(Value(module)) 1894382Sbinkertn@umich.edu Source(cc_file) 1904382Sbinkertn@umich.edu PySource(package, py_file) 1914382Sbinkertn@umich.edu 1924382Sbinkertn@umich.edudef MakeSwigInit(target, source, env): 1934382Sbinkertn@umich.edu f = file(str(target[0]), 'w') 1944382Sbinkertn@umich.edu print >>f, 'extern "C" {' 1954382Sbinkertn@umich.edu for module in source: 1964382Sbinkertn@umich.edu print >>f, ' void init_%s();' % module.get_contents() 1974382Sbinkertn@umich.edu print >>f, '}' 1984382Sbinkertn@umich.edu print >>f, 'void init_swig() {' 1994382Sbinkertn@umich.edu for module in source: 2004382Sbinkertn@umich.edu print >>f, ' init_%s();' % module.get_contents() 2014382Sbinkertn@umich.edu print >>f, '}' 2024382Sbinkertn@umich.edu f.close() 2034382Sbinkertn@umich.eduenv.Command('python/swig/init.cc', swig_modules, MakeSwigInit) 2044382Sbinkertn@umich.edu 2054382Sbinkertn@umich.edudef CompilePyFile(target, source, env): 2064382Sbinkertn@umich.edu import py_compile 2074382Sbinkertn@umich.edu py_compile.compile(str(source[0]), str(target[0])) 2084382Sbinkertn@umich.edu 2094382Sbinkertn@umich.edupy_compiled = [] 2104382Sbinkertn@umich.edupy_arcname = {} 2114382Sbinkertn@umich.edupy_zip_depends = [] 2124382Sbinkertn@umich.edufor source in py_sources: 2134382Sbinkertn@umich.edu filename = str(source) 2144382Sbinkertn@umich.edu package = py_source_packages[source] 2154382Sbinkertn@umich.edu arc_path = package.split('.') + [ basename(filename) + 'c' ] 2164382Sbinkertn@umich.edu zip_path = [ 'zip' ] + arc_path 2174382Sbinkertn@umich.edu arcname = joinpath(*arc_path) 2184382Sbinkertn@umich.edu zipname = joinpath(*zip_path) 2194382Sbinkertn@umich.edu f = File(zipname) 2204382Sbinkertn@umich.edu 2214382Sbinkertn@umich.edu env.Command(f, source, CompilePyFile) 2224382Sbinkertn@umich.edu py_compiled.append(f) 2234382Sbinkertn@umich.edu py_arcname[f] = arcname 2244382Sbinkertn@umich.edu 2254382Sbinkertn@umich.edu # make the zipfile depend on the archive name so that the archive 2264382Sbinkertn@umich.edu # is rebuilt if the name changes 2274382Sbinkertn@umich.edu py_zip_depends.append(Value(arcname)) 2284382Sbinkertn@umich.edu 2294382Sbinkertn@umich.edu# Action function to build the zip archive. Uses the PyZipFile module 2304382Sbinkertn@umich.edu# included in the standard Python library. 2314382Sbinkertn@umich.edudef buildPyZip(target, source, env): 2324382Sbinkertn@umich.edu zf = zipfile.ZipFile(str(target[0]), 'w') 2334382Sbinkertn@umich.edu for s in source: 2344382Sbinkertn@umich.edu arcname = py_arcname[s] 2354382Sbinkertn@umich.edu zipname = str(s) 2364382Sbinkertn@umich.edu zf.write(zipname, arcname) 2374382Sbinkertn@umich.edu zf.close() 2384382Sbinkertn@umich.edu 2394382Sbinkertn@umich.edu# Add the zip file target to the environment. 2404382Sbinkertn@umich.eduenv.Command('m5py.zip', py_compiled, buildPyZip) 2414382Sbinkertn@umich.eduenv.Depends('m5py.zip', py_zip_depends) 2424382Sbinkertn@umich.edu 2434382Sbinkertn@umich.edu######################################################################## 2444382Sbinkertn@umich.edu# 2454382Sbinkertn@umich.edu# Define binaries. Each different build type (debug, opt, etc.) gets 2464382Sbinkertn@umich.edu# a slightly different build environment. 2474382Sbinkertn@umich.edu# 2484382Sbinkertn@umich.edu 2494382Sbinkertn@umich.edu# List of constructed environments to pass back to SConstruct 2504382Sbinkertn@umich.eduenvList = [] 2514382Sbinkertn@umich.edu 252955SN/A# This function adds the specified sources to the given build 253955SN/A# environment, and returns a list of all the corresponding SCons 254955SN/A# Object nodes (including an extra one for date.cc). We explicitly 255955SN/A# add the Object nodes so we can set up special dependencies for 2561108SN/A# date.cc. 257955SN/Adef make_objs(sources, env): 258955SN/A objs = [env.Object(s) for s in sources] 259955SN/A # make date.cc depend on all other objects so it always gets 260955SN/A # recompiled whenever anything else does 261955SN/A date_obj = env.Object('base/date.cc') 262955SN/A env.Depends(date_obj, objs) 263955SN/A objs.append(date_obj) 264955SN/A return objs 265955SN/A 2662655Sstever@eecs.umich.edu# Function to create a new build environment as clone of current 2672655Sstever@eecs.umich.edu# environment 'env' with modified object suffix and optional stripped 2682655Sstever@eecs.umich.edu# binary. Additional keyword arguments are appended to corresponding 2692655Sstever@eecs.umich.edu# build environment vars. 2702655Sstever@eecs.umich.edudef makeEnv(label, objsfx, strip = False, **kwargs): 2712655Sstever@eecs.umich.edu newEnv = env.Copy(OBJSUFFIX=objsfx) 2722655Sstever@eecs.umich.edu newEnv.Label = label 2732655Sstever@eecs.umich.edu newEnv.Append(**kwargs) 2742655Sstever@eecs.umich.edu exe = 'm5.' + label # final executable 2752655Sstever@eecs.umich.edu bin = exe + '.bin' # executable w/o appended Python zip archive 2762655Sstever@eecs.umich.edu newEnv.Program(bin, make_objs(sources, newEnv)) 2772655Sstever@eecs.umich.edu if strip: 2782655Sstever@eecs.umich.edu stripped_bin = bin + '.stripped' 2794007Ssaidi@eecs.umich.edu if sys.platform == 'sunos5': 2804007Ssaidi@eecs.umich.edu newEnv.Command(stripped_bin, bin, 'cp $SOURCE $TARGET; strip $TARGET') 2814007Ssaidi@eecs.umich.edu else: 2824007Ssaidi@eecs.umich.edu newEnv.Command(stripped_bin, bin, 'strip $SOURCE -o $TARGET') 2832655Sstever@eecs.umich.edu bin = stripped_bin 2844382Sbinkertn@umich.edu targets = newEnv.Concat(exe, [bin, 'm5py.zip']) 2852655Sstever@eecs.umich.edu newEnv.M5Binary = targets[0] 2862655Sstever@eecs.umich.edu envList.append(newEnv) 2872655Sstever@eecs.umich.edu 288955SN/A# Debug binary 2893918Ssaidi@eecs.umich.educcflags = {} 2903918Ssaidi@eecs.umich.eduif env['GCC']: 2913918Ssaidi@eecs.umich.edu if sys.platform == 'sunos5': 2923918Ssaidi@eecs.umich.edu ccflags['debug'] = '-gstabs+' 2933918Ssaidi@eecs.umich.edu else: 2943918Ssaidi@eecs.umich.edu ccflags['debug'] = '-ggdb3' 2953918Ssaidi@eecs.umich.edu ccflags['opt'] = '-g -O3' 2963918Ssaidi@eecs.umich.edu ccflags['fast'] = '-O3' 2973918Ssaidi@eecs.umich.edu ccflags['prof'] = '-O3 -g -pg' 2983918Ssaidi@eecs.umich.eduelif env['SUNCC']: 2993918Ssaidi@eecs.umich.edu ccflags['debug'] = '-g0' 3003918Ssaidi@eecs.umich.edu ccflags['opt'] = '-g -O' 3013918Ssaidi@eecs.umich.edu ccflags['fast'] = '-fast' 3023918Ssaidi@eecs.umich.edu ccflags['prof'] = '-fast -g -pg' 3033940Ssaidi@eecs.umich.eduelif env['ICC']: 3043940Ssaidi@eecs.umich.edu ccflags['debug'] = '-g -O0' 3053940Ssaidi@eecs.umich.edu ccflags['opt'] = '-g -O' 3063942Ssaidi@eecs.umich.edu ccflags['fast'] = '-fast' 3073940Ssaidi@eecs.umich.edu ccflags['prof'] = '-fast -g -pg' 3083515Ssaidi@eecs.umich.eduelse: 3093918Ssaidi@eecs.umich.edu print 'Unknown compiler, please fix compiler options' 3103918Ssaidi@eecs.umich.edu Exit(1) 3113515Ssaidi@eecs.umich.edu 3122655Sstever@eecs.umich.edumakeEnv('debug', '.do', 3133918Ssaidi@eecs.umich.edu CCFLAGS = Split(ccflags['debug']), 3143619Sbinkertn@umich.edu CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) 315955SN/A 316955SN/A# Optimized binary 3172655Sstever@eecs.umich.edumakeEnv('opt', '.o', 3183918Ssaidi@eecs.umich.edu CCFLAGS = Split(ccflags['opt']), 3193619Sbinkertn@umich.edu CPPDEFINES = ['TRACING_ON=1']) 320955SN/A 321955SN/A# "Fast" binary 3222655Sstever@eecs.umich.edumakeEnv('fast', '.fo', strip = True, 3233918Ssaidi@eecs.umich.edu CCFLAGS = Split(ccflags['fast']), 3243619Sbinkertn@umich.edu CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) 325955SN/A 326955SN/A# Profiled binary 3272655Sstever@eecs.umich.edumakeEnv('prof', '.po', 3283918Ssaidi@eecs.umich.edu CCFLAGS = Split(ccflags['prof']), 3293683Sstever@eecs.umich.edu CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], 3302655Sstever@eecs.umich.edu LINKFLAGS = '-pg') 3311869SN/A 3321869SN/AReturn('envList') 333