blob: 2087a94fe466be16b8847e038a743fc2ad42a32f [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001# Copyright 2008 the V8 project authors. 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
29import re
30import sys
31import os
32from os.path import join, dirname, abspath
33from types import DictType, StringTypes
34root_dir = dirname(File('SConstruct').rfile().abspath)
35sys.path.append(join(root_dir, 'tools'))
36import js2c, utils
37
38
39# ANDROID_TOP is the top of the Android checkout, fetched from the environment
40# variable 'TOP'. You will also need to set the CXX, CC, AR and RANLIB
41# environment variables to the cross-compiling tools.
42ANDROID_TOP = os.environ.get('TOP')
43if ANDROID_TOP is None:
44 ANDROID_TOP=""
45
46# TODO: Sort these issues out properly but as a temporary solution for gcc 4.4
47# on linux we need these compiler flags to avoid crashes in the v8 test suite
48# and avoid dtoa.c strict aliasing issues
49if os.environ.get('GCC_VERSION') == '44':
50 GCC_EXTRA_CCFLAGS = ['-fno-tree-vrp']
51 GCC_DTOA_EXTRA_CCFLAGS = ['-fno-strict-aliasing']
52else:
53 GCC_EXTRA_CCFLAGS = []
54 GCC_DTOA_EXTRA_CCFLAGS = []
55
56ANDROID_FLAGS = ['-march=armv5te',
57 '-mtune=xscale',
58 '-msoft-float',
59 '-fpic',
60 '-mthumb-interwork',
61 '-funwind-tables',
62 '-fstack-protector',
63 '-fno-short-enums',
64 '-fmessage-length=0',
65 '-finline-functions',
66 '-fno-inline-functions-called-once',
67 '-fgcse-after-reload',
68 '-frerun-cse-after-loop',
69 '-frename-registers',
70 '-fomit-frame-pointer',
71 '-fno-strict-aliasing',
72 '-finline-limit=64',
73 '-MD']
74
75ANDROID_INCLUDES = [ANDROID_TOP + '/bionic/libc/arch-arm/include',
76 ANDROID_TOP + '/bionic/libc/include',
77 ANDROID_TOP + '/bionic/libstdc++/include',
78 ANDROID_TOP + '/bionic/libc/kernel/common',
79 ANDROID_TOP + '/bionic/libc/kernel/arch-arm',
80 ANDROID_TOP + '/bionic/libm/include',
81 ANDROID_TOP + '/bionic/libm/include/arch/arm',
82 ANDROID_TOP + '/bionic/libthread_db/include',
83 ANDROID_TOP + '/frameworks/base/include',
84 ANDROID_TOP + '/system/core/include']
85
86ANDROID_LINKFLAGS = ['-nostdlib',
87 '-Bdynamic',
88 '-Wl,-T,' + ANDROID_TOP + '/build/core/armelf.x',
89 '-Wl,-dynamic-linker,/system/bin/linker',
90 '-Wl,--gc-sections',
91 '-Wl,-z,nocopyreloc',
92 '-Wl,-rpath-link=' + ANDROID_TOP + '/out/target/product/generic/obj/lib',
93 ANDROID_TOP + '/out/target/product/generic/obj/lib/crtbegin_dynamic.o',
94 ANDROID_TOP + '/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a',
95 ANDROID_TOP + '/out/target/product/generic/obj/lib/crtend_android.o'];
96
97LIBRARY_FLAGS = {
98 'all': {
99 'CPPPATH': [join(root_dir, 'src')],
100 'regexp:native': {
101 'CPPDEFINES': ['V8_NATIVE_REGEXP']
102 },
103 'mode:debug': {
104 'CPPDEFINES': ['V8_ENABLE_CHECKS']
105 },
106 'profilingsupport:on': {
107 'CPPDEFINES': ['ENABLE_LOGGING_AND_PROFILING'],
108 },
109 'debuggersupport:on': {
110 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT'],
111 }
112 },
113 'gcc': {
114 'all': {
115 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
116 'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
117 },
118 'visibility:hidden': {
119 # Use visibility=default to disable this.
120 'CXXFLAGS': ['-fvisibility=hidden']
121 },
122 'mode:debug': {
123 'CCFLAGS': ['-g', '-O0'],
124 'CPPDEFINES': ['ENABLE_DISASSEMBLER', 'DEBUG'],
125 'os:android': {
126 'CCFLAGS': ['-mthumb']
127 }
128 },
129 'mode:release': {
130 'CCFLAGS': ['-O3', '-fomit-frame-pointer', '-fdata-sections',
131 '-ffunction-sections'],
132 'os:android': {
133 'CCFLAGS': ['-mthumb', '-Os'],
134 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
135 }
136 },
137 'os:linux': {
138 'CCFLAGS': ['-ansi'] + GCC_EXTRA_CCFLAGS,
139 'library:shared': {
140 'CPPDEFINES': ['V8_SHARED'],
141 'LIBS': ['pthread']
142 }
143 },
144 'os:macos': {
145 'CCFLAGS': ['-ansi', '-mmacosx-version-min=10.4'],
146 },
147 'os:freebsd': {
148 'CPPPATH' : ['/usr/local/include'],
149 'LIBPATH' : ['/usr/local/lib'],
150 'CCFLAGS': ['-ansi'],
151 },
Steve Blockd0582a62009-12-15 09:54:21 +0000152 'os:openbsd': {
153 'CPPPATH' : ['/usr/local/include'],
154 'LIBPATH' : ['/usr/local/lib'],
155 'CCFLAGS': ['-ansi'],
156 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000157 'os:win32': {
158 'CCFLAGS': ['-DWIN32'],
159 'CXXFLAGS': ['-DWIN32'],
160 },
161 'os:android': {
162 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
163 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
164 'CCFLAGS': ANDROID_FLAGS,
165 'WARNINGFLAGS': ['-Wall', '-Wno-unused', '-Werror=return-type',
166 '-Wstrict-aliasing=2'],
167 'CPPPATH': ANDROID_INCLUDES,
168 },
169 'arch:ia32': {
170 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'],
171 'CCFLAGS': ['-m32'],
172 'LINKFLAGS': ['-m32']
173 },
174 'arch:arm': {
175 'CPPDEFINES': ['V8_TARGET_ARCH_ARM']
176 },
177 'simulator:arm': {
178 'CCFLAGS': ['-m32'],
179 'LINKFLAGS': ['-m32']
180 },
181 'arch:x64': {
182 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
183 'CCFLAGS': ['-m64'],
184 'LINKFLAGS': ['-m64'],
185 },
186 'prof:oprofile': {
187 'CPPDEFINES': ['ENABLE_OPROFILE_AGENT']
188 }
189 },
190 'msvc': {
191 'all': {
192 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
193 'CXXFLAGS': ['$CCFLAGS', '/GR-', '/Gy'],
194 'CPPDEFINES': ['WIN32'],
195 'LINKFLAGS': ['/INCREMENTAL:NO', '/NXCOMPAT', '/IGNORE:4221'],
196 'CCPDBFLAGS': ['/Zi']
197 },
198 'verbose:off': {
199 'DIALECTFLAGS': ['/nologo'],
200 'ARFLAGS': ['/NOLOGO']
201 },
202 'arch:ia32': {
203 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', '_USE_32BIT_TIME_T'],
204 'LINKFLAGS': ['/MACHINE:X86'],
205 'ARFLAGS': ['/MACHINE:X86']
206 },
207 'arch:x64': {
208 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
209 'LINKFLAGS': ['/MACHINE:X64'],
210 'ARFLAGS': ['/MACHINE:X64']
211 },
212 'mode:debug': {
213 'CCFLAGS': ['/Od', '/Gm'],
214 'CPPDEFINES': ['_DEBUG', 'ENABLE_DISASSEMBLER', 'DEBUG'],
215 'LINKFLAGS': ['/DEBUG'],
216 'msvcrt:static': {
217 'CCFLAGS': ['/MTd']
218 },
219 'msvcrt:shared': {
220 'CCFLAGS': ['/MDd']
221 }
222 },
223 'mode:release': {
224 'CCFLAGS': ['/O2'],
225 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
226 'msvcrt:static': {
227 'CCFLAGS': ['/MT']
228 },
229 'msvcrt:shared': {
230 'CCFLAGS': ['/MD']
231 },
232 'msvcltcg:on': {
233 'CCFLAGS': ['/GL'],
234 'LINKFLAGS': ['/LTCG'],
235 'ARFLAGS': ['/LTCG'],
236 }
237 }
238 }
239}
240
241
242V8_EXTRA_FLAGS = {
243 'gcc': {
244 'all': {
245 'WARNINGFLAGS': ['-Wall',
246 '-Werror',
247 '-W',
248 '-Wno-unused-parameter',
249 '-Wnon-virtual-dtor']
250 },
251 'os:win32': {
252 'WARNINGFLAGS': ['-pedantic', '-Wno-long-long']
253 },
254 'os:linux': {
255 'WARNINGFLAGS': ['-pedantic'],
256 'library:shared': {
257 'soname:on': {
258 'LINKFLAGS': ['-Wl,-soname,${SONAME}']
259 }
260 }
261 },
262 'os:macos': {
263 'WARNINGFLAGS': ['-pedantic']
264 },
265 'disassembler:on': {
266 'CPPDEFINES': ['ENABLE_DISASSEMBLER']
267 }
268 },
269 'msvc': {
270 'all': {
271 'WARNINGFLAGS': ['/WX', '/wd4355', '/wd4800']
272 },
273 'library:shared': {
274 'CPPDEFINES': ['BUILDING_V8_SHARED'],
275 'LIBS': ['winmm', 'ws2_32']
276 },
277 'arch:ia32': {
278 'WARNINGFLAGS': ['/W3']
279 },
280 'arch:x64': {
Steve Blockd0582a62009-12-15 09:54:21 +0000281 'WARNINGFLAGS': ['/W3']
Steve Blocka7e24c12009-10-30 11:49:00 +0000282 },
283 'arch:arm': {
284 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'],
285 # /wd4996 is to silence the warning about sscanf
286 # used by the arm simulator.
287 'WARNINGFLAGS': ['/wd4996']
288 },
289 'disassembler:on': {
290 'CPPDEFINES': ['ENABLE_DISASSEMBLER']
291 }
292 }
293}
294
295
296MKSNAPSHOT_EXTRA_FLAGS = {
297 'gcc': {
298 'os:linux': {
299 'LIBS': ['pthread'],
300 },
301 'os:macos': {
302 'LIBS': ['pthread'],
303 },
304 'os:freebsd': {
305 'LIBS': ['execinfo', 'pthread']
306 },
Steve Blockd0582a62009-12-15 09:54:21 +0000307 'os:openbsd': {
308 'LIBS': ['execinfo', 'pthread']
309 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000310 'os:win32': {
311 'LIBS': ['winmm', 'ws2_32'],
312 },
313 },
314 'msvc': {
315 'all': {
316 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
317 'LIBS': ['winmm', 'ws2_32']
318 }
319 }
320}
321
322
323DTOA_EXTRA_FLAGS = {
324 'gcc': {
325 'all': {
326 'WARNINGFLAGS': ['-Werror', '-Wno-uninitialized'],
327 'CCFLAGS': GCC_DTOA_EXTRA_CCFLAGS
328 }
329 },
330 'msvc': {
331 'all': {
332 'WARNINGFLAGS': ['/WX', '/wd4018', '/wd4244']
333 }
334 }
335}
336
337
338CCTEST_EXTRA_FLAGS = {
339 'all': {
340 'CPPPATH': [join(root_dir, 'src')],
341 'LIBS': ['$LIBRARY']
342 },
343 'gcc': {
344 'all': {
345 'LIBPATH': [abspath('.')]
346 },
347 'os:linux': {
348 'LIBS': ['pthread'],
349 },
350 'os:macos': {
351 'LIBS': ['pthread'],
352 },
353 'os:freebsd': {
354 'LIBS': ['execinfo', 'pthread']
355 },
Steve Blockd0582a62009-12-15 09:54:21 +0000356 'os:openbsd': {
357 'LIBS': ['execinfo', 'pthread']
358 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000359 'os:win32': {
360 'LIBS': ['winmm', 'ws2_32']
361 },
362 'os:android': {
363 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
364 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
365 'CCFLAGS': ANDROID_FLAGS,
366 'CPPPATH': ANDROID_INCLUDES,
367 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
368 'LINKFLAGS': ANDROID_LINKFLAGS,
369 'LIBS': ['log', 'c', 'stdc++', 'm'],
370 'mode:release': {
371 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
372 }
373 },
374 },
375 'msvc': {
376 'all': {
377 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
378 'LIBS': ['winmm', 'ws2_32']
379 },
380 'library:shared': {
381 'CPPDEFINES': ['USING_V8_SHARED']
382 },
383 'arch:ia32': {
384 'CPPDEFINES': ['V8_TARGET_ARCH_IA32']
385 },
386 'arch:x64': {
Steve Block3ce2e202009-11-05 08:53:23 +0000387 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
388 'LINKFLAGS': ['/STACK:2091752']
Steve Blocka7e24c12009-10-30 11:49:00 +0000389 },
390 }
391}
392
393
394SAMPLE_FLAGS = {
395 'all': {
396 'CPPPATH': [join(abspath('.'), 'include')],
397 'LIBS': ['$LIBRARY'],
398 },
399 'gcc': {
400 'all': {
401 'LIBPATH': ['.'],
402 'CCFLAGS': ['-fno-rtti', '-fno-exceptions']
403 },
404 'os:linux': {
405 'LIBS': ['pthread'],
406 },
407 'os:macos': {
408 'LIBS': ['pthread'],
409 },
410 'os:freebsd': {
411 'LIBPATH' : ['/usr/local/lib'],
Steve Blockd0582a62009-12-15 09:54:21 +0000412 'LIBS': ['execinfo', 'pthread']
413 },
414 'os:openbsd': {
415 'LIBPATH' : ['/usr/local/lib'],
416 'LIBS': ['execinfo', 'pthread']
Steve Blocka7e24c12009-10-30 11:49:00 +0000417 },
418 'os:win32': {
419 'LIBS': ['winmm', 'ws2_32']
420 },
421 'os:android': {
422 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
423 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
424 'CCFLAGS': ANDROID_FLAGS,
425 'CPPPATH': ANDROID_INCLUDES,
426 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
427 'LINKFLAGS': ANDROID_LINKFLAGS,
428 'LIBS': ['log', 'c', 'stdc++', 'm'],
429 'mode:release': {
430 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
431 }
432 },
433 'arch:ia32': {
434 'CCFLAGS': ['-m32'],
435 'LINKFLAGS': ['-m32']
436 },
437 'arch:x64': {
438 'CCFLAGS': ['-m64'],
439 'LINKFLAGS': ['-m64']
440 },
441 'simulator:arm': {
442 'CCFLAGS': ['-m32'],
443 'LINKFLAGS': ['-m32']
444 },
445 'mode:release': {
446 'CCFLAGS': ['-O2']
447 },
448 'mode:debug': {
449 'CCFLAGS': ['-g', '-O0']
450 },
451 'prof:oprofile': {
452 'LIBPATH': ['/usr/lib32', '/usr/lib32/oprofile'],
453 'LIBS': ['opagent']
454 }
455 },
456 'msvc': {
457 'all': {
458 'LIBS': ['winmm', 'ws2_32']
459 },
460 'verbose:off': {
461 'CCFLAGS': ['/nologo'],
462 'LINKFLAGS': ['/NOLOGO']
463 },
464 'verbose:on': {
465 'LINKFLAGS': ['/VERBOSE']
466 },
467 'library:shared': {
468 'CPPDEFINES': ['USING_V8_SHARED']
469 },
470 'prof:on': {
471 'LINKFLAGS': ['/MAP']
472 },
473 'mode:release': {
474 'CCFLAGS': ['/O2'],
475 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
476 'msvcrt:static': {
477 'CCFLAGS': ['/MT']
478 },
479 'msvcrt:shared': {
480 'CCFLAGS': ['/MD']
481 },
482 'msvcltcg:on': {
483 'CCFLAGS': ['/GL'],
484 'LINKFLAGS': ['/LTCG'],
485 }
486 },
487 'arch:ia32': {
488 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'],
489 'LINKFLAGS': ['/MACHINE:X86']
490 },
491 'arch:x64': {
492 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
Steve Block3ce2e202009-11-05 08:53:23 +0000493 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2091752']
Steve Blocka7e24c12009-10-30 11:49:00 +0000494 },
495 'mode:debug': {
496 'CCFLAGS': ['/Od'],
497 'LINKFLAGS': ['/DEBUG'],
498 'msvcrt:static': {
499 'CCFLAGS': ['/MTd']
500 },
501 'msvcrt:shared': {
502 'CCFLAGS': ['/MDd']
503 }
504 }
505 }
506}
507
508
509D8_FLAGS = {
510 'gcc': {
511 'console:readline': {
512 'LIBS': ['readline']
513 },
514 'os:linux': {
515 'LIBS': ['pthread'],
516 },
517 'os:macos': {
518 'LIBS': ['pthread'],
519 },
520 'os:freebsd': {
521 'LIBS': ['pthread'],
522 },
Steve Blockd0582a62009-12-15 09:54:21 +0000523 'os:openbsd': {
524 'LIBS': ['pthread'],
525 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000526 'os:android': {
527 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
528 'LINKFLAGS': ANDROID_LINKFLAGS,
529 'LIBS': ['log', 'c', 'stdc++', 'm'],
530 },
531 'os:win32': {
532 'LIBS': ['winmm', 'ws2_32'],
533 },
534 },
535 'msvc': {
536 'all': {
537 'LIBS': ['winmm', 'ws2_32']
538 }
539 }
540}
541
542
543SUFFIXES = {
544 'release': '',
545 'debug': '_g'
546}
547
548
549def Abort(message):
550 print message
551 sys.exit(1)
552
553
554def GuessToolchain(os):
555 tools = Environment()['TOOLS']
556 if 'gcc' in tools:
557 return 'gcc'
558 elif 'msvc' in tools:
559 return 'msvc'
560 else:
561 return None
562
563
564OS_GUESS = utils.GuessOS()
565TOOLCHAIN_GUESS = GuessToolchain(OS_GUESS)
566ARCH_GUESS = utils.GuessArchitecture()
567
568
569SIMPLE_OPTIONS = {
570 'toolchain': {
571 'values': ['gcc', 'msvc'],
572 'default': TOOLCHAIN_GUESS,
573 'help': 'the toolchain to use (' + TOOLCHAIN_GUESS + ')'
574 },
575 'os': {
Steve Blockd0582a62009-12-15 09:54:21 +0000576 'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd'],
Steve Blocka7e24c12009-10-30 11:49:00 +0000577 'default': OS_GUESS,
578 'help': 'the os to build for (' + OS_GUESS + ')'
579 },
580 'arch': {
581 'values':['arm', 'ia32', 'x64'],
582 'default': ARCH_GUESS,
583 'help': 'the architecture to build for (' + ARCH_GUESS + ')'
584 },
585 'regexp': {
586 'values': ['native', 'interpreted'],
587 'default': 'native',
588 'help': 'Whether to use native or interpreted regexp implementation'
589 },
590 'snapshot': {
591 'values': ['on', 'off', 'nobuild'],
592 'default': 'off',
593 'help': 'build using snapshots for faster start-up'
594 },
595 'prof': {
596 'values': ['on', 'off', 'oprofile'],
597 'default': 'off',
598 'help': 'enable profiling of build target'
599 },
600 'library': {
601 'values': ['static', 'shared'],
602 'default': 'static',
603 'help': 'the type of library to produce'
604 },
605 'profilingsupport': {
606 'values': ['on', 'off'],
607 'default': 'on',
608 'help': 'enable profiling of JavaScript code'
609 },
610 'debuggersupport': {
611 'values': ['on', 'off'],
612 'default': 'on',
613 'help': 'enable debugging of JavaScript code'
614 },
615 'soname': {
616 'values': ['on', 'off'],
617 'default': 'off',
618 'help': 'turn on setting soname for Linux shared library'
619 },
620 'msvcrt': {
621 'values': ['static', 'shared'],
622 'default': 'static',
623 'help': 'the type of Microsoft Visual C++ runtime library to use'
624 },
625 'msvcltcg': {
626 'values': ['on', 'off'],
627 'default': 'on',
628 'help': 'use Microsoft Visual C++ link-time code generation'
629 },
630 'simulator': {
631 'values': ['arm', 'none'],
632 'default': 'none',
633 'help': 'build with simulator'
634 },
635 'disassembler': {
636 'values': ['on', 'off'],
637 'default': 'off',
638 'help': 'enable the disassembler to inspect generated code'
639 },
640 'sourcesignatures': {
641 'values': ['MD5', 'timestamp'],
642 'default': 'MD5',
643 'help': 'set how the build system detects file changes'
644 },
645 'console': {
646 'values': ['dumb', 'readline'],
647 'default': 'dumb',
648 'help': 'the console to use for the d8 shell'
649 },
650 'verbose': {
651 'values': ['on', 'off'],
652 'default': 'off',
653 'help': 'more output from compiler and linker'
654 },
655 'visibility': {
656 'values': ['default', 'hidden'],
657 'default': 'hidden',
658 'help': 'shared library symbol visibility'
659 }
660}
661
662
663def GetOptions():
664 result = Options()
665 result.Add('mode', 'compilation mode (debug, release)', 'release')
666 result.Add('sample', 'build sample (shell, process)', '')
667 result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '')
668 result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '')
669 for (name, option) in SIMPLE_OPTIONS.iteritems():
670 help = '%s (%s)' % (name, ", ".join(option['values']))
671 result.Add(name, help, option.get('default'))
672 return result
673
674
675def GetVersionComponents():
676 MAJOR_VERSION_PATTERN = re.compile(r"#define\s+MAJOR_VERSION\s+(.*)")
677 MINOR_VERSION_PATTERN = re.compile(r"#define\s+MINOR_VERSION\s+(.*)")
678 BUILD_NUMBER_PATTERN = re.compile(r"#define\s+BUILD_NUMBER\s+(.*)")
679 PATCH_LEVEL_PATTERN = re.compile(r"#define\s+PATCH_LEVEL\s+(.*)")
680
681 patterns = [MAJOR_VERSION_PATTERN,
682 MINOR_VERSION_PATTERN,
683 BUILD_NUMBER_PATTERN,
684 PATCH_LEVEL_PATTERN]
685
686 source = open(join(root_dir, 'src', 'version.cc')).read()
687 version_components = []
688 for pattern in patterns:
689 match = pattern.search(source)
690 if match:
691 version_components.append(match.group(1).strip())
692 else:
693 version_components.append('0')
694
695 return version_components
696
697
698def GetVersion():
699 version_components = GetVersionComponents()
700
701 if version_components[len(version_components) - 1] == '0':
702 version_components.pop()
703 return '.'.join(version_components)
704
705
706def GetSpecificSONAME():
707 SONAME_PATTERN = re.compile(r"#define\s+SONAME\s+\"(.*)\"")
708
709 source = open(join(root_dir, 'src', 'version.cc')).read()
710 match = SONAME_PATTERN.search(source)
711
712 if match:
713 return match.group(1).strip()
714 else:
715 return ''
716
717
718def SplitList(str):
719 return [ s for s in str.split(",") if len(s) > 0 ]
720
721
722def IsLegal(env, option, values):
723 str = env[option]
724 for s in SplitList(str):
725 if not s in values:
726 Abort("Illegal value for option %s '%s'." % (option, s))
727 return False
728 return True
729
730
731def VerifyOptions(env):
732 if not IsLegal(env, 'mode', ['debug', 'release']):
733 return False
734 if not IsLegal(env, 'sample', ["shell", "process"]):
735 return False
736 if not IsLegal(env, 'regexp', ["native", "interpreted"]):
737 return False
738 if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on':
739 Abort("Profiling on windows only supported for static library.")
740 if env['prof'] == 'oprofile' and env['os'] != 'linux':
741 Abort("OProfile is only supported on Linux.")
742 if env['os'] == 'win32' and env['soname'] == 'on':
743 Abort("Shared Object soname not applicable for Windows.")
744 if env['soname'] == 'on' and env['library'] == 'static':
745 Abort("Shared Object soname not applicable for static library.")
746 for (name, option) in SIMPLE_OPTIONS.iteritems():
747 if (not option.get('default')) and (name not in ARGUMENTS):
748 message = ("A value for option %s must be specified (%s)." %
749 (name, ", ".join(option['values'])))
750 Abort(message)
751 if not env[name] in option['values']:
752 message = ("Unknown %s value '%s'. Possible values are (%s)." %
753 (name, env[name], ", ".join(option['values'])))
754 Abort(message)
755
756
757class BuildContext(object):
758
759 def __init__(self, options, env_overrides, samples):
760 self.library_targets = []
761 self.mksnapshot_targets = []
762 self.cctest_targets = []
763 self.sample_targets = []
764 self.d8_targets = []
765 self.options = options
766 self.env_overrides = env_overrides
767 self.samples = samples
768 self.use_snapshot = (options['snapshot'] != 'off')
769 self.build_snapshot = (options['snapshot'] == 'on')
770 self.flags = None
771
772 def AddRelevantFlags(self, initial, flags):
773 result = initial.copy()
774 toolchain = self.options['toolchain']
775 if toolchain in flags:
776 self.AppendFlags(result, flags[toolchain].get('all'))
777 for option in sorted(self.options.keys()):
778 value = self.options[option]
779 self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
780 self.AppendFlags(result, flags.get('all'))
781 return result
782
783 def AddRelevantSubFlags(self, options, flags):
784 self.AppendFlags(options, flags.get('all'))
785 for option in sorted(self.options.keys()):
786 value = self.options[option]
787 self.AppendFlags(options, flags.get(option + ':' + value))
788
789 def GetRelevantSources(self, source):
790 result = []
791 result += source.get('all', [])
792 for (name, value) in self.options.iteritems():
793 source_value = source.get(name + ':' + value, [])
794 if type(source_value) == dict:
795 result += self.GetRelevantSources(source_value)
796 else:
797 result += source_value
798 return sorted(result)
799
800 def AppendFlags(self, options, added):
801 if not added:
802 return
803 for (key, value) in added.iteritems():
804 if key.find(':') != -1:
805 self.AddRelevantSubFlags(options, { key: value })
806 else:
807 if not key in options:
808 options[key] = value
809 else:
810 prefix = options[key]
811 if isinstance(prefix, StringTypes): prefix = prefix.split()
812 options[key] = prefix + value
813
814 def ConfigureObject(self, env, input, **kw):
815 if (kw.has_key('CPPPATH') and env.has_key('CPPPATH')):
816 kw['CPPPATH'] += env['CPPPATH']
817 if self.options['library'] == 'static':
818 return env.StaticObject(input, **kw)
819 else:
820 return env.SharedObject(input, **kw)
821
822 def ApplyEnvOverrides(self, env):
823 if not self.env_overrides:
824 return
825 if type(env['ENV']) == DictType:
826 env['ENV'].update(**self.env_overrides)
827 else:
828 env['ENV'] = self.env_overrides
829
830
831def PostprocessOptions(options):
832 # Adjust architecture if the simulator option has been set
833 if (options['simulator'] != 'none') and (options['arch'] != options['simulator']):
834 if 'arch' in ARGUMENTS:
835 # Print a warning if arch has explicitly been set
836 print "Warning: forcing architecture to match simulator (%s)" % options['simulator']
837 options['arch'] = options['simulator']
838 if (options['prof'] != 'off') and (options['profilingsupport'] == 'off'):
839 # Print a warning if profiling is enabled without profiling support
840 print "Warning: forcing profilingsupport on when prof is on"
841 options['profilingsupport'] = 'on'
842
843
844def ParseEnvOverrides(arg, imports):
845 # The environment overrides are in the format NAME0:value0,NAME1:value1,...
846 # The environment imports are in the format NAME0,NAME1,...
847 overrides = {}
848 for var in imports.split(','):
849 if var in os.environ:
850 overrides[var] = os.environ[var]
851 for override in arg.split(','):
852 pos = override.find(':')
853 if pos == -1:
854 continue
855 overrides[override[:pos].strip()] = override[pos+1:].strip()
856 return overrides
857
858
859def BuildSpecific(env, mode, env_overrides):
860 options = {'mode': mode}
861 for option in SIMPLE_OPTIONS:
862 options[option] = env[option]
863 PostprocessOptions(options)
864
865 context = BuildContext(options, env_overrides, samples=SplitList(env['sample']))
866
867 # Remove variables which can't be imported from the user's external
868 # environment into a construction environment.
869 user_environ = os.environ.copy()
870 try:
871 del user_environ['ENV']
872 except KeyError:
873 pass
874
875 library_flags = context.AddRelevantFlags(user_environ, LIBRARY_FLAGS)
876 v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
877 mksnapshot_flags = context.AddRelevantFlags(library_flags, MKSNAPSHOT_EXTRA_FLAGS)
878 dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
879 cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS)
880 sample_flags = context.AddRelevantFlags(user_environ, SAMPLE_FLAGS)
881 d8_flags = context.AddRelevantFlags(library_flags, D8_FLAGS)
882
883 context.flags = {
884 'v8': v8_flags,
885 'mksnapshot': mksnapshot_flags,
886 'dtoa': dtoa_flags,
887 'cctest': cctest_flags,
888 'sample': sample_flags,
889 'd8': d8_flags
890 }
891
892 # Generate library base name.
893 target_id = mode
894 suffix = SUFFIXES[target_id]
895 library_name = 'v8' + suffix
896 version = GetVersion()
897 if context.options['soname'] == 'on':
898 # When building shared object with SONAME version the library name.
899 library_name += '-' + version
900 env['LIBRARY'] = library_name
901
902 # Generate library SONAME if required by the build.
903 if context.options['soname'] == 'on':
904 soname = GetSpecificSONAME()
905 if soname == '':
906 soname = 'lib' + library_name + '.so'
907 env['SONAME'] = soname
908
909 # Build the object files by invoking SCons recursively.
910 (object_files, shell_files, mksnapshot) = env.SConscript(
911 join('src', 'SConscript'),
912 build_dir=join('obj', target_id),
913 exports='context',
914 duplicate=False
915 )
916
917 context.mksnapshot_targets.append(mksnapshot)
918
919 # Link the object files into a library.
920 env.Replace(**context.flags['v8'])
921 context.ApplyEnvOverrides(env)
922 if context.options['library'] == 'static':
923 library = env.StaticLibrary(library_name, object_files)
924 else:
925 # There seems to be a glitch in the way scons decides where to put
926 # PDB files when compiling using MSVC so we specify it manually.
927 # This should not affect any other platforms.
928 pdb_name = library_name + '.dll.pdb'
929 library = env.SharedLibrary(library_name, object_files, PDB=pdb_name)
930 context.library_targets.append(library)
931
932 d8_env = Environment()
933 d8_env.Replace(**context.flags['d8'])
934 shell = d8_env.Program('d8' + suffix, object_files + shell_files)
935 context.d8_targets.append(shell)
936
937 for sample in context.samples:
938 sample_env = Environment(LIBRARY=library_name)
939 sample_env.Replace(**context.flags['sample'])
940 context.ApplyEnvOverrides(sample_env)
941 sample_object = sample_env.SConscript(
942 join('samples', 'SConscript'),
943 build_dir=join('obj', 'sample', sample, target_id),
944 exports='sample context',
945 duplicate=False
946 )
947 sample_name = sample + suffix
948 sample_program = sample_env.Program(sample_name, sample_object)
949 sample_env.Depends(sample_program, library)
950 context.sample_targets.append(sample_program)
951
952 cctest_program = env.SConscript(
953 join('test', 'cctest', 'SConscript'),
954 build_dir=join('obj', 'test', target_id),
955 exports='context object_files',
956 duplicate=False
957 )
958 context.cctest_targets.append(cctest_program)
959
960 return context
961
962
963def Build():
964 opts = GetOptions()
965 env = Environment(options=opts)
966 Help(opts.GenerateHelpText(env))
967 VerifyOptions(env)
968 env_overrides = ParseEnvOverrides(env['env'], env['importenv'])
969
970 SourceSignatures(env['sourcesignatures'])
971
972 libraries = []
973 mksnapshots = []
974 cctests = []
975 samples = []
976 d8s = []
977 modes = SplitList(env['mode'])
978 for mode in modes:
979 context = BuildSpecific(env.Copy(), mode, env_overrides)
980 libraries += context.library_targets
981 mksnapshots += context.mksnapshot_targets
982 cctests += context.cctest_targets
983 samples += context.sample_targets
984 d8s += context.d8_targets
985
986 env.Alias('library', libraries)
987 env.Alias('mksnapshot', mksnapshots)
988 env.Alias('cctests', cctests)
989 env.Alias('sample', samples)
990 env.Alias('d8', d8s)
991
992 if env['sample']:
993 env.Default('sample')
994 else:
995 env.Default('library')
996
997
998# We disable deprecation warnings because we need to be able to use
999# env.Copy without getting warnings for compatibility with older
1000# version of scons. Also, there's a bug in some revisions that
1001# doesn't allow this flag to be set, so we swallow any exceptions.
1002# Lovely.
1003try:
1004 SetOption('warn', 'no-deprecated')
1005except:
1006 pass
1007
1008
1009Build()