blob: 2ec31f92d19d7dbb916aa069c1fd6d914acad2ee [file] [log] [blame]
# Copyright 2013, ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of ARM Limited nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import os.path
import sys
# Global configuration.
PROJ_SRC_DIR = 'src'
PROJ_SRC_FILES = '''
src/utils-vixl.cc
src/a64/assembler-a64.cc
src/a64/macro-assembler-a64.cc
src/a64/instructions-a64.cc
src/a64/decoder-a64.cc
src/a64/debugger-a64.cc
src/a64/disasm-a64.cc
src/a64/cpu-a64.cc
src/a64/simulator-a64.cc
src/a64/instrument-a64.cc
'''.split()
PROJ_EXAMPLES_DIR = 'examples'
PROJ_EXAMPLES_SRC_FILES = '''
examples/debugger.cc
examples/add3-double.cc
examples/add4-double.cc
examples/factorial-rec.cc
examples/factorial.cc
examples/sum-array.cc
examples/abs.cc
examples/swap4.cc
examples/swap-int32.cc
examples/check-bounds.cc
examples/getting-started.cc
'''.split()
# List target specific files.
# Target names are used as dictionary entries.
TARGET_SRC_DIR = {
'cctest': 'test',
'bench_dataop': 'benchmarks',
'bench_branch': 'benchmarks',
'examples': 'examples'
}
TARGET_SRC_FILES = {
'cctest': '''
test/cctest.cc
test/test-utils-a64.cc
test/test-assembler-a64.cc
test/test-simulator-a64.cc
test/test-disasm-a64.cc
test/test-fuzz-a64.cc
test/examples/test-examples.cc
'''.split() + PROJ_EXAMPLES_SRC_FILES,
'bench_dataop': '''
benchmarks/bench-dataop.cc
'''.split(),
'bench_branch': '''
benchmarks/bench-branch.cc
'''.split()
}
RELEASE_OBJ_DIR = 'obj/release'
DEBUG_OBJ_DIR = 'obj/debug'
COVERAGE_OBJ_DIR = 'obj/coverage'
# Helper functions.
def abort(message):
print('ABORTING: ' + message)
sys.exit(1)
def list_target(obj_dir, src_files):
return map(lambda x: os.path.join(obj_dir, x), src_files)
def create_variant(obj_dir, targets_dir):
VariantDir(os.path.join(obj_dir, PROJ_SRC_DIR), PROJ_SRC_DIR)
for directory in targets_dir.itervalues():
VariantDir(os.path.join(obj_dir, directory), directory)
# Build arguments.
args = Variables()
args.Add(EnumVariable('mode', 'Build mode', 'release',
allowed_values = ['release', 'debug', 'coverage']))
args.Add(EnumVariable('target', 'Target to build', 'cctest',
allowed_values = ['cctest',
'bench_dataop',
'bench_branch',
'examples']))
args.Add(EnumVariable('simulator', 'build for the simulator', 'on',
allowed_values = ['on', 'off']))
# Configure the environment.
create_variant(RELEASE_OBJ_DIR, TARGET_SRC_DIR)
create_variant(DEBUG_OBJ_DIR, TARGET_SRC_DIR)
create_variant(COVERAGE_OBJ_DIR, TARGET_SRC_DIR)
env = Environment(variables=args)
# Commandline help.
Help(args.GenerateHelpText(env))
# Abort if any invalid argument was passed.
# This check must happened after an environment is created.
unknown_arg = args.UnknownVariables()
if unknown_arg:
abort('Unknown variable(s): ' + str(unknown_arg.keys()))
# Setup tools.
# This is necessary for cross-compilation.
env['CXX'] = os.environ.get('CXX', env.get('CXX'))
env['AR'] = os.environ.get('AR', env.get('AR'))
env['RANLIB'] = os.environ.get('RANLIB', env.get('RANLIB'))
env['CC'] = os.environ.get('CC', env.get('CC'))
env['LD'] = os.environ.get('LD', env.get('LD'))
if os.environ.get('CPPFLAGS'):
env.Append(CPPFLAGS = os.environ.get('CPPFLAGS').split())
if os.environ.get('LINKFLAGS'):
env.Append(LINKFLAGS = os.environ.get('LINKFLAGS').split())
# Always look in 'src' for include files.
env.Append(CPPPATH = [PROJ_SRC_DIR])
env.Append(CPPFLAGS = ['-Wall',
'-Werror',
'-fdiagnostics-show-option',
'-Wextra',
'-pedantic',
# Explicitly enable the write-strings warning. VIXL uses
# const correctly when handling string constants.
'-Wwrite-strings'])
target_program = env['target']
build_suffix = ''
if env['simulator'] == 'on':
env.Append(CPPFLAGS = ['-DUSE_SIMULATOR'])
build_suffix += '_sim'
if env['mode'] == 'debug':
env.Append(CPPFLAGS = ['-g', '-DDEBUG'])
# Append the debug mode suffix to the executable name.
build_suffix += '_g'
build_dir = DEBUG_OBJ_DIR
elif env['mode'] == 'coverage':
env.Append(CPPFLAGS = ['-g', '-DDEBUG', '-fprofile-arcs', '-ftest-coverage'])
env.Append(LINKFLAGS = ['-fprofile-arcs'])
# Append the coverage mode suffix to the executable name.
build_suffix += '_gcov'
build_dir = COVERAGE_OBJ_DIR
else:
# Release mode.
env.Append(CPPFLAGS = ['-O3'])
build_dir = RELEASE_OBJ_DIR
# GCC 4.8 has a bug which produces a warning saying that an anonymous Operand
# object might be used uninitialized:
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57045
# The bug does not seem to appear in GCC 4.7, or in debug builds with GCC 4.8.
env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized'])
if target_program == 'cctest':
env.Append(CPPPATH = [PROJ_EXAMPLES_DIR])
env.Append(CPPFLAGS = ['-DTEST_EXAMPLES'])
# Build the library.
proj_library = env.Library('vixl' + build_suffix, list_target(build_dir, PROJ_SRC_FILES))
if target_program == 'examples':
# Build the examples.
env.Append(CPPPATH = [PROJ_EXAMPLES_DIR])
for example in PROJ_EXAMPLES_SRC_FILES:
example_name = "example-" + os.path.splitext(os.path.basename(example))[0]
env.Program(example_name, list_target(build_dir, [example]) + proj_library)
else:
# Build the target program.
program_target_files = list_target(build_dir, TARGET_SRC_FILES[env['target']])
env.Program(target_program + build_suffix, program_target_files + proj_library)