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 |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 29 | import subprocess |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 30 | import sys |
| 31 | |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 32 | root_dir = os.path.dirname(File('SConstruct').rfile().abspath) |
| 33 | sys.path.insert(0, os.path.join(root_dir, 'tools')) |
| 34 | import util |
| 35 | |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 36 | # Global configuration. |
| 37 | PROJ_SRC_DIR = 'src' |
| 38 | PROJ_SRC_FILES = ''' |
| 39 | src/utils.cc |
| 40 | src/a64/assembler-a64.cc |
| 41 | src/a64/macro-assembler-a64.cc |
| 42 | src/a64/instructions-a64.cc |
| 43 | src/a64/decoder-a64.cc |
| 44 | src/a64/debugger-a64.cc |
| 45 | src/a64/disasm-a64.cc |
| 46 | src/a64/cpu-a64.cc |
| 47 | src/a64/simulator-a64.cc |
armvixl | 578645f | 2013-08-15 17:21:42 +0100 | [diff] [blame] | 48 | src/a64/instrument-a64.cc |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 49 | '''.split() |
| 50 | PROJ_EXAMPLES_DIR = 'examples' |
| 51 | PROJ_EXAMPLES_SRC_FILES = ''' |
| 52 | examples/debugger.cc |
| 53 | examples/add3-double.cc |
| 54 | examples/add4-double.cc |
| 55 | examples/factorial-rec.cc |
| 56 | examples/factorial.cc |
| 57 | examples/sum-array.cc |
| 58 | examples/abs.cc |
| 59 | examples/swap4.cc |
| 60 | examples/swap-int32.cc |
| 61 | examples/check-bounds.cc |
| 62 | examples/getting-started.cc |
| 63 | '''.split() |
| 64 | # List target specific files. |
| 65 | # Target names are used as dictionary entries. |
| 66 | TARGET_SRC_DIR = { |
| 67 | 'cctest': 'test', |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 68 | 'bench-dataop': 'benchmarks', |
| 69 | 'bench-branch': 'benchmarks', |
| 70 | 'bench-branch-link': 'benchmarks', |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 71 | 'examples': 'examples' |
| 72 | } |
| 73 | TARGET_SRC_FILES = { |
| 74 | 'cctest': ''' |
| 75 | test/cctest.cc |
| 76 | test/test-utils-a64.cc |
| 77 | test/test-assembler-a64.cc |
armvixl | b0c8ae2 | 2014-03-21 14:03:59 +0000 | [diff] [blame] | 78 | test/test-simulator-a64.cc |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 79 | test/test-disasm-a64.cc |
armvixl | 578645f | 2013-08-15 17:21:42 +0100 | [diff] [blame] | 80 | test/test-fuzz-a64.cc |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 81 | test/examples/test-examples.cc |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 82 | '''.split(), |
| 83 | 'bench-dataop': ''' |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 84 | benchmarks/bench-dataop.cc |
| 85 | '''.split(), |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 86 | 'bench-branch': ''' |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 87 | benchmarks/bench-branch.cc |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 88 | '''.split(), |
| 89 | 'bench-branch-link': ''' |
| 90 | benchmarks/bench-branch-link.cc |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 91 | '''.split() |
| 92 | } |
| 93 | RELEASE_OBJ_DIR = 'obj/release' |
| 94 | DEBUG_OBJ_DIR = 'obj/debug' |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 95 | |
| 96 | |
| 97 | # Helper functions. |
| 98 | def abort(message): |
| 99 | print('ABORTING: ' + message) |
| 100 | sys.exit(1) |
| 101 | |
| 102 | |
| 103 | def list_target(obj_dir, src_files): |
| 104 | return map(lambda x: os.path.join(obj_dir, x), src_files) |
| 105 | |
| 106 | |
| 107 | def create_variant(obj_dir, targets_dir): |
| 108 | VariantDir(os.path.join(obj_dir, PROJ_SRC_DIR), PROJ_SRC_DIR) |
| 109 | for directory in targets_dir.itervalues(): |
| 110 | VariantDir(os.path.join(obj_dir, directory), directory) |
| 111 | |
| 112 | |
| 113 | # Build arguments. |
| 114 | args = Variables() |
| 115 | args.Add(EnumVariable('mode', 'Build mode', 'release', |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 116 | allowed_values = ['release', 'debug'])) |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 117 | args.Add(EnumVariable('simulator', 'build for the simulator', 'on', |
| 118 | allowed_values = ['on', 'off'])) |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 119 | args.Add(BoolVariable('list_targets', 'List top level targets available.', 0)) |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 120 | |
| 121 | # Configure the environment. |
| 122 | create_variant(RELEASE_OBJ_DIR, TARGET_SRC_DIR) |
| 123 | create_variant(DEBUG_OBJ_DIR, TARGET_SRC_DIR) |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 124 | env = Environment(variables=args) |
| 125 | |
| 126 | # Commandline help. |
| 127 | Help(args.GenerateHelpText(env)) |
| 128 | |
| 129 | # Abort if any invalid argument was passed. |
| 130 | # This check must happened after an environment is created. |
| 131 | unknown_arg = args.UnknownVariables() |
| 132 | if unknown_arg: |
| 133 | abort('Unknown variable(s): ' + str(unknown_arg.keys())) |
| 134 | |
| 135 | # Setup tools. |
| 136 | # This is necessary for cross-compilation. |
| 137 | env['CXX'] = os.environ.get('CXX', env.get('CXX')) |
| 138 | env['AR'] = os.environ.get('AR', env.get('AR')) |
| 139 | env['RANLIB'] = os.environ.get('RANLIB', env.get('RANLIB')) |
| 140 | env['CC'] = os.environ.get('CC', env.get('CC')) |
| 141 | env['LD'] = os.environ.get('LD', env.get('LD')) |
| 142 | |
armvixl | b0c8ae2 | 2014-03-21 14:03:59 +0000 | [diff] [blame] | 143 | if os.environ.get('CPPFLAGS'): |
| 144 | env.Append(CPPFLAGS = os.environ.get('CPPFLAGS').split()) |
| 145 | if os.environ.get('LINKFLAGS'): |
| 146 | env.Append(LINKFLAGS = os.environ.get('LINKFLAGS').split()) |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 147 | |
| 148 | # Always look in 'src' for include files. |
| 149 | env.Append(CPPPATH = [PROJ_SRC_DIR]) |
| 150 | env.Append(CPPFLAGS = ['-Wall', |
| 151 | '-Werror', |
| 152 | '-fdiagnostics-show-option', |
| 153 | '-Wextra', |
| 154 | '-pedantic', |
| 155 | # Explicitly enable the write-strings warning. VIXL uses |
| 156 | # const correctly when handling string constants. |
| 157 | '-Wwrite-strings']) |
| 158 | |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 159 | build_suffix = '' |
| 160 | |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 161 | |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 162 | if env['simulator'] == 'on': |
| 163 | env.Append(CPPFLAGS = ['-DUSE_SIMULATOR']) |
| 164 | build_suffix += '_sim' |
| 165 | |
| 166 | if env['mode'] == 'debug': |
| 167 | env.Append(CPPFLAGS = ['-g', '-DDEBUG']) |
| 168 | # Append the debug mode suffix to the executable name. |
| 169 | build_suffix += '_g' |
| 170 | build_dir = DEBUG_OBJ_DIR |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 171 | else: |
| 172 | # Release mode. |
| 173 | env.Append(CPPFLAGS = ['-O3']) |
| 174 | build_dir = RELEASE_OBJ_DIR |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 175 | process = subprocess.Popen(env['CXX'] + ' --version | grep "gnu.*4\.8"', |
| 176 | shell = True, |
| 177 | stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| 178 | stdout, stderr = process.communicate() |
| 179 | using_gcc48 = stdout != '' |
| 180 | if using_gcc48: |
| 181 | # GCC 4.8 has a bug which produces a warning saying that an anonymous |
| 182 | # Operand object might be used uninitialized: |
| 183 | # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57045 |
| 184 | # The bug does not seem to appear in GCC 4.7, or in debug builds with |
| 185 | # GCC 4.8. |
| 186 | env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized']) |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 187 | |
| 188 | |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 189 | # The lists of available targets and target names. |
| 190 | targets = [] |
| 191 | target_alias_names = [] |
| 192 | # Helper to create aliases. |
| 193 | def create_alias(name, target): |
| 194 | env.Alias(name, target) |
| 195 | targets.append(target) |
| 196 | target_alias_names.append(name) |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 197 | |
armvixl | ad96eda | 2013-06-14 11:42:37 +0100 | [diff] [blame] | 198 | |
armvixl | 4a102ba | 2014-07-14 09:02:40 +0100 | [diff] [blame^] | 199 | # The vixl library. |
| 200 | libvixl = env.Library('vixl' + build_suffix, |
| 201 | list_target(build_dir, PROJ_SRC_FILES)) |
| 202 | create_alias('libvixl', libvixl) |
| 203 | |
| 204 | |
| 205 | # The cctest executable. |
| 206 | # The cctest requires building the example files with specific options, so we |
| 207 | # create a separate variant dir for the example objects built this way. |
| 208 | cctest_ex_vdir = os.path.join(build_dir, 'cctest_examples') |
| 209 | VariantDir(cctest_ex_vdir, '.') |
| 210 | cctest_ex_obj = env.Object(list_target(cctest_ex_vdir, PROJ_EXAMPLES_SRC_FILES), |
| 211 | CPPFLAGS = env['CPPFLAGS'] + ['-DTEST_EXAMPLES']) |
| 212 | cctest = env.Program('cctest' + build_suffix, |
| 213 | list_target(build_dir, TARGET_SRC_FILES['cctest']) + |
| 214 | cctest_ex_obj + libvixl, |
| 215 | CPPPATH = env['CPPPATH'] + [PROJ_EXAMPLES_DIR]) |
| 216 | create_alias('cctest', cctest) |
| 217 | |
| 218 | # The benchmarks. |
| 219 | for bench in ['bench-dataop', 'bench-branch', 'bench-branch-link']: |
| 220 | prog = env.Program(bench + build_suffix, |
| 221 | list_target(build_dir, TARGET_SRC_FILES[bench]) + libvixl) |
| 222 | create_alias(bench, prog) |
| 223 | |
| 224 | # The examples. |
| 225 | examples = [] |
| 226 | for example in PROJ_EXAMPLES_SRC_FILES: |
| 227 | example_name = "example-" + os.path.splitext(os.path.basename(example))[0] |
| 228 | prog = env.Program(example_name, |
| 229 | [os.path.join(build_dir, example)] + libvixl, |
| 230 | CPPPATH = env['CPPPATH'] + [PROJ_EXAMPLES_DIR]) |
| 231 | create_alias(example_name, prog) |
| 232 | examples.append(prog) |
| 233 | # Alias to build all examples. |
| 234 | create_alias('examples', examples) |
| 235 | |
| 236 | |
| 237 | # Create a simple alias to build everything with the current options. |
| 238 | create_alias('all', targets) |
| 239 | |
| 240 | if env['list_targets']: |
| 241 | print 'Available targets:' |
| 242 | print '\t' + '\n\t'.join(target_alias_names) |
| 243 | sys.exit(0); |
| 244 | |
| 245 | # By default, only build the cctests. |
| 246 | Default(libvixl, cctest) |