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