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