blob: 6bb23ce09dea2040b78ded0a4d460f05f704180a [file] [log] [blame]
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001# Copyright 2008 Google Inc. All rights reserved.
2# Redistribution and use in source and binary forms, with or without
3# modification, are permitted provided that the following conditions are
4# met:
5#
6# * Redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer.
8# * Redistributions in binary form must reproduce the above
9# copyright notice, this list of conditions and the following
10# disclaimer in the documentation and/or other materials provided
11# with the distribution.
12# * Neither the name of Google Inc. nor the names of its
13# contributors may be used to endorse or promote products derived
14# from this software without specific prior written permission.
15#
16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28import platform
kasper.lund212ac232008-07-16 07:07:30 +000029import re
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000030import sys
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000031import os
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032from os.path import join, dirname, abspath
33root_dir = dirname(File('SConstruct').rfile().abspath)
34sys.path.append(join(root_dir, 'tools'))
35import js2c
36
37
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000038LIBRARY_FLAGS = {
39 'all': {
40 'CPPDEFINES': ['ENABLE_LOGGING_AND_PROFILING']
41 },
42 'gcc': {
43 'all': {
44 'DIALECTFLAGS': ['-ansi'],
45 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS',
46 '-fno-strict-aliasing'],
47 'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
48 'LIBS': ['pthread']
49 },
50 'mode:debug': {
51 'CCFLAGS': ['-g', '-O0'],
52 'CPPDEFINES': ['ENABLE_DISASSEMBLER', 'DEBUG']
53 },
54 'mode:release': {
55 'CCFLAGS': ['-O2']
56 },
57 'wordsize:64': {
58 'CCFLAGS': ['-m32']
59 },
60 },
61 'msvc': {
62 'all': {
63 'DIALECTFLAGS': ['/nologo'],
64 'WARNINGFLAGS': ['/W3', '/WX', '/wd4355', '/wd4800'],
65 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
v8.team.kasperl727e9952008-09-02 14:56:44 +000066 'CXXFLAGS': ['$CCFLAGS', '/GR-', '/Gy'],
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000067 'CPPDEFINES': ['WIN32', '_CRT_SECURE_NO_DEPRECATE',
68 '_CRT_NONSTDC_NO_DEPRECATE', '_USE_32BIT_TIME_T',
69 'PCRE_STATIC'],
70 'LINKFLAGS': ['/NOLOGO', '/MACHINE:X86', '/INCREMENTAL:NO',
71 '/NXCOMPAT', '/IGNORE:4221'],
72 'ARFLAGS': ['/NOLOGO'],
73 'CCPDBFLAGS': ['/Zi']
74 },
75 'mode:debug': {
76 'CCFLAGS': ['/Od', '/Gm', '/MTd'],
77 'CPPDEFINES': ['_DEBUG', 'ENABLE_DISASSEMBLER', 'DEBUG'],
78 'LINKFLAGS': ['/DEBUG']
79 },
80 'mode:release': {
81 'CCFLAGS': ['/Ox', '/MT', '/Ob2', '/Oi', '/Oy'],
v8.team.kasperl727e9952008-09-02 14:56:44 +000082 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF']
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000083 }
84 }
85}
86
87
88V8_EXTRA_FLAGS = {
89 'gcc': {
90 'all': {
91 'CXXFLAGS': [], #['-fvisibility=hidden'],
92 'WARNINGFLAGS': ['-pedantic', '-Wall', '-Werror', '-W',
93 '-Wno-unused-parameter']
94 },
95 'arch:arm': {
96 'CPPDEFINES': ['ARM']
97 },
98 },
99 'msvc': {
100 'all': {
101 'WARNINGFLAGS': ['/W3', '/WX', '/wd4355', '/wd4800']
102 },
103 'library:shared': {
104 'CPPDEFINES': ['BUILDING_V8_SHARED']
105 },
106 'arch:arm': {
107 'CPPDEFINES': ['ARM']
108 },
109 }
110}
111
112
113JSCRE_EXTRA_FLAGS = {
114 'gcc': {
115 'all': {
116 'CPPDEFINES': ['SUPPORT_UTF8', 'NO_RECURSE', 'SUPPORT_UCP'],
117 'WARNINGFLAGS': ['-w']
118 },
119 },
120 'msvc': {
121 'all': {
122 'CPPDEFINES': ['SUPPORT_UTF8', 'NO_RECURSE', 'SUPPORT_UCP'],
123 'WARNINGFLAGS': ['/W3', '/WX', '/wd4355', '/wd4800']
124 },
125 'library:shared': {
126 'CPPDEFINES': ['BUILDING_V8_SHARED']
127 }
128 }
129}
130
131
132DTOA_EXTRA_FLAGS = {
133 'gcc': {
134 'all': {
135 'WARNINGFLAGS': ['-Werror']
136 }
137 },
138 'msvc': {
139 'all': {
140 'WARNINGFLAGS': ['/WX', '/wd4018', '/wd4244']
141 }
142 }
143}
144
145
146CCTEST_EXTRA_FLAGS = {
147 'all': {
148 'CPPPATH': [join(root_dir, 'src')],
149 'LIBS': ['$LIBRARY']
150 },
151 'gcc': {
152 'all': {
153 'LIBPATH': [abspath('.')]
154 },
155 'wordsize:64': {
156 'CCFLAGS': ['-m32'],
157 'LINKFLAGS': ['-m32']
158 },
159 },
160 'msvc': {
161 'all': {
162 'CPPDEFINES': ['_HAS_EXCEPTIONS=0']
163 },
164 'library:shared': {
165 'CPPDEFINES': ['USING_V8_SHARED']
166 }
167 }
168}
169
170
171SAMPLE_FLAGS = {
172 'all': {
v8.team.kasperl727e9952008-09-02 14:56:44 +0000173 'CPPPATH': [join(abspath('.'), 'include')],
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000174 'LIBS': ['$LIBRARY'],
175 },
176 'gcc': {
177 'all': {
178 'LIBS': ['pthread'],
179 'LIBPATH': ['.']
180 },
181 'wordsize:64': {
182 'CCFLAGS': ['-m32'],
183 'LINKFLAGS': ['-m32']
184 },
185 },
186 'msvc': {
187 'all': {
188 'CCFLAGS': ['/nologo'],
189 },
190 'library:shared': {
191 'CPPDEFINES': ['USING_V8_SHARED']
192 },
193 'mode:release': {
194 'CCFLAGS': ['/MT'],
195 },
196 'mode:debug': {
197 'CCFLAGS': ['/MTd']
198 }
199 }
200}
201
202
203SUFFIXES = {
204 'release': '',
205 'debug': '_g'
206}
207
208
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000209def Abort(message):
210 print message
211 sys.exit(1)
212
213
214def GuessOS():
215 id = platform.system()
216 if id == 'Linux':
217 return 'linux'
218 elif id == 'Darwin':
219 return 'macos'
220 elif id == 'Windows':
221 return 'win32'
222 else:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000223 return None
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224
225
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000226def GuessArchitecture():
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000227 id = platform.machine()
228 if id.startswith('arm'):
229 return 'arm'
kasper.lund212ac232008-07-16 07:07:30 +0000230 elif (not id) or (not re.match('(x|i[3-6])86', id) is None):
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231 return 'ia32'
232 else:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000233 return None
234
235
236def GuessWordsize():
237 if '64' in platform.machine():
238 return '64'
239 else:
240 return '32'
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000241
242
243def GuessToolchain(os):
244 tools = Environment()['TOOLS']
245 if 'gcc' in tools:
kasper.lund7276f142008-07-30 08:49:36 +0000246 return 'gcc'
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247 elif 'msvc' in tools:
248 return 'msvc'
249 else:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000250 return None
251
252
253OS_GUESS = GuessOS()
254TOOLCHAIN_GUESS = GuessToolchain(OS_GUESS)
255ARCH_GUESS = GuessArchitecture()
256WORDSIZE_GUESS = GuessWordsize()
257
258
259SIMPLE_OPTIONS = {
260 'toolchain': {
261 'values': ['gcc', 'msvc'],
262 'default': TOOLCHAIN_GUESS,
263 'help': 'the toolchain to use'
264 },
265 'os': {
266 'values': ['linux', 'macos', 'win32'],
267 'default': OS_GUESS,
268 'help': 'the os to build for'
269 },
270 'arch': {
271 'values':['arm', 'ia32'],
272 'default': ARCH_GUESS,
273 'help': 'the architecture to build for'
274 },
275 'snapshot': {
276 'values': ['on', 'off'],
277 'default': 'off',
278 'help': 'build using snapshots for faster start-up'
279 },
280 'library': {
281 'values': ['static', 'shared'],
282 'default': 'static',
283 'help': 'the type of library to produce'
284 },
285 'wordsize': {
286 'values': ['64', '32'],
287 'default': WORDSIZE_GUESS,
288 'help': 'the word size'
289 },
290 'simulator': {
291 'values': ['arm', 'none'],
292 'default': 'none',
293 'help': 'build with simulator'
294 }
295}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000296
297
298def GetOptions():
299 result = Options()
kasper.lund7276f142008-07-30 08:49:36 +0000300 result.Add('mode', 'compilation mode (debug, release)', 'release')
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000301 result.Add('sample', 'build sample (shell, process)', '')
v8.team.kasperl727e9952008-09-02 14:56:44 +0000302 result.Add('env', 'override environment settings (NAME1:value1,NAME2:value2)', '')
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000303 for (name, option) in SIMPLE_OPTIONS.items():
304 help = '%s (%s)' % (name, ", ".join(option['values']))
305 result.Add(name, help, option.get('default'))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306 return result
307
308
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000309def SplitList(str):
310 return [ s for s in str.split(",") if len(s) > 0 ]
311
312
313def IsLegal(env, option, values):
314 str = env[option]
315 for s in SplitList(str):
316 if not s in values:
317 Abort("Illegal value for option %s '%s'." % (option, s))
318 return False
319 return True
320
321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322def VerifyOptions(env):
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000323 if not IsLegal(env, 'mode', ['debug', 'release']):
324 return False
325 if not IsLegal(env, 'sample', ["shell", "process"]):
326 return False
327 for (name, option) in SIMPLE_OPTIONS.items():
328 if (not option.get('default')) and (name not in ARGUMENTS):
329 message = ("A value for option %s must be specified (%s)." %
330 (name, ", ".join(option['values'])))
331 Abort(message)
332 if not env[name] in option['values']:
333 message = ("Unknown %s value '%s'. Possible values are (%s)." %
334 (name, env[name], ", ".join(option['values'])))
335 Abort(message)
336
337
338class BuildContext(object):
339
v8.team.kasperl727e9952008-09-02 14:56:44 +0000340 def __init__(self, options, env_overrides, samples):
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000341 self.library_targets = []
342 self.cctest_targets = []
343 self.sample_targets = []
344 self.options = options
v8.team.kasperl727e9952008-09-02 14:56:44 +0000345 self.env_overrides = env_overrides
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000346 self.samples = samples
347 self.use_snapshot = (options['snapshot'] == 'on')
348 self.flags = None
349
350 def AddRelevantFlags(self, initial, flags):
351 result = initial.copy()
352 self.AppendFlags(result, flags.get('all'))
353 toolchain = self.options['toolchain']
354 self.AppendFlags(result, flags[toolchain].get('all'))
355 for option in sorted(self.options.keys()):
356 value = self.options[option]
357 self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
358 return result
359
360 def GetRelevantSources(self, source):
361 result = []
362 result += source.get('all', [])
363 for (name, value) in self.options.items():
364 result += source.get(name + ':' + value, [])
365 return sorted(result)
366
367 def AppendFlags(self, options, added):
368 if not added:
369 return
370 for (key, value) in added.items():
371 if not key in options:
372 options[key] = value
373 else:
374 options[key] = options[key] + value
375
376 def ConfigureObject(self, env, input, **kw):
377 if self.options['library'] == 'static':
378 return env.StaticObject(input, **kw)
379 else:
380 return env.SharedObject(input, **kw)
381
382
383def PostprocessOptions(options):
384 # Adjust architecture if the simulator option has been set
385 if (options['simulator'] != 'none') and (options['arch'] != options['simulator']):
386 if 'arch' in ARGUMENTS:
387 # Print a warning if arch has explicitly been set
388 print "Warning: forcing architecture to match simulator (%s)" % options['simulator']
389 options['arch'] = options['simulator']
390
391
v8.team.kasperl727e9952008-09-02 14:56:44 +0000392def ParseEnvOverrides(arg):
393 # The environment overrides are in the format NAME1:value1,NAME2:value2
394 overrides = {}
395 for override in arg.split(','):
396 pos = override.find(':')
397 if pos == -1:
398 continue
399 overrides[override[:pos].strip()] = override[pos+1:].strip()
400 return overrides
401
402
403def BuildSpecific(env, mode, env_overrides):
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000404 options = {'mode': mode}
405 for option in SIMPLE_OPTIONS:
406 options[option] = env[option]
407 PostprocessOptions(options)
408
v8.team.kasperl727e9952008-09-02 14:56:44 +0000409 context = BuildContext(options, env_overrides, samples=SplitList(env['sample']))
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000410
411 library_flags = context.AddRelevantFlags(os.environ, LIBRARY_FLAGS)
412 v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
413 jscre_flags = context.AddRelevantFlags(library_flags, JSCRE_EXTRA_FLAGS)
414 dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
415 cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS)
416 sample_flags = context.AddRelevantFlags(os.environ, SAMPLE_FLAGS)
417
418 context.flags = {
419 'v8': v8_flags,
420 'jscre': jscre_flags,
421 'dtoa': dtoa_flags,
422 'cctest': cctest_flags,
423 'sample': sample_flags
424 }
425
426 target_id = mode
427 suffix = SUFFIXES[target_id]
428 library_name = 'v8' + suffix
429 env['LIBRARY'] = library_name
430
431 # Build the object files by invoking SCons recursively.
432 object_files = env.SConscript(
433 join('src', 'SConscript'),
434 build_dir=join('obj', target_id),
435 exports='context',
436 duplicate=False
437 )
438
439 # Link the object files into a library.
440 if context.options['library'] == 'static':
441 library = env.StaticLibrary(library_name, object_files)
442 else:
443 # There seems to be a glitch in the way scons decides where to put
444 # PDB files when compiling using MSVC so we specify it manually.
445 # This should not affect any other platforms.
446 pdb_name = library_name + '.dll.pdb'
447 library = env.SharedLibrary(library_name, object_files, PDB=pdb_name)
448 context.library_targets.append(library)
449
450 for sample in context.samples:
451 sample_env = Environment(LIBRARY=library_name)
452 sample_env.Replace(**context.flags['sample'])
v8.team.kasperl727e9952008-09-02 14:56:44 +0000453 sample_env['ENV'].update(**context.env_overrides)
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000454 sample_object = sample_env.SConscript(
455 join('samples', 'SConscript'),
456 build_dir=join('obj', 'sample', sample, target_id),
457 exports='sample context',
458 duplicate=False
459 )
460 sample_name = sample + suffix
461 sample_program = sample_env.Program(sample_name, sample_object)
462 sample_env.Depends(sample_program, library)
463 context.sample_targets.append(sample_program)
464
465 cctest_program = env.SConscript(
466 join('test', 'cctest', 'SConscript'),
467 build_dir=join('obj', 'test', target_id),
468 exports='context object_files',
469 duplicate=False
470 )
471 context.cctest_targets.append(cctest_program)
472
473 return context
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474
475
kasper.lund7276f142008-07-30 08:49:36 +0000476def Build():
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 opts = GetOptions()
478 env = Environment(options=opts)
479 Help(opts.GenerateHelpText(env))
480 VerifyOptions(env)
v8.team.kasperl727e9952008-09-02 14:56:44 +0000481 env_overrides = ParseEnvOverrides(env['env'])
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000482
483 libraries = []
484 cctests = []
485 samples = []
486 modes = SplitList(env['mode'])
487 for mode in modes:
v8.team.kasperl727e9952008-09-02 14:56:44 +0000488 context = BuildSpecific(env.Copy(), mode, env_overrides)
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000489 libraries += context.library_targets
490 cctests += context.cctest_targets
491 samples += context.sample_targets
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000493 env.Alias('library', libraries)
494 env.Alias('cctests', cctests)
495 env.Alias('sample', samples)
496
497 if env['sample']:
498 env.Default('sample')
kasper.lund7276f142008-07-30 08:49:36 +0000499 else:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000500 env.Default('library')
kasper.lund7276f142008-07-30 08:49:36 +0000501
502
v8.team.kasperl727e9952008-09-02 14:56:44 +0000503# We disable deprecation warnings because we need to be able to use
504# env.Copy without getting warnings for compatibility with older
505# version of scons. Also, there's a bug in some revisions that
506# doesn't allow this flag to be set, so we swallow any exceptions.
507# Lovely.
508try:
509 SetOption('warn', 'no-deprecated')
510except:
511 pass
512
513
kasper.lund7276f142008-07-30 08:49:36 +0000514Build()