1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
|
# Copyright 2015, VIXL authors
# 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 glob
import itertools
import os
from os.path import join
import platform
import subprocess
import sys
from collections import OrderedDict
root_dir = os.path.dirname(File('SConstruct').rfile().abspath)
sys.path.insert(0, join(root_dir, 'tools'))
import config
import util
from SCons.Errors import UserError
Help('''
Build system for the VIXL project.
See README.md for documentation and details about the build system.
''')
# We track top-level targets to automatically generate help and alias them.
class VIXLTargets:
def __init__(self):
self.targets = []
self.help_messages = []
def Add(self, target, help_message):
self.targets.append(target)
self.help_messages.append(help_message)
def Help(self):
res = ""
for i in range(len(self.targets)):
res += '\t{0:<{1}}{2:<{3}}\n'.format(
'scons ' + self.targets[i],
len('scons ') + max(map(len, self.targets)),
' : ' + self.help_messages[i],
len(' : ') + max(map(len, self.help_messages)))
return res
top_level_targets = VIXLTargets()
# Build options ----------------------------------------------------------------
# Store all the options in a dictionary.
# The SConstruct will check the build variables and construct the build
# environment as appropriate.
options = {
'all' : { # Unconditionally processed.
'CCFLAGS' : ['-Wall',
'-Werror',
'-fdiagnostics-show-option',
'-Wextra',
'-Wredundant-decls',
'-pedantic',
'-Wwrite-strings',
'-Wunused',
'-Wno-missing-noreturn'],
'CPPPATH' : [config.dir_src_vixl]
},
# 'build_option:value' : {
# 'environment_key' : 'values to append'
# },
'mode:debug' : {
'CCFLAGS' : ['-DVIXL_DEBUG', '-O0']
},
'mode:release' : {
'CCFLAGS' : ['-O3'],
},
'simulator:aarch64' : {
'CCFLAGS' : ['-DVIXL_INCLUDE_SIMULATOR_AARCH64'],
},
'symbols:on' : {
'CCFLAGS' : ['-g'],
'LINKFLAGS' : ['-g']
},
'negative_testing:on' : {
'CCFLAGS' : ['-DVIXL_NEGATIVE_TESTING']
},
'code_buffer_allocator:mmap' : {
'CCFLAGS' : ['-DVIXL_CODE_BUFFER_MMAP']
},
'code_buffer_allocator:malloc' : {
'CCFLAGS' : ['-DVIXL_CODE_BUFFER_MALLOC']
},
'ubsan:on' : {
'CCFLAGS': ['-fsanitize=undefined'],
'LINKFLAGS': ['-fsanitize=undefined']
}
}
# A `DefaultVariable` has a default value that depends on elements not known
# when variables are first evaluated.
# Each `DefaultVariable` has a handler that will compute the default value for
# the given environment.
def modifiable_flags_handler(env):
env['modifiable_flags'] = \
'on' if 'mode' in env and env['mode'] == 'debug' else 'off'
def symbols_handler(env):
env['symbols'] = 'on' if 'mode' in env and env['mode'] == 'debug' else 'off'
def Is32BitHost(env):
return env['host_arch'] in ['aarch32', 'i386']
def IsAArch64Host(env):
return env['host_arch'] == 'aarch64'
def CanTargetA32(env):
return 'a32' in env['target']
def CanTargetT32(env):
return 't32' in env['target']
def CanTargetAArch32(env):
return CanTargetA32(env) or CanTargetT32(env)
def CanTargetA64(env):
return 'a64' in env['target']
def CanTargetAArch64(env):
return CanTargetA64(env)
# By default, include the simulator only if AArch64 is targeted and we are not
# building VIXL natively for AArch64.
def simulator_handler(env):
if not IsAArch64Host(env) and CanTargetAArch64(env):
env['simulator'] = 'aarch64'
else:
env['simulator'] = 'none'
# 'mmap' is required for use with 'mprotect', which is needed for the tests
# (when running natively), so we use it by default where we can.
def code_buffer_allocator_handler(env):
directives = util.GetCompilerDirectives(env)
if '__linux__' in directives:
env['code_buffer_allocator'] = 'mmap'
else:
env['code_buffer_allocator'] = 'malloc'
# A validator checks the consistency of provided options against the environment.
def default_validator(env):
pass
def simulator_validator(env):
if env['simulator'] == 'aarch64' and not CanTargetAArch64(env):
raise UserError('Building an AArch64 simulator implies that VIXL targets '
'AArch64. Set `target` to include `aarch64` or `a64`.')
# Default variables may depend on each other, therefore we need this dictionnary
# to be ordered.
vars_default_handlers = OrderedDict({
# variable_name : [ 'default val', 'handler', 'validator']
'symbols' : [ 'mode==debug', symbols_handler, default_validator ],
'modifiable_flags' : [ 'mode==debug', modifiable_flags_handler, default_validator],
'simulator' : [ 'on if the target architectures include AArch64 but '
'the host is not AArch64, else off',
simulator_handler, simulator_validator ],
'code_buffer_allocator' : [ 'mmap with __linux__, malloc otherwise',
code_buffer_allocator_handler, default_validator ]
})
def DefaultVariable(name, help, allowed_values):
help = '%s (%s)' % (help, '|'.join(allowed_values))
default_value = vars_default_handlers[name][0]
def validator(name, value, env):
if value != default_value and value not in allowed_values:
raise UserError('Invalid value for option {name}: {value}. '
'Valid values are: {allowed_values}'.format(
name, value, allowed_values))
return (name, help, default_value, validator)
def SortListVariable(iterator):
# Previously this code relied on the order of items in a list
# converted from a set. However in Python 3 the order changes each run.
# Here we do a custom partial sort to ensure that the build directory
# name is stable, the same across Python 2 and 3, and the same as the
# old code.
result = list(sorted(iterator))
result = sorted(result, key=lambda x: x == 't32', reverse=True)
result = sorted(result, key=lambda x: x == 'a32', reverse=True)
result = sorted(result, key=lambda x: x == 'a64', reverse=True)
return result
def AliasedListVariable(name, help, default_value, allowed_values, aliasing):
help = '%s (all|auto|comma-separated list) (any combination from [%s])' % \
(help, ', '.join(allowed_values))
def validator(name, value, env):
# Here list has been converted to space separated strings.
if value == '': return # auto
for v in value.split():
if v not in allowed_values:
raise UserError('Invalid value for %s: %s' % (name, value))
def converter(value):
if value == 'auto': return []
if value == 'all':
translated = [aliasing[v] for v in allowed_values]
return SortListVariable(itertools.chain.from_iterable(translated))
# The validator is run later hence the get.
translated = [aliasing.get(v, v) for v in value.split(',')]
return SortListVariable(itertools.chain.from_iterable(translated))
return (name, help, default_value, validator, converter)
vars = Variables()
# Define command line build options.
vars.AddVariables(
AliasedListVariable('target', 'Target ISA/Architecture', 'auto',
['aarch32', 'a32', 't32', 'aarch64', 'a64'],
{'aarch32' : ['a32', 't32'],
'a32' : ['a32'], 't32' : ['t32'],
'aarch64' : ['a64'], 'a64' : ['a64']}),
EnumVariable('mode', 'Build mode',
'release', allowed_values=config.build_options_modes),
EnumVariable('ubsan', 'Enable undefined behavior checks',
'off', allowed_values=['on', 'off']),
EnumVariable('negative_testing',
'Enable negative testing (needs exceptions)',
'off', allowed_values=['on', 'off']),
DefaultVariable('symbols', 'Include debugging symbols in the binaries',
['on', 'off']),
DefaultVariable('simulator', 'Simulators to include', ['aarch64', 'none']),
DefaultVariable('code_buffer_allocator',
'Configure the allocation mechanism in the CodeBuffer',
['malloc', 'mmap']),
('std',
'C++ standard. The standards tested are: %s.' % \
', '.join(config.tested_cpp_standards),
config.tested_cpp_standards[0]),
('compiler_wrapper', 'Command to prefix to the C and C++ compiler (e.g ccache)', '')
)
# We use 'variant directories' to avoid recompiling multiple times when build
# options are changed, different build paths are used depending on the options
# set. These are the options that should be reflected in the build directory
# path.
options_influencing_build_path = [
'target', 'mode', 'symbols', 'compiler', 'std', 'simulator', 'negative_testing',
'code_buffer_allocator'
]
# Build helpers ----------------------------------------------------------------
def RetrieveEnvironmentVariables(env):
for key in ['CC', 'CXX', 'AR', 'RANLIB', 'LD']:
if os.getenv(key): env[key] = os.getenv(key)
if os.getenv('LD_LIBRARY_PATH'): env['LIBPATH'] = os.getenv('LD_LIBRARY_PATH')
if os.getenv('CCFLAGS'):
env.Append(CCFLAGS = os.getenv('CCFLAGS').split())
if os.getenv('CXXFLAGS'):
env.Append(CXXFLAGS = os.getenv('CXXFLAGS').split())
if os.getenv('LINKFLAGS'):
env.Append(LINKFLAGS = os.getenv('LINKFLAGS').split())
# The architecture targeted by default will depend on the compiler being
# used. 'host_arch' is extracted from the compiler while 'target' can be
# set by the user.
# By default, we target both AArch32 and AArch64 unless the compiler targets a
# 32-bit architecture. At the moment, we cannot build VIXL's AArch64 support on
# a 32-bit platform.
# TODO: Port VIXL to build on a 32-bit platform.
def target_handler(env):
# Auto detect
if Is32BitHost(env):
# We use list(set(...)) to keep the same order as if it was specify as
# an option.
env['target'] = SortListVariable(['a32', 't32'])
else:
env['target'] = SortListVariable(['a64', 'a32', 't32'])
def target_validator(env):
# TODO: Port VIXL64 to work on a 32-bit platform.
if Is32BitHost(env) and CanTargetAArch64(env):
raise UserError('Building VIXL for AArch64 in 32-bit is not supported. Set '
'`target` to `aarch32`')
# The target option is handled differently from the rest.
def ProcessTargetOption(env):
if env['target'] == []: target_handler(env)
if 'a32' in env['target']: env['CCFLAGS'] += ['-DVIXL_INCLUDE_TARGET_A32']
if 't32' in env['target']: env['CCFLAGS'] += ['-DVIXL_INCLUDE_TARGET_T32']
if 'a64' in env['target']: env['CCFLAGS'] += ['-DVIXL_INCLUDE_TARGET_A64']
target_validator(env)
def ProcessBuildOptions(env):
# 'all' is unconditionally processed.
if 'all' in options:
for var in options['all']:
if var in env and env[var]:
env[var] += options['all'][var]
else:
env[var] = options['all'][var]
# The target option *must* be processed before the options defined in
# vars_default_handlers.
ProcessTargetOption(env)
# Other build options must match 'option:value'
env_dict = env.Dictionary()
# First apply the default variables handlers in order.
for key, value in vars_default_handlers.items():
default = value[0]
handler = value[1]
if env_dict.get(key) == default:
handler(env_dict)
# Second, run the series of validators, to check for errors.
for _, value in vars_default_handlers.items():
validator = value[2]
validator(env)
for key in env_dict.keys():
# Then update the environment according to the value of the variable.
key_val_couple = key + ':%s' % env_dict[key]
if key_val_couple in options:
for var in options[key_val_couple]:
env[var] += options[key_val_couple][var]
def ConfigureEnvironmentForCompiler(env):
compiler = util.CompilerInformation(env)
if compiler == 'clang':
# These warnings only work for Clang.
# -Wimplicit-fallthrough only works when compiling the code base as C++11 or
# newer. The compiler does not complain if the option is passed when
# compiling earlier C++ standards.
env.Append(CPPFLAGS = ['-Wimplicit-fallthrough', '-Wshorten-64-to-32'])
# The '-Wunreachable-code' flag breaks builds for clang 3.4.
if compiler != 'clang-3.4':
env.Append(CPPFLAGS = ['-Wunreachable-code'])
if env['ubsan'] == 'on':
env.Append(LINKFLAGS = ['-fuse-ld=lld'])
# 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.
if env['mode'] == 'release':
if compiler == 'gcc-4.8':
env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized'])
# GCC 6 and higher is able to detect throwing from inside a destructor and
# reports a warning. However, if negative testing is enabled then assertions
# will throw exceptions.
if env['negative_testing'] == 'on' and env['mode'] == 'debug' \
and compiler >= 'gcc-6':
env.Append(CPPFLAGS = ['-Wno-terminate'])
# Suggest missing override keywords on methods.
if compiler >= 'gcc-5':
env.Append(CPPFLAGS = ['-Wsuggest-override'])
elif compiler >= 'clang-3.6':
env.Append(CPPFLAGS = ['-Winconsistent-missing-override'])
def ConfigureEnvironment(env):
RetrieveEnvironmentVariables(env)
env['compiler'] = env['CXX']
if env['compiler_wrapper'] != '':
env['CXX'] = env['compiler_wrapper'] + ' ' + env['CXX']
env['CC'] = env['compiler_wrapper'] + ' ' + env['CC']
env['host_arch'] = util.GetHostArch(env)
ProcessBuildOptions(env)
if 'std' in env:
env.Append(CPPFLAGS = ['-std=' + env['std']])
std_path = env['std']
ConfigureEnvironmentForCompiler(env)
def TargetBuildDir(env):
# Build-time option values are embedded in the build path to avoid requiring a
# full build when an option changes.
build_dir = config.dir_build
for option in options_influencing_build_path:
option_value = ''.join(env[option]) if option in env else ''
build_dir = join(build_dir, option + '_'+ option_value)
return build_dir
def PrepareVariantDir(location, build_dir):
location_build_dir = join(build_dir, location)
VariantDir(location_build_dir, location)
return location_build_dir
def VIXLLibraryTarget(env):
build_dir = TargetBuildDir(env)
# Create a link to the latest build directory.
# Use `-r` to avoid failure when `latest` exists and is a directory.
subprocess.check_call(["rm", "-rf", config.dir_build_latest])
util.ensure_dir(build_dir)
subprocess.check_call(["ln", "-s", build_dir, config.dir_build_latest])
# Source files are in `src` and in `src/aarch64/`.
variant_dir_vixl = PrepareVariantDir(join('src'), build_dir)
sources = [Glob(join(variant_dir_vixl, '*.cc'))]
if CanTargetAArch32(env):
variant_dir_aarch32 = PrepareVariantDir(join('src', 'aarch32'), build_dir)
sources.append(Glob(join(variant_dir_aarch32, '*.cc')))
if CanTargetAArch64(env):
variant_dir_aarch64 = PrepareVariantDir(join('src', 'aarch64'), build_dir)
sources.append(Glob(join(variant_dir_aarch64, '*.cc')))
return env.Library(join(build_dir, 'vixl'), sources)
# Build ------------------------------------------------------------------------
# The VIXL library, built by default.
env = Environment(variables = vars,
BUILDERS = {
'Markdown': Builder(action = 'markdown $SOURCE > $TARGET',
suffix = '.html')
}, ENV = os.environ)
# Abort the build if any command line option is unknown or invalid.
unknown_build_options = vars.UnknownVariables()
if unknown_build_options:
print('Unknown build options: ' + str(unknown_build_options.keys()))
Exit(1)
if env['negative_testing'] == 'on' and env['mode'] != 'debug':
print('negative_testing only works in debug mode')
Exit(1)
ConfigureEnvironment(env)
Help(vars.GenerateHelpText(env))
libvixl = VIXLLibraryTarget(env)
Default(libvixl)
env.Alias('libvixl', libvixl)
top_level_targets.Add('', 'Build the VIXL library.')
# Common test code.
test_build_dir = PrepareVariantDir('test', TargetBuildDir(env))
test_objects = [env.Object(Glob(join(test_build_dir, '*.cc')))]
# AArch32 support
if CanTargetAArch32(env):
# The examples.
aarch32_example_names = util.ListCCFilesWithoutExt(config.dir_aarch32_examples)
aarch32_examples_build_dir = PrepareVariantDir('examples/aarch32', TargetBuildDir(env))
aarch32_example_targets = []
for example in aarch32_example_names:
prog = env.Program(join(aarch32_examples_build_dir, example),
join(aarch32_examples_build_dir, example + '.cc'),
LIBS=[libvixl])
aarch32_example_targets.append(prog)
env.Alias('aarch32_examples', aarch32_example_targets)
top_level_targets.Add('aarch32_examples', 'Build the examples for AArch32.')
# The benchmarks
aarch32_benchmark_names = util.ListCCFilesWithoutExt(config.dir_aarch32_benchmarks)
aarch32_benchmarks_build_dir = PrepareVariantDir('benchmarks/aarch32', TargetBuildDir(env))
aarch32_benchmark_targets = []
for bench in aarch32_benchmark_names:
prog = env.Program(join(aarch32_benchmarks_build_dir, bench),
join(aarch32_benchmarks_build_dir, bench + '.cc'),
LIBS=[libvixl])
aarch32_benchmark_targets.append(prog)
env.Alias('aarch32_benchmarks', aarch32_benchmark_targets)
top_level_targets.Add('aarch32_benchmarks', 'Build the benchmarks for AArch32.')
# The tests.
test_aarch32_build_dir = PrepareVariantDir(join('test', 'aarch32'), TargetBuildDir(env))
test_objects.append(env.Object(
Glob(join(test_aarch32_build_dir, '*.cc')),
CPPPATH = env['CPPPATH'] + [config.dir_tests],
CCFLAGS = [flag for flag in env['CCFLAGS'] if flag != '-O3']))
# AArch64 support
if CanTargetAArch64(env):
# The benchmarks.
aarch64_benchmark_names = util.ListCCFilesWithoutExt(config.dir_aarch64_benchmarks)
aarch64_benchmarks_build_dir = PrepareVariantDir('benchmarks/aarch64', TargetBuildDir(env))
aarch64_benchmark_targets = []
bench_utils = env.Object(join(aarch64_benchmarks_build_dir, 'bench-utils.o'),
join(aarch64_benchmarks_build_dir, 'bench-utils.cc'))
for bench in aarch64_benchmark_names:
if bench != 'bench-utils':
prog = env.Program(join(aarch64_benchmarks_build_dir, bench),
[join(aarch64_benchmarks_build_dir, bench + '.cc'), bench_utils],
LIBS=[libvixl])
aarch64_benchmark_targets.append(prog)
env.Alias('aarch64_benchmarks', aarch64_benchmark_targets)
top_level_targets.Add('aarch64_benchmarks', 'Build the benchmarks for AArch64.')
# The examples.
aarch64_example_names = util.ListCCFilesWithoutExt(config.dir_aarch64_examples)
aarch64_examples_build_dir = PrepareVariantDir('examples/aarch64', TargetBuildDir(env))
aarch64_example_targets = []
for example in aarch64_example_names:
prog = env.Program(join(aarch64_examples_build_dir, example),
join(aarch64_examples_build_dir, example + '.cc'),
LIBS=[libvixl])
aarch64_example_targets.append(prog)
env.Alias('aarch64_examples', aarch64_example_targets)
top_level_targets.Add('aarch64_examples', 'Build the examples for AArch64.')
# The tests.
test_aarch64_build_dir = PrepareVariantDir(join('test', 'aarch64'), TargetBuildDir(env))
test_objects.append(env.Object(
Glob(join(test_aarch64_build_dir, '*.cc')),
CPPPATH = env['CPPPATH'] + [config.dir_tests],
CCFLAGS = [flag for flag in env['CCFLAGS'] if flag != '-O3']))
# The test requires building the example files with specific options, so we
# create a separate variant dir for the example objects built this way.
test_aarch64_examples_vdir = join(TargetBuildDir(env), 'test', 'aarch64', 'test_examples')
VariantDir(test_aarch64_examples_vdir, '.')
test_aarch64_examples_obj = env.Object(
[Glob(join(test_aarch64_examples_vdir, join('test', 'aarch64', 'examples', '*.cc'))),
Glob(join(test_aarch64_examples_vdir, join('examples/aarch64', '*.cc')))],
CCFLAGS = env['CCFLAGS'] + ['-DTEST_EXAMPLES'],
CPPPATH = env['CPPPATH'] + [config.dir_aarch64_examples] + [config.dir_tests])
test_objects.append(test_aarch64_examples_obj)
test = env.Program(join(test_build_dir, 'test-runner'), test_objects,
LIBS=[libvixl])
env.Alias('tests', test)
top_level_targets.Add('tests', 'Build the tests.')
env.Alias('all', top_level_targets.targets)
top_level_targets.Add('all', 'Build all the targets above.')
Help('\n\nAvailable top level targets:\n' + top_level_targets.Help())
extra_targets = VIXLTargets()
# Build documentation
doc = [
env.Markdown('README.md'),
env.Markdown('doc/changelog.md'),
env.Markdown('doc/aarch32/getting-started-aarch32.md'),
env.Markdown('doc/aarch32/design/code-generation-aarch32.md'),
env.Markdown('doc/aarch32/design/literal-pool-aarch32.md'),
env.Markdown('doc/aarch64/supported-instructions-aarch64.md'),
env.Markdown('doc/aarch64/getting-started-aarch64.md'),
env.Markdown('doc/aarch64/topics/ycm.md'),
env.Markdown('doc/aarch64/topics/extending-the-disassembler.md'),
env.Markdown('doc/aarch64/topics/index.md'),
]
env.Alias('doc', doc)
extra_targets.Add('doc', 'Convert documentation to HTML (requires the '
'`markdown` program).')
Help('\nAvailable extra targets:\n' + extra_targets.Help())
|