blob: 739e3445caa9f3bd7a1864ea1f7f6f05b167a64a [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'],
Leon Clarkee46be812010-01-19 14:06:41 +0000146 'library:shared': {
147 'CPPDEFINES': ['V8_SHARED']
148 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000149 },
150 'os:freebsd': {
151 'CPPPATH' : ['/usr/local/include'],
152 'LIBPATH' : ['/usr/local/lib'],
153 'CCFLAGS': ['-ansi'],
154 },
Steve Blockd0582a62009-12-15 09:54:21 +0000155 'os:openbsd': {
156 'CPPPATH' : ['/usr/local/include'],
157 'LIBPATH' : ['/usr/local/lib'],
158 'CCFLAGS': ['-ansi'],
159 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000160 'os:win32': {
161 'CCFLAGS': ['-DWIN32'],
162 'CXXFLAGS': ['-DWIN32'],
163 },
164 'os:android': {
165 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
166 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
167 'CCFLAGS': ANDROID_FLAGS,
168 'WARNINGFLAGS': ['-Wall', '-Wno-unused', '-Werror=return-type',
169 '-Wstrict-aliasing=2'],
170 'CPPPATH': ANDROID_INCLUDES,
171 },
172 'arch:ia32': {
173 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'],
174 'CCFLAGS': ['-m32'],
175 'LINKFLAGS': ['-m32']
176 },
177 'arch:arm': {
178 'CPPDEFINES': ['V8_TARGET_ARCH_ARM']
179 },
180 'simulator:arm': {
181 'CCFLAGS': ['-m32'],
182 'LINKFLAGS': ['-m32']
183 },
Leon Clarkee46be812010-01-19 14:06:41 +0000184 'armvariant:thumb2': {
185 'CPPDEFINES': ['V8_ARM_VARIANT_THUMB']
186 },
187 'armvariant:arm': {
188 'CPPDEFINES': ['V8_ARM_VARIANT_ARM']
189 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 'arch:x64': {
191 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
192 'CCFLAGS': ['-m64'],
193 'LINKFLAGS': ['-m64'],
194 },
195 'prof:oprofile': {
196 'CPPDEFINES': ['ENABLE_OPROFILE_AGENT']
197 }
198 },
199 'msvc': {
200 'all': {
201 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
202 'CXXFLAGS': ['$CCFLAGS', '/GR-', '/Gy'],
203 'CPPDEFINES': ['WIN32'],
204 'LINKFLAGS': ['/INCREMENTAL:NO', '/NXCOMPAT', '/IGNORE:4221'],
205 'CCPDBFLAGS': ['/Zi']
206 },
207 'verbose:off': {
208 'DIALECTFLAGS': ['/nologo'],
209 'ARFLAGS': ['/NOLOGO']
210 },
211 'arch:ia32': {
212 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', '_USE_32BIT_TIME_T'],
213 'LINKFLAGS': ['/MACHINE:X86'],
214 'ARFLAGS': ['/MACHINE:X86']
215 },
216 'arch:x64': {
217 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
218 'LINKFLAGS': ['/MACHINE:X64'],
219 'ARFLAGS': ['/MACHINE:X64']
220 },
221 'mode:debug': {
222 'CCFLAGS': ['/Od', '/Gm'],
223 'CPPDEFINES': ['_DEBUG', 'ENABLE_DISASSEMBLER', 'DEBUG'],
224 'LINKFLAGS': ['/DEBUG'],
225 'msvcrt:static': {
226 'CCFLAGS': ['/MTd']
227 },
228 'msvcrt:shared': {
229 'CCFLAGS': ['/MDd']
230 }
231 },
232 'mode:release': {
233 'CCFLAGS': ['/O2'],
234 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
235 'msvcrt:static': {
236 'CCFLAGS': ['/MT']
237 },
238 'msvcrt:shared': {
239 'CCFLAGS': ['/MD']
240 },
241 'msvcltcg:on': {
242 'CCFLAGS': ['/GL'],
243 'LINKFLAGS': ['/LTCG'],
244 'ARFLAGS': ['/LTCG'],
245 }
246 }
247 }
248}
249
250
251V8_EXTRA_FLAGS = {
252 'gcc': {
253 'all': {
254 'WARNINGFLAGS': ['-Wall',
255 '-Werror',
256 '-W',
257 '-Wno-unused-parameter',
258 '-Wnon-virtual-dtor']
259 },
260 'os:win32': {
261 'WARNINGFLAGS': ['-pedantic', '-Wno-long-long']
262 },
263 'os:linux': {
264 'WARNINGFLAGS': ['-pedantic'],
265 'library:shared': {
266 'soname:on': {
267 'LINKFLAGS': ['-Wl,-soname,${SONAME}']
268 }
269 }
270 },
271 'os:macos': {
272 'WARNINGFLAGS': ['-pedantic']
273 },
274 'disassembler:on': {
275 'CPPDEFINES': ['ENABLE_DISASSEMBLER']
276 }
277 },
278 'msvc': {
279 'all': {
280 'WARNINGFLAGS': ['/WX', '/wd4355', '/wd4800']
281 },
282 'library:shared': {
283 'CPPDEFINES': ['BUILDING_V8_SHARED'],
284 'LIBS': ['winmm', 'ws2_32']
285 },
286 'arch:ia32': {
287 'WARNINGFLAGS': ['/W3']
288 },
289 'arch:x64': {
Steve Blockd0582a62009-12-15 09:54:21 +0000290 'WARNINGFLAGS': ['/W3']
Steve Blocka7e24c12009-10-30 11:49:00 +0000291 },
292 'arch:arm': {
293 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'],
294 # /wd4996 is to silence the warning about sscanf
295 # used by the arm simulator.
296 'WARNINGFLAGS': ['/wd4996']
297 },
298 'disassembler:on': {
299 'CPPDEFINES': ['ENABLE_DISASSEMBLER']
300 }
301 }
302}
303
304
305MKSNAPSHOT_EXTRA_FLAGS = {
306 'gcc': {
307 'os:linux': {
308 'LIBS': ['pthread'],
309 },
310 'os:macos': {
311 'LIBS': ['pthread'],
312 },
313 'os:freebsd': {
314 'LIBS': ['execinfo', 'pthread']
315 },
Steve Blockd0582a62009-12-15 09:54:21 +0000316 'os:openbsd': {
317 'LIBS': ['execinfo', 'pthread']
318 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000319 'os:win32': {
320 'LIBS': ['winmm', 'ws2_32'],
321 },
322 },
323 'msvc': {
324 'all': {
325 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
326 'LIBS': ['winmm', 'ws2_32']
327 }
328 }
329}
330
331
332DTOA_EXTRA_FLAGS = {
333 'gcc': {
334 'all': {
335 'WARNINGFLAGS': ['-Werror', '-Wno-uninitialized'],
336 'CCFLAGS': GCC_DTOA_EXTRA_CCFLAGS
337 }
338 },
339 'msvc': {
340 'all': {
341 'WARNINGFLAGS': ['/WX', '/wd4018', '/wd4244']
342 }
343 }
344}
345
346
347CCTEST_EXTRA_FLAGS = {
348 'all': {
349 'CPPPATH': [join(root_dir, 'src')],
350 'LIBS': ['$LIBRARY']
351 },
352 'gcc': {
353 'all': {
354 'LIBPATH': [abspath('.')]
355 },
356 'os:linux': {
357 'LIBS': ['pthread'],
358 },
359 'os:macos': {
360 'LIBS': ['pthread'],
361 },
362 'os:freebsd': {
363 'LIBS': ['execinfo', 'pthread']
364 },
Steve Blockd0582a62009-12-15 09:54:21 +0000365 'os:openbsd': {
366 'LIBS': ['execinfo', 'pthread']
367 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000368 'os:win32': {
369 'LIBS': ['winmm', 'ws2_32']
370 },
371 'os:android': {
372 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
373 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
374 'CCFLAGS': ANDROID_FLAGS,
375 'CPPPATH': ANDROID_INCLUDES,
376 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
377 'LINKFLAGS': ANDROID_LINKFLAGS,
378 'LIBS': ['log', 'c', 'stdc++', 'm'],
379 'mode:release': {
380 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
381 }
382 },
383 },
384 'msvc': {
385 'all': {
386 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
387 'LIBS': ['winmm', 'ws2_32']
388 },
389 'library:shared': {
390 'CPPDEFINES': ['USING_V8_SHARED']
391 },
392 'arch:ia32': {
393 'CPPDEFINES': ['V8_TARGET_ARCH_IA32']
394 },
395 'arch:x64': {
Steve Block3ce2e202009-11-05 08:53:23 +0000396 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
397 'LINKFLAGS': ['/STACK:2091752']
Steve Blocka7e24c12009-10-30 11:49:00 +0000398 },
399 }
400}
401
402
403SAMPLE_FLAGS = {
404 'all': {
405 'CPPPATH': [join(abspath('.'), 'include')],
406 'LIBS': ['$LIBRARY'],
407 },
408 'gcc': {
409 'all': {
410 'LIBPATH': ['.'],
411 'CCFLAGS': ['-fno-rtti', '-fno-exceptions']
412 },
413 'os:linux': {
414 'LIBS': ['pthread'],
415 },
416 'os:macos': {
417 'LIBS': ['pthread'],
418 },
419 'os:freebsd': {
420 'LIBPATH' : ['/usr/local/lib'],
Steve Blockd0582a62009-12-15 09:54:21 +0000421 'LIBS': ['execinfo', 'pthread']
422 },
423 'os:openbsd': {
424 'LIBPATH' : ['/usr/local/lib'],
425 'LIBS': ['execinfo', 'pthread']
Steve Blocka7e24c12009-10-30 11:49:00 +0000426 },
427 'os:win32': {
428 'LIBS': ['winmm', 'ws2_32']
429 },
430 'os:android': {
431 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
432 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
433 'CCFLAGS': ANDROID_FLAGS,
434 'CPPPATH': ANDROID_INCLUDES,
435 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
436 'LINKFLAGS': ANDROID_LINKFLAGS,
437 'LIBS': ['log', 'c', 'stdc++', 'm'],
438 'mode:release': {
439 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
440 }
441 },
442 'arch:ia32': {
443 'CCFLAGS': ['-m32'],
444 'LINKFLAGS': ['-m32']
445 },
446 'arch:x64': {
447 'CCFLAGS': ['-m64'],
448 'LINKFLAGS': ['-m64']
449 },
450 'simulator:arm': {
451 'CCFLAGS': ['-m32'],
452 'LINKFLAGS': ['-m32']
453 },
454 'mode:release': {
455 'CCFLAGS': ['-O2']
456 },
457 'mode:debug': {
458 'CCFLAGS': ['-g', '-O0']
459 },
460 'prof:oprofile': {
461 'LIBPATH': ['/usr/lib32', '/usr/lib32/oprofile'],
462 'LIBS': ['opagent']
463 }
464 },
465 'msvc': {
466 'all': {
467 'LIBS': ['winmm', 'ws2_32']
468 },
469 'verbose:off': {
470 'CCFLAGS': ['/nologo'],
471 'LINKFLAGS': ['/NOLOGO']
472 },
473 'verbose:on': {
474 'LINKFLAGS': ['/VERBOSE']
475 },
476 'library:shared': {
477 'CPPDEFINES': ['USING_V8_SHARED']
478 },
479 'prof:on': {
480 'LINKFLAGS': ['/MAP']
481 },
482 'mode:release': {
483 'CCFLAGS': ['/O2'],
484 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
485 'msvcrt:static': {
486 'CCFLAGS': ['/MT']
487 },
488 'msvcrt:shared': {
489 'CCFLAGS': ['/MD']
490 },
491 'msvcltcg:on': {
492 'CCFLAGS': ['/GL'],
493 'LINKFLAGS': ['/LTCG'],
494 }
495 },
496 'arch:ia32': {
497 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'],
498 'LINKFLAGS': ['/MACHINE:X86']
499 },
500 'arch:x64': {
501 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
Steve Block3ce2e202009-11-05 08:53:23 +0000502 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2091752']
Steve Blocka7e24c12009-10-30 11:49:00 +0000503 },
504 'mode:debug': {
505 'CCFLAGS': ['/Od'],
506 'LINKFLAGS': ['/DEBUG'],
507 'msvcrt:static': {
508 'CCFLAGS': ['/MTd']
509 },
510 'msvcrt:shared': {
511 'CCFLAGS': ['/MDd']
512 }
513 }
514 }
515}
516
517
518D8_FLAGS = {
519 'gcc': {
520 'console:readline': {
521 'LIBS': ['readline']
522 },
523 'os:linux': {
524 'LIBS': ['pthread'],
525 },
526 'os:macos': {
527 'LIBS': ['pthread'],
528 },
529 'os:freebsd': {
530 'LIBS': ['pthread'],
531 },
Steve Blockd0582a62009-12-15 09:54:21 +0000532 'os:openbsd': {
533 'LIBS': ['pthread'],
534 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000535 'os:android': {
536 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
537 'LINKFLAGS': ANDROID_LINKFLAGS,
538 'LIBS': ['log', 'c', 'stdc++', 'm'],
539 },
540 'os:win32': {
541 'LIBS': ['winmm', 'ws2_32'],
542 },
543 },
544 'msvc': {
545 'all': {
546 'LIBS': ['winmm', 'ws2_32']
547 }
548 }
549}
550
551
552SUFFIXES = {
553 'release': '',
554 'debug': '_g'
555}
556
557
558def Abort(message):
559 print message
560 sys.exit(1)
561
562
563def GuessToolchain(os):
564 tools = Environment()['TOOLS']
565 if 'gcc' in tools:
566 return 'gcc'
567 elif 'msvc' in tools:
568 return 'msvc'
569 else:
570 return None
571
572
573OS_GUESS = utils.GuessOS()
574TOOLCHAIN_GUESS = GuessToolchain(OS_GUESS)
575ARCH_GUESS = utils.GuessArchitecture()
576
577
578SIMPLE_OPTIONS = {
579 'toolchain': {
580 'values': ['gcc', 'msvc'],
581 'default': TOOLCHAIN_GUESS,
582 'help': 'the toolchain to use (' + TOOLCHAIN_GUESS + ')'
583 },
584 'os': {
Steve Blockd0582a62009-12-15 09:54:21 +0000585 'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd'],
Steve Blocka7e24c12009-10-30 11:49:00 +0000586 'default': OS_GUESS,
587 'help': 'the os to build for (' + OS_GUESS + ')'
588 },
589 'arch': {
590 'values':['arm', 'ia32', 'x64'],
591 'default': ARCH_GUESS,
592 'help': 'the architecture to build for (' + ARCH_GUESS + ')'
593 },
594 'regexp': {
595 'values': ['native', 'interpreted'],
596 'default': 'native',
597 'help': 'Whether to use native or interpreted regexp implementation'
598 },
599 'snapshot': {
600 'values': ['on', 'off', 'nobuild'],
601 'default': 'off',
602 'help': 'build using snapshots for faster start-up'
603 },
604 'prof': {
605 'values': ['on', 'off', 'oprofile'],
606 'default': 'off',
607 'help': 'enable profiling of build target'
608 },
609 'library': {
610 'values': ['static', 'shared'],
611 'default': 'static',
612 'help': 'the type of library to produce'
613 },
614 'profilingsupport': {
615 'values': ['on', 'off'],
616 'default': 'on',
617 'help': 'enable profiling of JavaScript code'
618 },
619 'debuggersupport': {
620 'values': ['on', 'off'],
621 'default': 'on',
622 'help': 'enable debugging of JavaScript code'
623 },
624 'soname': {
625 'values': ['on', 'off'],
626 'default': 'off',
627 'help': 'turn on setting soname for Linux shared library'
628 },
629 'msvcrt': {
630 'values': ['static', 'shared'],
631 'default': 'static',
632 'help': 'the type of Microsoft Visual C++ runtime library to use'
633 },
634 'msvcltcg': {
635 'values': ['on', 'off'],
636 'default': 'on',
637 'help': 'use Microsoft Visual C++ link-time code generation'
638 },
639 'simulator': {
640 'values': ['arm', 'none'],
641 'default': 'none',
642 'help': 'build with simulator'
643 },
644 'disassembler': {
645 'values': ['on', 'off'],
646 'default': 'off',
647 'help': 'enable the disassembler to inspect generated code'
648 },
649 'sourcesignatures': {
650 'values': ['MD5', 'timestamp'],
651 'default': 'MD5',
652 'help': 'set how the build system detects file changes'
653 },
654 'console': {
655 'values': ['dumb', 'readline'],
656 'default': 'dumb',
657 'help': 'the console to use for the d8 shell'
658 },
659 'verbose': {
660 'values': ['on', 'off'],
661 'default': 'off',
662 'help': 'more output from compiler and linker'
663 },
664 'visibility': {
665 'values': ['default', 'hidden'],
666 'default': 'hidden',
667 'help': 'shared library symbol visibility'
Leon Clarkee46be812010-01-19 14:06:41 +0000668 },
669 'armvariant': {
670 'values': ['arm', 'thumb2', 'none'],
671 'default': 'none',
672 'help': 'generate thumb2 instructions instead of arm instructions (default)'
Steve Blocka7e24c12009-10-30 11:49:00 +0000673 }
674}
675
676
677def GetOptions():
678 result = Options()
679 result.Add('mode', 'compilation mode (debug, release)', 'release')
Leon Clarkee46be812010-01-19 14:06:41 +0000680 result.Add('sample', 'build sample (shell, process, lineprocessor)', '')
Steve Blocka7e24c12009-10-30 11:49:00 +0000681 result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '')
682 result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '')
683 for (name, option) in SIMPLE_OPTIONS.iteritems():
684 help = '%s (%s)' % (name, ", ".join(option['values']))
685 result.Add(name, help, option.get('default'))
686 return result
687
688
689def GetVersionComponents():
690 MAJOR_VERSION_PATTERN = re.compile(r"#define\s+MAJOR_VERSION\s+(.*)")
691 MINOR_VERSION_PATTERN = re.compile(r"#define\s+MINOR_VERSION\s+(.*)")
692 BUILD_NUMBER_PATTERN = re.compile(r"#define\s+BUILD_NUMBER\s+(.*)")
693 PATCH_LEVEL_PATTERN = re.compile(r"#define\s+PATCH_LEVEL\s+(.*)")
694
695 patterns = [MAJOR_VERSION_PATTERN,
696 MINOR_VERSION_PATTERN,
697 BUILD_NUMBER_PATTERN,
698 PATCH_LEVEL_PATTERN]
699
700 source = open(join(root_dir, 'src', 'version.cc')).read()
701 version_components = []
702 for pattern in patterns:
703 match = pattern.search(source)
704 if match:
705 version_components.append(match.group(1).strip())
706 else:
707 version_components.append('0')
708
709 return version_components
710
711
712def GetVersion():
713 version_components = GetVersionComponents()
714
715 if version_components[len(version_components) - 1] == '0':
716 version_components.pop()
717 return '.'.join(version_components)
718
719
720def GetSpecificSONAME():
721 SONAME_PATTERN = re.compile(r"#define\s+SONAME\s+\"(.*)\"")
722
723 source = open(join(root_dir, 'src', 'version.cc')).read()
724 match = SONAME_PATTERN.search(source)
725
726 if match:
727 return match.group(1).strip()
728 else:
729 return ''
730
731
732def SplitList(str):
733 return [ s for s in str.split(",") if len(s) > 0 ]
734
735
736def IsLegal(env, option, values):
737 str = env[option]
738 for s in SplitList(str):
739 if not s in values:
740 Abort("Illegal value for option %s '%s'." % (option, s))
741 return False
742 return True
743
744
745def VerifyOptions(env):
746 if not IsLegal(env, 'mode', ['debug', 'release']):
747 return False
Leon Clarkee46be812010-01-19 14:06:41 +0000748 if not IsLegal(env, 'sample', ["shell", "process", "lineprocessor"]):
Steve Blocka7e24c12009-10-30 11:49:00 +0000749 return False
750 if not IsLegal(env, 'regexp', ["native", "interpreted"]):
751 return False
752 if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on':
753 Abort("Profiling on windows only supported for static library.")
754 if env['prof'] == 'oprofile' and env['os'] != 'linux':
755 Abort("OProfile is only supported on Linux.")
756 if env['os'] == 'win32' and env['soname'] == 'on':
757 Abort("Shared Object soname not applicable for Windows.")
758 if env['soname'] == 'on' and env['library'] == 'static':
759 Abort("Shared Object soname not applicable for static library.")
760 for (name, option) in SIMPLE_OPTIONS.iteritems():
761 if (not option.get('default')) and (name not in ARGUMENTS):
762 message = ("A value for option %s must be specified (%s)." %
763 (name, ", ".join(option['values'])))
764 Abort(message)
765 if not env[name] in option['values']:
766 message = ("Unknown %s value '%s'. Possible values are (%s)." %
767 (name, env[name], ", ".join(option['values'])))
768 Abort(message)
769
770
771class BuildContext(object):
772
773 def __init__(self, options, env_overrides, samples):
774 self.library_targets = []
775 self.mksnapshot_targets = []
776 self.cctest_targets = []
777 self.sample_targets = []
778 self.d8_targets = []
779 self.options = options
780 self.env_overrides = env_overrides
781 self.samples = samples
782 self.use_snapshot = (options['snapshot'] != 'off')
783 self.build_snapshot = (options['snapshot'] == 'on')
784 self.flags = None
785
786 def AddRelevantFlags(self, initial, flags):
787 result = initial.copy()
788 toolchain = self.options['toolchain']
789 if toolchain in flags:
790 self.AppendFlags(result, flags[toolchain].get('all'))
791 for option in sorted(self.options.keys()):
792 value = self.options[option]
793 self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
794 self.AppendFlags(result, flags.get('all'))
795 return result
796
797 def AddRelevantSubFlags(self, options, flags):
798 self.AppendFlags(options, flags.get('all'))
799 for option in sorted(self.options.keys()):
800 value = self.options[option]
801 self.AppendFlags(options, flags.get(option + ':' + value))
802
803 def GetRelevantSources(self, source):
804 result = []
805 result += source.get('all', [])
806 for (name, value) in self.options.iteritems():
807 source_value = source.get(name + ':' + value, [])
808 if type(source_value) == dict:
809 result += self.GetRelevantSources(source_value)
810 else:
811 result += source_value
812 return sorted(result)
813
814 def AppendFlags(self, options, added):
815 if not added:
816 return
817 for (key, value) in added.iteritems():
818 if key.find(':') != -1:
819 self.AddRelevantSubFlags(options, { key: value })
820 else:
821 if not key in options:
822 options[key] = value
823 else:
824 prefix = options[key]
825 if isinstance(prefix, StringTypes): prefix = prefix.split()
826 options[key] = prefix + value
827
828 def ConfigureObject(self, env, input, **kw):
829 if (kw.has_key('CPPPATH') and env.has_key('CPPPATH')):
830 kw['CPPPATH'] += env['CPPPATH']
831 if self.options['library'] == 'static':
832 return env.StaticObject(input, **kw)
833 else:
834 return env.SharedObject(input, **kw)
835
836 def ApplyEnvOverrides(self, env):
837 if not self.env_overrides:
838 return
839 if type(env['ENV']) == DictType:
840 env['ENV'].update(**self.env_overrides)
841 else:
842 env['ENV'] = self.env_overrides
843
844
845def PostprocessOptions(options):
846 # Adjust architecture if the simulator option has been set
847 if (options['simulator'] != 'none') and (options['arch'] != options['simulator']):
848 if 'arch' in ARGUMENTS:
849 # Print a warning if arch has explicitly been set
850 print "Warning: forcing architecture to match simulator (%s)" % options['simulator']
851 options['arch'] = options['simulator']
852 if (options['prof'] != 'off') and (options['profilingsupport'] == 'off'):
853 # Print a warning if profiling is enabled without profiling support
854 print "Warning: forcing profilingsupport on when prof is on"
855 options['profilingsupport'] = 'on'
Leon Clarkee46be812010-01-19 14:06:41 +0000856 if (options['armvariant'] == 'none' and options['arch'] == 'arm'):
857 options['armvariant'] = 'arm'
858 if (options['armvariant'] != 'none' and options['arch'] != 'arm'):
859 options['armvariant'] = 'none'
Steve Blocka7e24c12009-10-30 11:49:00 +0000860
861
862def ParseEnvOverrides(arg, imports):
863 # The environment overrides are in the format NAME0:value0,NAME1:value1,...
864 # The environment imports are in the format NAME0,NAME1,...
865 overrides = {}
866 for var in imports.split(','):
867 if var in os.environ:
868 overrides[var] = os.environ[var]
869 for override in arg.split(','):
870 pos = override.find(':')
871 if pos == -1:
872 continue
873 overrides[override[:pos].strip()] = override[pos+1:].strip()
874 return overrides
875
876
877def BuildSpecific(env, mode, env_overrides):
878 options = {'mode': mode}
879 for option in SIMPLE_OPTIONS:
880 options[option] = env[option]
881 PostprocessOptions(options)
882
883 context = BuildContext(options, env_overrides, samples=SplitList(env['sample']))
884
885 # Remove variables which can't be imported from the user's external
886 # environment into a construction environment.
887 user_environ = os.environ.copy()
888 try:
889 del user_environ['ENV']
890 except KeyError:
891 pass
892
893 library_flags = context.AddRelevantFlags(user_environ, LIBRARY_FLAGS)
894 v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
895 mksnapshot_flags = context.AddRelevantFlags(library_flags, MKSNAPSHOT_EXTRA_FLAGS)
896 dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
897 cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS)
898 sample_flags = context.AddRelevantFlags(user_environ, SAMPLE_FLAGS)
899 d8_flags = context.AddRelevantFlags(library_flags, D8_FLAGS)
900
901 context.flags = {
902 'v8': v8_flags,
903 'mksnapshot': mksnapshot_flags,
904 'dtoa': dtoa_flags,
905 'cctest': cctest_flags,
906 'sample': sample_flags,
907 'd8': d8_flags
908 }
909
910 # Generate library base name.
911 target_id = mode
912 suffix = SUFFIXES[target_id]
913 library_name = 'v8' + suffix
914 version = GetVersion()
915 if context.options['soname'] == 'on':
916 # When building shared object with SONAME version the library name.
917 library_name += '-' + version
918 env['LIBRARY'] = library_name
919
920 # Generate library SONAME if required by the build.
921 if context.options['soname'] == 'on':
922 soname = GetSpecificSONAME()
923 if soname == '':
924 soname = 'lib' + library_name + '.so'
925 env['SONAME'] = soname
926
927 # Build the object files by invoking SCons recursively.
928 (object_files, shell_files, mksnapshot) = env.SConscript(
929 join('src', 'SConscript'),
930 build_dir=join('obj', target_id),
931 exports='context',
932 duplicate=False
933 )
934
935 context.mksnapshot_targets.append(mksnapshot)
936
937 # Link the object files into a library.
938 env.Replace(**context.flags['v8'])
939 context.ApplyEnvOverrides(env)
940 if context.options['library'] == 'static':
941 library = env.StaticLibrary(library_name, object_files)
942 else:
943 # There seems to be a glitch in the way scons decides where to put
944 # PDB files when compiling using MSVC so we specify it manually.
945 # This should not affect any other platforms.
946 pdb_name = library_name + '.dll.pdb'
947 library = env.SharedLibrary(library_name, object_files, PDB=pdb_name)
948 context.library_targets.append(library)
949
950 d8_env = Environment()
951 d8_env.Replace(**context.flags['d8'])
Leon Clarkee46be812010-01-19 14:06:41 +0000952 context.ApplyEnvOverrides(d8_env)
Steve Blocka7e24c12009-10-30 11:49:00 +0000953 shell = d8_env.Program('d8' + suffix, object_files + shell_files)
954 context.d8_targets.append(shell)
955
956 for sample in context.samples:
957 sample_env = Environment(LIBRARY=library_name)
958 sample_env.Replace(**context.flags['sample'])
959 context.ApplyEnvOverrides(sample_env)
960 sample_object = sample_env.SConscript(
961 join('samples', 'SConscript'),
962 build_dir=join('obj', 'sample', sample, target_id),
963 exports='sample context',
964 duplicate=False
965 )
966 sample_name = sample + suffix
967 sample_program = sample_env.Program(sample_name, sample_object)
968 sample_env.Depends(sample_program, library)
969 context.sample_targets.append(sample_program)
970
971 cctest_program = env.SConscript(
972 join('test', 'cctest', 'SConscript'),
973 build_dir=join('obj', 'test', target_id),
974 exports='context object_files',
975 duplicate=False
976 )
977 context.cctest_targets.append(cctest_program)
978
979 return context
980
981
982def Build():
983 opts = GetOptions()
984 env = Environment(options=opts)
985 Help(opts.GenerateHelpText(env))
986 VerifyOptions(env)
987 env_overrides = ParseEnvOverrides(env['env'], env['importenv'])
988
989 SourceSignatures(env['sourcesignatures'])
990
991 libraries = []
992 mksnapshots = []
993 cctests = []
994 samples = []
995 d8s = []
996 modes = SplitList(env['mode'])
997 for mode in modes:
998 context = BuildSpecific(env.Copy(), mode, env_overrides)
999 libraries += context.library_targets
1000 mksnapshots += context.mksnapshot_targets
1001 cctests += context.cctest_targets
1002 samples += context.sample_targets
1003 d8s += context.d8_targets
1004
1005 env.Alias('library', libraries)
1006 env.Alias('mksnapshot', mksnapshots)
1007 env.Alias('cctests', cctests)
1008 env.Alias('sample', samples)
1009 env.Alias('d8', d8s)
1010
1011 if env['sample']:
1012 env.Default('sample')
1013 else:
1014 env.Default('library')
1015
1016
1017# We disable deprecation warnings because we need to be able to use
1018# env.Copy without getting warnings for compatibility with older
1019# version of scons. Also, there's a bug in some revisions that
1020# doesn't allow this flag to be set, so we swallow any exceptions.
1021# Lovely.
1022try:
1023 SetOption('warn', 'no-deprecated')
1024except:
1025 pass
1026
1027
1028Build()