blob: 18cc5fb4da01fba52756cf501900d6a6117d38a0 [file] [log] [blame]
armvixlad96eda2013-06-14 11:42:37 +01001# 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
27import os
28import os.path
armvixl4a102ba2014-07-14 09:02:40 +010029import subprocess
armvixlad96eda2013-06-14 11:42:37 +010030import sys
31
armvixl4a102ba2014-07-14 09:02:40 +010032root_dir = os.path.dirname(File('SConstruct').rfile().abspath)
33sys.path.insert(0, os.path.join(root_dir, 'tools'))
34import util
35
armvixlad96eda2013-06-14 11:42:37 +010036# Global configuration.
37PROJ_SRC_DIR = 'src'
38PROJ_SRC_FILES = '''
39src/utils.cc
40src/a64/assembler-a64.cc
41src/a64/macro-assembler-a64.cc
42src/a64/instructions-a64.cc
43src/a64/decoder-a64.cc
44src/a64/debugger-a64.cc
45src/a64/disasm-a64.cc
46src/a64/cpu-a64.cc
47src/a64/simulator-a64.cc
armvixl578645f2013-08-15 17:21:42 +010048src/a64/instrument-a64.cc
armvixlad96eda2013-06-14 11:42:37 +010049'''.split()
50PROJ_EXAMPLES_DIR = 'examples'
51PROJ_EXAMPLES_SRC_FILES = '''
52examples/debugger.cc
53examples/add3-double.cc
54examples/add4-double.cc
55examples/factorial-rec.cc
56examples/factorial.cc
57examples/sum-array.cc
58examples/abs.cc
59examples/swap4.cc
60examples/swap-int32.cc
61examples/check-bounds.cc
62examples/getting-started.cc
63'''.split()
64# List target specific files.
65# Target names are used as dictionary entries.
66TARGET_SRC_DIR = {
67 'cctest': 'test',
armvixl4a102ba2014-07-14 09:02:40 +010068 'bench-dataop': 'benchmarks',
69 'bench-branch': 'benchmarks',
70 'bench-branch-link': 'benchmarks',
armvixlad96eda2013-06-14 11:42:37 +010071 'examples': 'examples'
72}
73TARGET_SRC_FILES = {
74 'cctest': '''
75 test/cctest.cc
76 test/test-utils-a64.cc
77 test/test-assembler-a64.cc
armvixlb0c8ae22014-03-21 14:03:59 +000078 test/test-simulator-a64.cc
armvixlad96eda2013-06-14 11:42:37 +010079 test/test-disasm-a64.cc
armvixl578645f2013-08-15 17:21:42 +010080 test/test-fuzz-a64.cc
armvixlad96eda2013-06-14 11:42:37 +010081 test/examples/test-examples.cc
armvixl4a102ba2014-07-14 09:02:40 +010082 '''.split(),
83 'bench-dataop': '''
armvixlad96eda2013-06-14 11:42:37 +010084 benchmarks/bench-dataop.cc
85 '''.split(),
armvixl4a102ba2014-07-14 09:02:40 +010086 'bench-branch': '''
armvixlad96eda2013-06-14 11:42:37 +010087 benchmarks/bench-branch.cc
armvixl4a102ba2014-07-14 09:02:40 +010088 '''.split(),
89 'bench-branch-link': '''
90 benchmarks/bench-branch-link.cc
armvixlad96eda2013-06-14 11:42:37 +010091 '''.split()
92}
93RELEASE_OBJ_DIR = 'obj/release'
94DEBUG_OBJ_DIR = 'obj/debug'
armvixlad96eda2013-06-14 11:42:37 +010095
96
97# Helper functions.
98def abort(message):
99 print('ABORTING: ' + message)
100 sys.exit(1)
101
102
103def list_target(obj_dir, src_files):
104 return map(lambda x: os.path.join(obj_dir, x), src_files)
105
106
107def 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.
114args = Variables()
115args.Add(EnumVariable('mode', 'Build mode', 'release',
armvixl4a102ba2014-07-14 09:02:40 +0100116 allowed_values = ['release', 'debug']))
armvixlad96eda2013-06-14 11:42:37 +0100117args.Add(EnumVariable('simulator', 'build for the simulator', 'on',
118 allowed_values = ['on', 'off']))
armvixl4a102ba2014-07-14 09:02:40 +0100119args.Add(BoolVariable('list_targets', 'List top level targets available.', 0))
armvixlad96eda2013-06-14 11:42:37 +0100120
121# Configure the environment.
122create_variant(RELEASE_OBJ_DIR, TARGET_SRC_DIR)
123create_variant(DEBUG_OBJ_DIR, TARGET_SRC_DIR)
armvixlad96eda2013-06-14 11:42:37 +0100124env = Environment(variables=args)
125
126# Commandline help.
127Help(args.GenerateHelpText(env))
128
129# Abort if any invalid argument was passed.
130# This check must happened after an environment is created.
131unknown_arg = args.UnknownVariables()
132if unknown_arg:
133 abort('Unknown variable(s): ' + str(unknown_arg.keys()))
134
135# Setup tools.
136# This is necessary for cross-compilation.
137env['CXX'] = os.environ.get('CXX', env.get('CXX'))
138env['AR'] = os.environ.get('AR', env.get('AR'))
139env['RANLIB'] = os.environ.get('RANLIB', env.get('RANLIB'))
140env['CC'] = os.environ.get('CC', env.get('CC'))
141env['LD'] = os.environ.get('LD', env.get('LD'))
142
armvixlb0c8ae22014-03-21 14:03:59 +0000143if os.environ.get('CPPFLAGS'):
144 env.Append(CPPFLAGS = os.environ.get('CPPFLAGS').split())
145if os.environ.get('LINKFLAGS'):
146 env.Append(LINKFLAGS = os.environ.get('LINKFLAGS').split())
armvixlad96eda2013-06-14 11:42:37 +0100147
148# Always look in 'src' for include files.
149env.Append(CPPPATH = [PROJ_SRC_DIR])
150env.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
armvixlad96eda2013-06-14 11:42:37 +0100159build_suffix = ''
160
armvixl4a102ba2014-07-14 09:02:40 +0100161
armvixlad96eda2013-06-14 11:42:37 +0100162if env['simulator'] == 'on':
163 env.Append(CPPFLAGS = ['-DUSE_SIMULATOR'])
164 build_suffix += '_sim'
165
166if 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
armvixlad96eda2013-06-14 11:42:37 +0100171else:
172 # Release mode.
173 env.Append(CPPFLAGS = ['-O3'])
174 build_dir = RELEASE_OBJ_DIR
armvixl4a102ba2014-07-14 09:02:40 +0100175 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'])
armvixlad96eda2013-06-14 11:42:37 +0100187
188
armvixl4a102ba2014-07-14 09:02:40 +0100189# The lists of available targets and target names.
190targets = []
191target_alias_names = []
192# Helper to create aliases.
193def create_alias(name, target):
194 env.Alias(name, target)
195 targets.append(target)
196 target_alias_names.append(name)
armvixlad96eda2013-06-14 11:42:37 +0100197
armvixlad96eda2013-06-14 11:42:37 +0100198
armvixl4a102ba2014-07-14 09:02:40 +0100199# The vixl library.
200libvixl = env.Library('vixl' + build_suffix,
201 list_target(build_dir, PROJ_SRC_FILES))
202create_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.
208cctest_ex_vdir = os.path.join(build_dir, 'cctest_examples')
209VariantDir(cctest_ex_vdir, '.')
210cctest_ex_obj = env.Object(list_target(cctest_ex_vdir, PROJ_EXAMPLES_SRC_FILES),
211 CPPFLAGS = env['CPPFLAGS'] + ['-DTEST_EXAMPLES'])
212cctest = 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])
216create_alias('cctest', cctest)
217
218# The benchmarks.
219for 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.
225examples = []
226for 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.
234create_alias('examples', examples)
235
236
237# Create a simple alias to build everything with the current options.
238create_alias('all', targets)
239
240if 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.
246Default(libvixl, cctest)