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