Home | History | Annotate | Download | only in vixl
      1 # Copyright 2013, ARM Limited
      2 # All rights reserved.
      3 #
      4 # Redistribution and use in source and binary forms, with or without
      5 # modification, are permitted provided that the following conditions are met:
      6 #
      7 #   * Redistributions of source code must retain the above copyright notice,
      8 #     this list of conditions and the following disclaimer.
      9 #   * Redistributions in binary form must reproduce the above copyright notice,
     10 #     this list of conditions and the following disclaimer in the documentation
     11 #     and/or other materials provided with the distribution.
     12 #   * Neither the name of ARM Limited nor the names of its contributors may be
     13 #     used to endorse or promote products derived from this software without
     14 #     specific prior written permission.
     15 #
     16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 import os
     28 import os.path
     29 import sys
     30 
     31 # Global configuration.
     32 PROJ_SRC_DIR   = 'src'
     33 PROJ_SRC_FILES = '''
     34 src/utils-vixl.cc
     35 src/a64/assembler-a64.cc
     36 src/a64/macro-assembler-a64.cc
     37 src/a64/instructions-a64.cc
     38 src/a64/decoder-a64.cc
     39 src/a64/debugger-a64.cc
     40 src/a64/disasm-a64.cc
     41 src/a64/cpu-a64.cc
     42 src/a64/simulator-a64.cc
     43 src/a64/instrument-a64.cc
     44 '''.split()
     45 PROJ_EXAMPLES_DIR = 'examples'
     46 PROJ_EXAMPLES_SRC_FILES = '''
     47 examples/debugger.cc
     48 examples/add3-double.cc
     49 examples/add4-double.cc
     50 examples/factorial-rec.cc
     51 examples/factorial.cc
     52 examples/sum-array.cc
     53 examples/abs.cc
     54 examples/swap4.cc
     55 examples/swap-int32.cc
     56 examples/check-bounds.cc
     57 examples/getting-started.cc
     58 '''.split()
     59 # List target specific files.
     60 # Target names are used as dictionary entries.
     61 TARGET_SRC_DIR = {
     62   'cctest': 'test',
     63   'bench_dataop': 'benchmarks',
     64   'bench_branch': 'benchmarks',
     65   'examples': 'examples'
     66 }
     67 TARGET_SRC_FILES = {
     68   'cctest': '''
     69     test/cctest.cc
     70     test/test-utils-a64.cc
     71     test/test-assembler-a64.cc
     72     test/test-simulator-a64.cc
     73     test/test-disasm-a64.cc
     74     test/test-fuzz-a64.cc
     75     test/examples/test-examples.cc
     76     '''.split() + PROJ_EXAMPLES_SRC_FILES,
     77   'bench_dataop': '''
     78     benchmarks/bench-dataop.cc
     79     '''.split(),
     80   'bench_branch': '''
     81     benchmarks/bench-branch.cc
     82     '''.split()
     83 }
     84 RELEASE_OBJ_DIR  = 'obj/release'
     85 DEBUG_OBJ_DIR    = 'obj/debug'
     86 COVERAGE_OBJ_DIR = 'obj/coverage'
     87 
     88 
     89 # Helper functions.
     90 def abort(message):
     91   print('ABORTING: ' + message)
     92   sys.exit(1)
     93 
     94 
     95 def list_target(obj_dir, src_files):
     96   return map(lambda x: os.path.join(obj_dir, x), src_files)
     97 
     98 
     99 def create_variant(obj_dir, targets_dir):
    100   VariantDir(os.path.join(obj_dir, PROJ_SRC_DIR), PROJ_SRC_DIR)
    101   for directory in targets_dir.itervalues():
    102     VariantDir(os.path.join(obj_dir, directory), directory)
    103 
    104 
    105 # Build arguments.
    106 args = Variables()
    107 args.Add(EnumVariable('mode', 'Build mode', 'release',
    108                       allowed_values = ['release', 'debug', 'coverage']))
    109 args.Add(EnumVariable('target', 'Target to build', 'cctest',
    110                       allowed_values = ['cctest',
    111                                         'bench_dataop',
    112                                         'bench_branch',
    113                                         'examples']))
    114 args.Add(EnumVariable('simulator', 'build for the simulator', 'on',
    115                       allowed_values = ['on', 'off']))
    116 
    117 # Configure the environment.
    118 create_variant(RELEASE_OBJ_DIR, TARGET_SRC_DIR)
    119 create_variant(DEBUG_OBJ_DIR, TARGET_SRC_DIR)
    120 create_variant(COVERAGE_OBJ_DIR, TARGET_SRC_DIR)
    121 env = Environment(variables=args)
    122 
    123 # Commandline help.
    124 Help(args.GenerateHelpText(env))
    125 
    126 # Abort if any invalid argument was passed.
    127 # This check must happened after an environment is created.
    128 unknown_arg = args.UnknownVariables()
    129 if unknown_arg:
    130   abort('Unknown variable(s): ' + str(unknown_arg.keys()))
    131 
    132 # Setup tools.
    133 # This is necessary for cross-compilation.
    134 env['CXX'] = os.environ.get('CXX', env.get('CXX'))
    135 env['AR'] = os.environ.get('AR', env.get('AR'))
    136 env['RANLIB'] = os.environ.get('RANLIB', env.get('RANLIB'))
    137 env['CC'] = os.environ.get('CC', env.get('CC'))
    138 env['LD'] = os.environ.get('LD', env.get('LD'))
    139 
    140 if os.environ.get('CPPFLAGS'):
    141   env.Append(CPPFLAGS = os.environ.get('CPPFLAGS').split())
    142 if os.environ.get('LINKFLAGS'):
    143   env.Append(LINKFLAGS = os.environ.get('LINKFLAGS').split())
    144 
    145 # Always look in 'src' for include files.
    146 env.Append(CPPPATH = [PROJ_SRC_DIR])
    147 env.Append(CPPFLAGS = ['-Wall',
    148                        '-Werror',
    149                        '-fdiagnostics-show-option',
    150                        '-Wextra',
    151                        '-pedantic',
    152                        # Explicitly enable the write-strings warning. VIXL uses
    153                        # const correctly when handling string constants.
    154                        '-Wwrite-strings'])
    155 
    156 target_program = env['target']
    157 build_suffix = ''
    158 
    159 if env['simulator'] == 'on':
    160   env.Append(CPPFLAGS = ['-DUSE_SIMULATOR'])
    161   build_suffix += '_sim'
    162 
    163 if env['mode'] == 'debug':
    164   env.Append(CPPFLAGS = ['-g', '-DDEBUG'])
    165   # Append the debug mode suffix to the executable name.
    166   build_suffix += '_g'
    167   build_dir = DEBUG_OBJ_DIR
    168 elif env['mode'] == 'coverage':
    169   env.Append(CPPFLAGS = ['-g', '-DDEBUG', '-fprofile-arcs', '-ftest-coverage'])
    170   env.Append(LINKFLAGS = ['-fprofile-arcs'])
    171   # Append the coverage mode suffix to the executable name.
    172   build_suffix += '_gcov'
    173   build_dir = COVERAGE_OBJ_DIR
    174 else:
    175   # Release mode.
    176   env.Append(CPPFLAGS = ['-O3'])
    177   build_dir = RELEASE_OBJ_DIR
    178   # GCC 4.8 has a bug which produces a warning saying that an anonymous Operand
    179   # object might be used uninitialized:
    180   #   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57045
    181   # The bug does not seem to appear in GCC 4.7, or in debug builds with GCC 4.8.
    182   env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized'])
    183 
    184 
    185 if target_program == 'cctest':
    186   env.Append(CPPPATH = [PROJ_EXAMPLES_DIR])
    187   env.Append(CPPFLAGS = ['-DTEST_EXAMPLES'])
    188 
    189 # Build the library.
    190 proj_library = env.Library('vixl' + build_suffix, list_target(build_dir, PROJ_SRC_FILES))
    191 
    192 if target_program == 'examples':
    193   # Build the examples.
    194   env.Append(CPPPATH = [PROJ_EXAMPLES_DIR])
    195   for example in PROJ_EXAMPLES_SRC_FILES:
    196     example_name = "example-" + os.path.splitext(os.path.basename(example))[0]
    197     env.Program(example_name, list_target(build_dir, [example]) + proj_library)
    198 else:
    199   # Build the target program.
    200   program_target_files = list_target(build_dir, TARGET_SRC_FILES[env['target']])
    201   env.Program(target_program + build_suffix, program_target_files + proj_library)
    202