SConstruct revision 955
111945Sgabeblack@google.com# -*- mode:python -*-
211945Sgabeblack@google.com
311945Sgabeblack@google.com# Copyright (c) 2004 The Regents of The University of Michigan
411945Sgabeblack@google.com# All rights reserved.
511945Sgabeblack@google.com#
611945Sgabeblack@google.com# Redistribution and use in source and binary forms, with or without
711950Sgabeblack@google.com# modification, are permitted provided that the following conditions are
811950Sgabeblack@google.com# met: redistributions of source code must retain the above copyright
911950Sgabeblack@google.com# notice, this list of conditions and the following disclaimer;
1011950Sgabeblack@google.com# redistributions in binary form must reproduce the above copyright
1111950Sgabeblack@google.com# notice, this list of conditions and the following disclaimer in the
1211945Sgabeblack@google.com# documentation and/or other materials provided with the distribution;
1311945Sgabeblack@google.com# neither the name of the copyright holders nor the names of its
1411945Sgabeblack@google.com# contributors may be used to endorse or promote products derived from
1511945Sgabeblack@google.com# this software without specific prior written permission.
1611946Sgabeblack@google.com#
1711945Sgabeblack@google.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1811945Sgabeblack@google.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1911945Sgabeblack@google.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2011945Sgabeblack@google.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2111945Sgabeblack@google.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2211945Sgabeblack@google.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2311945Sgabeblack@google.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2411945Sgabeblack@google.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2511946Sgabeblack@google.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2611945Sgabeblack@google.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2711945Sgabeblack@google.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2811945Sgabeblack@google.com
2911945Sgabeblack@google.com###################################################
3011945Sgabeblack@google.com#
3111945Sgabeblack@google.com# SCons top-level build description (SConstruct) file.
3211945Sgabeblack@google.com#
3311945Sgabeblack@google.com# To build M5, you need a directory with three things:
3411945Sgabeblack@google.com# 1. A copy of this file (named SConstruct).
3511945Sgabeblack@google.com# 2. A link named 'm5' to the top of the M5 simulator source tree.
3611945Sgabeblack@google.com# 3. A link named 'ext' to the top of the M5 external source tree.
3711945Sgabeblack@google.com#
3811945Sgabeblack@google.com# Then type 'scons' to build the default configuration (see below), or
3911945Sgabeblack@google.com# 'scons <CONFIG>/<binary>' to build some other configuration (e.g.,
4011946Sgabeblack@google.com# 'KERNEL/m5.opt' for the optimized full-system version).
4111945Sgabeblack@google.com#
4211945Sgabeblack@google.com###################################################
4311945Sgabeblack@google.com
4411945Sgabeblack@google.com# Python library imports
4511945Sgabeblack@google.comimport sys
4611945Sgabeblack@google.comimport os
4711945Sgabeblack@google.com
4811945Sgabeblack@google.com# The absolute path to the current directory (where this file lives).
4911946Sgabeblack@google.comROOT = Dir('.').abspath
5011945Sgabeblack@google.com
5111945Sgabeblack@google.com# Paths to the M5 and external source trees (local symlinks).
5211945Sgabeblack@google.comSRCDIR = os.path.join(ROOT, 'm5')
5311945Sgabeblack@google.comEXT_SRCDIR = os.path.join(ROOT, 'ext')
5411945Sgabeblack@google.com
5511945Sgabeblack@google.com# Check for 'm5' and 'ext' links, die if they don't exist.
5611945Sgabeblack@google.comif not os.path.isdir(SRCDIR):
5711945Sgabeblack@google.com    print "Error: '%s' must be a link to the M5 source tree." % SRCDIR
5811945Sgabeblack@google.com    sys.exit(1)
5911945Sgabeblack@google.com
6011945Sgabeblack@google.comif not os.path.isdir('ext'):
6111945Sgabeblack@google.com    print "Error: '%s' must be a link to the M5 external source tree." \
6211945Sgabeblack@google.com          % EXT_SRCDIR
6311945Sgabeblack@google.com    sys.exit(1)
6411945Sgabeblack@google.com
6511945Sgabeblack@google.com
6611945Sgabeblack@google.com###################################################
6711945Sgabeblack@google.com#
6811945Sgabeblack@google.com# Define Configurations
6911945Sgabeblack@google.com#
7011945Sgabeblack@google.com# The build system infers the build options from the subdirectory name
7111945Sgabeblack@google.com# that the simulator is built under.  The subdirectory name must be of
7211945Sgabeblack@google.com# the form <CONFIG>[.<OPT>]*, where <CONFIG> is a base configuration
7311945Sgabeblack@google.com# (e.g., ALPHA or KERNEL) and OPT is an option (e.g., MYSQL).  The
7411946Sgabeblack@google.com# following code defines the standard configurations and options.
7511945Sgabeblack@google.com# Additional local configurations and options are read from the file
7611945Sgabeblack@google.com# 'local_configs' if it exists.
7711945Sgabeblack@google.com#
7811945Sgabeblack@google.com# Each base configuration or option is defined in two steps: a
7911945Sgabeblack@google.com# function that takes an SCons build environment and modifies it
8011945Sgabeblack@google.com# appropriately for that config or option, and an entry in the
8111945Sgabeblack@google.com# 'configs_map' or 'options_map' dictionary that maps the directory
8211945Sgabeblack@google.com# name string to the function.  (The directory names are all upper
8311945Sgabeblack@google.com# case, by convention.)
8411945Sgabeblack@google.com#
8511945Sgabeblack@google.com###################################################
8611945Sgabeblack@google.com
8711945Sgabeblack@google.com# Base non-full-system Alpha ISA configuration.
8811945Sgabeblack@google.comdef AlphaConfig(env):
8911945Sgabeblack@google.com    env.Replace(TARGET_ISA = 'alpha')
9011945Sgabeblack@google.com    env.Append(CPPDEFINES = 'SS_COMPATIBLE_FP')
9111945Sgabeblack@google.com
9211945Sgabeblack@google.com# Base full-system configuration.
9311945Sgabeblack@google.comdef KernelConfig(env):
9411945Sgabeblack@google.com    env.Replace(TARGET_ISA = 'alpha')
9511945Sgabeblack@google.com    env.Replace(FULL_SYSTEM = True)
9611945Sgabeblack@google.com    env.Append(CPPDEFINES = ['FULL_SYSTEM', 'SYSTEM_EV5'])
9711945Sgabeblack@google.com
9811945Sgabeblack@google.com# Base configurations map.
9911946Sgabeblack@google.comconfigs_map = {
10011945Sgabeblack@google.com    'ALPHA' : AlphaConfig,
10111945Sgabeblack@google.com    'KERNEL' : KernelConfig
10211945Sgabeblack@google.com    }
10311945Sgabeblack@google.com
10411945Sgabeblack@google.com# Enable detailed full-system binning.
10511945Sgabeblack@google.comdef MeasureOpt(env):
10611945Sgabeblack@google.com    env.Replace(USE_MYSQL = True)
10711945Sgabeblack@google.com    env.Append(CPPDEFINES = 'FS_MEASURE')
10811945Sgabeblack@google.com
10911945Sgabeblack@google.com# Enable MySql database output for stats.
11011945Sgabeblack@google.comdef MySqlOpt(env):
11111945Sgabeblack@google.com    env.Replace(USE_MYSQL = True)
11211945Sgabeblack@google.com
11311945Sgabeblack@google.com# Disable FastAlloc object allocation.
11411945Sgabeblack@google.comdef NoFastAllocOpt(env):
11511945Sgabeblack@google.com    env.Append(CPPDEFINES = 'NO_FAST_ALLOC')
11611946Sgabeblack@google.com
11711946Sgabeblack@google.com# Configuration options map.
11811945Sgabeblack@google.comoptions_map = {
11911948Sgabeblack@google.com    'MEASURE' : MeasureOpt,
12011945Sgabeblack@google.com    'MYSQL' : MySqlOpt,
12111945Sgabeblack@google.com    'NO_FAST_ALLOC' : NoFastAllocOpt
12211945Sgabeblack@google.com    }
12311945Sgabeblack@google.com
12411945Sgabeblack@google.com# The 'local_configs' file can be used to define additional base
12511945Sgabeblack@google.com# configurations and/or options without changing this file.
12611945Sgabeblack@google.comif os.path.isfile('local_configs'):
12711945Sgabeblack@google.com    SConscript('local_configs', exports = ['configs_map', 'options_map'])
12811945Sgabeblack@google.com
12911945Sgabeblack@google.com# This function parses a directory name of the form <CONFIG>[.<OPT>]*
13011945Sgabeblack@google.com# and sets up the build environment appropriately.  Returns True if
13111945Sgabeblack@google.com# successful, False if the base config or any of the options were not
13211945Sgabeblack@google.com# defined.
13311945Sgabeblack@google.comdef set_dir_options(dir, env):
13411945Sgabeblack@google.com    parts = dir.split('.')
13511945Sgabeblack@google.com    config = parts[0]
13611945Sgabeblack@google.com    opts = parts[1:]
13711945Sgabeblack@google.com    try:
13811945Sgabeblack@google.com        configs_map[config](env)
13911945Sgabeblack@google.com        map(lambda opt: options_map[opt](env), opts)
14011945Sgabeblack@google.com        return True
14111945Sgabeblack@google.com    except KeyError, key:
14211945Sgabeblack@google.com        print "Config/option '%s' not found." % key
14311945Sgabeblack@google.com        return False
14411945Sgabeblack@google.com
14511945Sgabeblack@google.com# Set the default configuration and binary.  The default target (if
14611945Sgabeblack@google.com# scons is invoked at the top level with no command-line targets) is
14711945Sgabeblack@google.com# 'ALPHA/m5.debug'.  If scons is invoked in a subdirectory with no
14811945Sgabeblack@google.com# command-line targets, the configuration
14911945Sgabeblack@google.com
15011945Sgabeblack@google.com###################################################
15111945Sgabeblack@google.com#
15211945Sgabeblack@google.com# Figure out which configurations to set up.
15311945Sgabeblack@google.com#
15411945Sgabeblack@google.com#
15511945Sgabeblack@google.com# It's prohibitive to do all the combinations of base configurations
15611945Sgabeblack@google.com# and options, so we have to infer which ones the user wants.
15711945Sgabeblack@google.com#
15811945Sgabeblack@google.com# 1. If there are command-line targets, the configuration(s) are inferred
15911945Sgabeblack@google.com#    from the directories of those targets.  If scons was invoked from a
16011945Sgabeblack@google.com#    subdirectory (using 'scons -u'), those targets have to be
16111945Sgabeblack@google.com#    interpreted relative to that subdirectory.
16211945Sgabeblack@google.com#
16311945Sgabeblack@google.com# 2. If there are no command-line targets, and scons was invoked from a
16411945Sgabeblack@google.com#    subdirectory (using 'scons -u'), the configuration is inferred from
16511945Sgabeblack@google.com#    the name of the subdirectory.
16611945Sgabeblack@google.com#
16711945Sgabeblack@google.com# 3. If there are no command-line targets and scons was invoked from
16811945Sgabeblack@google.com#    the root build directory, a default configuration is used.  The
16911945Sgabeblack@google.com#    built-in default is ALPHA, but this can be overridden by setting the
17011945Sgabeblack@google.com#    M5_DEFAULT_CONFIG shell environment veriable.
17111945Sgabeblack@google.com#
17211945Sgabeblack@google.com# In cases 2 & 3, the specific file target defaults to 'm5.debug', but
17311945Sgabeblack@google.com# this can be overridden by setting the M5_DEFAULT_BINARY shell
17411945Sgabeblack@google.com# environment veriable.
17511945Sgabeblack@google.com#
17611945Sgabeblack@google.com###################################################
17711945Sgabeblack@google.com
17811945Sgabeblack@google.com# Find default configuration & binary.
17911945Sgabeblack@google.comdefault_config = os.environ.get('M5_DEFAULT_CONFIG', 'ALPHA')
18011946Sgabeblack@google.comdefault_binary = os.environ.get('M5_DEFAULT_BINARY', 'm5.debug')
18111946Sgabeblack@google.com
18211945Sgabeblack@google.com# Ask SCons which directory it was invoked from.  If you invoke SCons
18311945Sgabeblack@google.com# from a subdirectory you must use the '-u' flag.
18411945Sgabeblack@google.comlaunch_dir = GetLaunchDir()
18511945Sgabeblack@google.com
18611945Sgabeblack@google.com# Build a list 'my_targets' of all the targets relative to ROOT.
18711945Sgabeblack@google.comif launch_dir == ROOT:
18811945Sgabeblack@google.com    # invoked from root build dir
18911945Sgabeblack@google.com    if len(COMMAND_LINE_TARGETS) != 0:
19011945Sgabeblack@google.com        # easy: use specified targets as is
19111945Sgabeblack@google.com        my_targets = COMMAND_LINE_TARGETS
19211945Sgabeblack@google.com    else:
19311945Sgabeblack@google.com        # default target (ALPHA/m5.debug, unless overridden)
19411945Sgabeblack@google.com        target = os.path.join(default_config, default_binary)
19511945Sgabeblack@google.com        my_targets = [target]
19611945Sgabeblack@google.com        Default(target)
19711945Sgabeblack@google.comelse:
19811945Sgabeblack@google.com    # invoked from subdirectory
19911945Sgabeblack@google.com    if not launch_dir.startswith(ROOT):
20011945Sgabeblack@google.com        print "Error: launch dir (%s) not a subdirectory of ROOT (%s)!" \
20111945Sgabeblack@google.com              (launch_dir, ROOT)
20211945Sgabeblack@google.com        sys.exit(1)
20311945Sgabeblack@google.com    # make launch_dir relative to ROOT (strip ROOT plus slash off front)
20411945Sgabeblack@google.com    launch_dir = launch_dir[len(ROOT)+1:]
20511945Sgabeblack@google.com    if len(COMMAND_LINE_TARGETS) != 0:
20611945Sgabeblack@google.com        # make specified targets relative to ROOT
20711945Sgabeblack@google.com        my_targets = map(lambda x: os.path.join(launch_dir, x),
20811945Sgabeblack@google.com                         COMMAND_LINE_TARGETS)
20911945Sgabeblack@google.com    else:
21011945Sgabeblack@google.com        # build default binary (m5.debug, unless overridden) using the
21111945Sgabeblack@google.com        # config inferred by the invocation directory (the first
21211945Sgabeblack@google.com        # subdirectory after ROOT)
21311945Sgabeblack@google.com        target = os.path.join(launch_dir.split('/')[0], default_binary)
21411946Sgabeblack@google.com        my_targets = [target]
21511945Sgabeblack@google.com        Default(target)
21611945Sgabeblack@google.com
21711945Sgabeblack@google.com# Normalize target paths (gets rid of '..' in the middle, etc.)
21811945Sgabeblack@google.commy_targets = map(os.path.normpath, my_targets)
21911945Sgabeblack@google.com
22011945Sgabeblack@google.com# Generate a list of the unique configs that the collected targets reference.
22111945Sgabeblack@google.combuild_dirs = []
22211945Sgabeblack@google.comfor t in my_targets:
22311945Sgabeblack@google.com    dir = t.split('/')[0]
22411945Sgabeblack@google.com    if dir not in build_dirs:
22511945Sgabeblack@google.com        build_dirs.append(dir)
22611945Sgabeblack@google.com
22711945Sgabeblack@google.com###################################################
22811945Sgabeblack@google.com#
22911945Sgabeblack@google.com# Set up the default build environment.  This environment is copied
23011945Sgabeblack@google.com# and modified according to each selected configuration.
23111945Sgabeblack@google.com#
23211945Sgabeblack@google.com###################################################
23311945Sgabeblack@google.com
23411945Sgabeblack@google.comdefault_env = Environment(ENV = os.environ,  # inherit user's enviroment vars
23511945Sgabeblack@google.com                          ROOT = ROOT,
23611945Sgabeblack@google.com                          SRCDIR = SRCDIR,
23711945Sgabeblack@google.com                          EXT_SRCDIR = EXT_SRCDIR,
23811945Sgabeblack@google.com                          CPPDEFINES = [],
23911945Sgabeblack@google.com                          FULL_SYSTEM = False,
24011945Sgabeblack@google.com                          USE_MYSQL = False)
24111945Sgabeblack@google.com
24211945Sgabeblack@google.com# M5_EXT is used by isa_parser.py to find the PLY package.
24311945Sgabeblack@google.comdefault_env.Append(ENV = { 'M5_EXT' : EXT_SRCDIR })
24411945Sgabeblack@google.com
24511945Sgabeblack@google.comdefault_env.Append(CCFLAGS='-pipe')
24611945Sgabeblack@google.comdefault_env.Append(CCFLAGS='-fno-strict-aliasing')
24711945Sgabeblack@google.comdefault_env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
24811945Sgabeblack@google.com
24911945Sgabeblack@google.com# libelf build is described in its own SConscript file.  Using a
25011945Sgabeblack@google.com# dictionary for exports lets us export "default_env" so the
25111945Sgabeblack@google.com# SConscript will see it as "env".
25211950Sgabeblack@google.comdefault_env.SConscript('m5/libelf/SConscript', exports={'env' : default_env})
25311945Sgabeblack@google.com
25411945Sgabeblack@google.com
25511945Sgabeblack@google.com###################################################
25611945Sgabeblack@google.com#
25711945Sgabeblack@google.com# Define build environments for selected configurations.
25811945Sgabeblack@google.com#
25911945Sgabeblack@google.com###################################################
26011945Sgabeblack@google.com
26111945Sgabeblack@google.comfor build_dir in build_dirs:
26211945Sgabeblack@google.com    # Make a copy of the default environment to use for this config.
26311946Sgabeblack@google.com    env = default_env.Copy()
26411946Sgabeblack@google.com    # Modify 'env' according to the build directory config.
26511946Sgabeblack@google.com    print "Configuring options for directory '%s'." % build_dir
26611946Sgabeblack@google.com    if not set_dir_options(build_dir, env):
26711946Sgabeblack@google.com        print "Skipping directory '%s'." % build_dir
26811946Sgabeblack@google.com        continue
26911946Sgabeblack@google.com
27011946Sgabeblack@google.com    # The m5/SConscript file sets up the build rules in 'env' according
27111946Sgabeblack@google.com    # to the configured options.
27211946Sgabeblack@google.com    SConscript('m5/SConscript', build_dir = build_dir, exports = 'env',
27311946Sgabeblack@google.com               duplicate=0)
27411946Sgabeblack@google.com
27511946Sgabeblack@google.com
27611946Sgabeblack@google.com###################################################
27711946Sgabeblack@google.com#
27811946Sgabeblack@google.com# Let SCons do its thing.  At this point SCons will use the defined
27911946Sgabeblack@google.com# build enviornments to build the requested targets.
28011945Sgabeblack@google.com#
28111945Sgabeblack@google.com###################################################
282
283