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