armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame^] | 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.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 | '''.split() |
| 44 | PROJ_EXAMPLES_DIR = 'examples' |
| 45 | PROJ_EXAMPLES_SRC_FILES = ''' |
| 46 | examples/debugger.cc |
| 47 | examples/add3-double.cc |
| 48 | examples/add4-double.cc |
| 49 | examples/factorial-rec.cc |
| 50 | examples/factorial.cc |
| 51 | examples/sum-array.cc |
| 52 | examples/abs.cc |
| 53 | examples/swap4.cc |
| 54 | examples/swap-int32.cc |
| 55 | examples/check-bounds.cc |
| 56 | examples/getting-started.cc |
| 57 | '''.split() |
| 58 | # List target specific files. |
| 59 | # Target names are used as dictionary entries. |
| 60 | TARGET_SRC_DIR = { |
| 61 | 'cctest': 'test', |
| 62 | 'bench_dataop': 'benchmarks', |
| 63 | 'bench_branch': 'benchmarks', |
| 64 | 'examples': 'examples' |
| 65 | } |
| 66 | TARGET_SRC_FILES = { |
| 67 | 'cctest': ''' |
| 68 | test/cctest.cc |
| 69 | test/test-utils-a64.cc |
| 70 | test/test-assembler-a64.cc |
| 71 | test/test-disasm-a64.cc |
| 72 | test/examples/test-examples.cc |
| 73 | '''.split() + PROJ_EXAMPLES_SRC_FILES, |
| 74 | 'bench_dataop': ''' |
| 75 | benchmarks/bench-dataop.cc |
| 76 | '''.split(), |
| 77 | 'bench_branch': ''' |
| 78 | benchmarks/bench-branch.cc |
| 79 | '''.split() |
| 80 | } |
| 81 | RELEASE_OBJ_DIR = 'obj/release' |
| 82 | DEBUG_OBJ_DIR = 'obj/debug' |
| 83 | COVERAGE_OBJ_DIR = 'obj/coverage' |
| 84 | |
| 85 | |
| 86 | # Helper functions. |
| 87 | def abort(message): |
| 88 | print('ABORTING: ' + message) |
| 89 | sys.exit(1) |
| 90 | |
| 91 | |
| 92 | def list_target(obj_dir, src_files): |
| 93 | return map(lambda x: os.path.join(obj_dir, x), src_files) |
| 94 | |
| 95 | |
| 96 | def create_variant(obj_dir, targets_dir): |
| 97 | VariantDir(os.path.join(obj_dir, PROJ_SRC_DIR), PROJ_SRC_DIR) |
| 98 | for directory in targets_dir.itervalues(): |
| 99 | VariantDir(os.path.join(obj_dir, directory), directory) |
| 100 | |
| 101 | |
| 102 | # Build arguments. |
| 103 | args = Variables() |
| 104 | args.Add(EnumVariable('mode', 'Build mode', 'release', |
| 105 | allowed_values = ['release', 'debug', 'coverage'])) |
| 106 | args.Add(EnumVariable('target', 'Target to build', 'cctest', |
| 107 | allowed_values = ['cctest', |
| 108 | 'bench_dataop', |
| 109 | 'bench_branch', |
| 110 | 'examples'])) |
| 111 | args.Add(EnumVariable('simulator', 'build for the simulator', 'on', |
| 112 | allowed_values = ['on', 'off'])) |
| 113 | |
| 114 | # Configure the environment. |
| 115 | create_variant(RELEASE_OBJ_DIR, TARGET_SRC_DIR) |
| 116 | create_variant(DEBUG_OBJ_DIR, TARGET_SRC_DIR) |
| 117 | create_variant(COVERAGE_OBJ_DIR, TARGET_SRC_DIR) |
| 118 | env = Environment(variables=args) |
| 119 | |
| 120 | # Commandline help. |
| 121 | Help(args.GenerateHelpText(env)) |
| 122 | |
| 123 | # Abort if any invalid argument was passed. |
| 124 | # This check must happened after an environment is created. |
| 125 | unknown_arg = args.UnknownVariables() |
| 126 | if unknown_arg: |
| 127 | abort('Unknown variable(s): ' + str(unknown_arg.keys())) |
| 128 | |
| 129 | # Setup tools. |
| 130 | # This is necessary for cross-compilation. |
| 131 | env['CXX'] = os.environ.get('CXX', env.get('CXX')) |
| 132 | env['AR'] = os.environ.get('AR', env.get('AR')) |
| 133 | env['RANLIB'] = os.environ.get('RANLIB', env.get('RANLIB')) |
| 134 | env['CC'] = os.environ.get('CC', env.get('CC')) |
| 135 | env['LD'] = os.environ.get('LD', env.get('LD')) |
| 136 | |
| 137 | env.Append(CPPFLAGS = os.environ.get('CPPFLAGS')) |
| 138 | |
| 139 | # Always look in 'src' for include files. |
| 140 | env.Append(CPPPATH = [PROJ_SRC_DIR]) |
| 141 | env.Append(CPPFLAGS = ['-Wall', |
| 142 | '-Werror', |
| 143 | '-fdiagnostics-show-option', |
| 144 | '-Wextra', |
| 145 | '-pedantic', |
| 146 | # Explicitly enable the write-strings warning. VIXL uses |
| 147 | # const correctly when handling string constants. |
| 148 | '-Wwrite-strings']) |
| 149 | |
| 150 | target_program = env['target'] |
| 151 | build_suffix = '' |
| 152 | |
| 153 | if env['simulator'] == 'on': |
| 154 | env.Append(CPPFLAGS = ['-DUSE_SIMULATOR']) |
| 155 | build_suffix += '_sim' |
| 156 | |
| 157 | if env['mode'] == 'debug': |
| 158 | env.Append(CPPFLAGS = ['-g', '-DDEBUG']) |
| 159 | # Append the debug mode suffix to the executable name. |
| 160 | build_suffix += '_g' |
| 161 | build_dir = DEBUG_OBJ_DIR |
| 162 | elif env['mode'] == 'coverage': |
| 163 | env.Append(CPPFLAGS = ['-g', '-DDEBUG', '-fprofile-arcs', '-ftest-coverage']) |
| 164 | env.Append(LINKFLAGS = ['-fprofile-arcs']) |
| 165 | # Append the coverage mode suffix to the executable name. |
| 166 | build_suffix += '_gcov' |
| 167 | build_dir = COVERAGE_OBJ_DIR |
| 168 | else: |
| 169 | # Release mode. |
| 170 | env.Append(CPPFLAGS = ['-O3']) |
| 171 | build_dir = RELEASE_OBJ_DIR |
| 172 | # GCC 4.8 has a bug which produces a warning saying that an anonymous Operand |
| 173 | # object might be used uninitialized: |
| 174 | # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57045 |
| 175 | # The bug does not seem to appear in GCC 4.7, or in debug builds with GCC 4.8. |
| 176 | env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized']) |
| 177 | |
| 178 | |
| 179 | if target_program == 'cctest': |
| 180 | env.Append(CPPPATH = [PROJ_EXAMPLES_DIR]) |
| 181 | env.Append(CPPFLAGS = ['-DTEST_EXAMPLES']) |
| 182 | |
| 183 | # Build the library. |
| 184 | proj_library = env.Library('vixl' + build_suffix, list_target(build_dir, PROJ_SRC_FILES)) |
| 185 | |
| 186 | if target_program == 'examples': |
| 187 | # Build the examples. |
| 188 | env.Append(CPPPATH = [PROJ_EXAMPLES_DIR]) |
| 189 | for example in PROJ_EXAMPLES_SRC_FILES: |
| 190 | example_name = "example-" + os.path.splitext(os.path.basename(example))[0] |
| 191 | env.Program(example_name, list_target(build_dir, [example]) + proj_library) |
| 192 | else: |
| 193 | # Build the target program. |
| 194 | program_target_files = list_target(build_dir, TARGET_SRC_FILES[env['target']]) |
| 195 | env.Program(target_program + build_suffix, program_target_files + proj_library) |