blob: c9c5a55c85d3ba61fecff498e1e4a4c4080bdc3f [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 Clarked91b9f72010-01-27 17:25:45 +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': {
Leon Clarked91b9f72010-01-27 17:25:45 +0000284 'WARNINGFLAGS': ['/W3', '/WX', '/wd4355', '/wd4800']
Steve Blocka7e24c12009-10-30 11:49:00 +0000285 },
286 'library:shared': {
287 'CPPDEFINES': ['BUILDING_V8_SHARED'],
288 'LIBS': ['winmm', 'ws2_32']
289 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000290 'arch:arm': {
291 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'],
292 # /wd4996 is to silence the warning about sscanf
293 # used by the arm simulator.
294 'WARNINGFLAGS': ['/wd4996']
295 },
296 'disassembler:on': {
297 'CPPDEFINES': ['ENABLE_DISASSEMBLER']
298 }
299 }
300}
301
302
303MKSNAPSHOT_EXTRA_FLAGS = {
304 'gcc': {
305 'os:linux': {
306 'LIBS': ['pthread'],
307 },
308 'os:macos': {
309 'LIBS': ['pthread'],
310 },
311 'os:freebsd': {
312 'LIBS': ['execinfo', 'pthread']
313 },
Leon Clarked91b9f72010-01-27 17:25:45 +0000314 'os:solaris': {
315 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'],
316 'LINKFLAGS': ['-mt']
317 },
Steve Blockd0582a62009-12-15 09:54:21 +0000318 'os:openbsd': {
319 'LIBS': ['execinfo', 'pthread']
320 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000321 'os:win32': {
322 'LIBS': ['winmm', 'ws2_32'],
323 },
324 },
325 'msvc': {
326 'all': {
327 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
328 'LIBS': ['winmm', 'ws2_32']
329 }
330 }
331}
332
333
334DTOA_EXTRA_FLAGS = {
335 'gcc': {
336 'all': {
337 'WARNINGFLAGS': ['-Werror', '-Wno-uninitialized'],
338 'CCFLAGS': GCC_DTOA_EXTRA_CCFLAGS
339 }
340 },
341 'msvc': {
342 'all': {
343 'WARNINGFLAGS': ['/WX', '/wd4018', '/wd4244']
344 }
345 }
346}
347
348
349CCTEST_EXTRA_FLAGS = {
350 'all': {
351 'CPPPATH': [join(root_dir, 'src')],
352 'LIBS': ['$LIBRARY']
353 },
354 'gcc': {
355 'all': {
356 'LIBPATH': [abspath('.')]
357 },
358 'os:linux': {
359 'LIBS': ['pthread'],
360 },
361 'os:macos': {
362 'LIBS': ['pthread'],
363 },
364 'os:freebsd': {
365 'LIBS': ['execinfo', 'pthread']
366 },
Leon Clarked91b9f72010-01-27 17:25:45 +0000367 'os:solaris': {
368 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'],
369 'LINKFLAGS': ['-mt']
370 },
Steve Blockd0582a62009-12-15 09:54:21 +0000371 'os:openbsd': {
372 'LIBS': ['execinfo', 'pthread']
373 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000374 'os:win32': {
375 'LIBS': ['winmm', 'ws2_32']
376 },
377 'os:android': {
378 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
379 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
380 'CCFLAGS': ANDROID_FLAGS,
381 'CPPPATH': ANDROID_INCLUDES,
382 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
383 'LINKFLAGS': ANDROID_LINKFLAGS,
384 'LIBS': ['log', 'c', 'stdc++', 'm'],
385 'mode:release': {
386 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
387 }
388 },
389 },
390 'msvc': {
391 'all': {
392 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
393 'LIBS': ['winmm', 'ws2_32']
394 },
395 'library:shared': {
396 'CPPDEFINES': ['USING_V8_SHARED']
397 },
398 'arch:ia32': {
399 'CPPDEFINES': ['V8_TARGET_ARCH_IA32']
400 },
401 'arch:x64': {
Steve Block3ce2e202009-11-05 08:53:23 +0000402 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
403 'LINKFLAGS': ['/STACK:2091752']
Steve Blocka7e24c12009-10-30 11:49:00 +0000404 },
405 }
406}
407
408
409SAMPLE_FLAGS = {
410 'all': {
411 'CPPPATH': [join(abspath('.'), 'include')],
412 'LIBS': ['$LIBRARY'],
413 },
414 'gcc': {
415 'all': {
416 'LIBPATH': ['.'],
417 'CCFLAGS': ['-fno-rtti', '-fno-exceptions']
418 },
419 'os:linux': {
420 'LIBS': ['pthread'],
421 },
422 'os:macos': {
423 'LIBS': ['pthread'],
424 },
425 'os:freebsd': {
426 'LIBPATH' : ['/usr/local/lib'],
Steve Blockd0582a62009-12-15 09:54:21 +0000427 'LIBS': ['execinfo', 'pthread']
428 },
Leon Clarked91b9f72010-01-27 17:25:45 +0000429 'os:solaris': {
430 'LIBPATH' : ['/usr/local/lib'],
431 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'],
432 'LINKFLAGS': ['-mt']
433 },
Steve Blockd0582a62009-12-15 09:54:21 +0000434 'os:openbsd': {
435 'LIBPATH' : ['/usr/local/lib'],
436 'LIBS': ['execinfo', 'pthread']
Steve Blocka7e24c12009-10-30 11:49:00 +0000437 },
438 'os:win32': {
439 'LIBS': ['winmm', 'ws2_32']
440 },
441 'os:android': {
442 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
443 '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
444 'CCFLAGS': ANDROID_FLAGS,
445 'CPPPATH': ANDROID_INCLUDES,
446 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
447 'LINKFLAGS': ANDROID_LINKFLAGS,
448 'LIBS': ['log', 'c', 'stdc++', 'm'],
449 'mode:release': {
450 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG']
451 }
452 },
453 'arch:ia32': {
454 'CCFLAGS': ['-m32'],
455 'LINKFLAGS': ['-m32']
456 },
457 'arch:x64': {
458 'CCFLAGS': ['-m64'],
459 'LINKFLAGS': ['-m64']
460 },
461 'simulator:arm': {
462 'CCFLAGS': ['-m32'],
463 'LINKFLAGS': ['-m32']
464 },
465 'mode:release': {
466 'CCFLAGS': ['-O2']
467 },
468 'mode:debug': {
469 'CCFLAGS': ['-g', '-O0']
470 },
471 'prof:oprofile': {
472 'LIBPATH': ['/usr/lib32', '/usr/lib32/oprofile'],
473 'LIBS': ['opagent']
474 }
475 },
476 'msvc': {
477 'all': {
478 'LIBS': ['winmm', 'ws2_32']
479 },
480 'verbose:off': {
481 'CCFLAGS': ['/nologo'],
482 'LINKFLAGS': ['/NOLOGO']
483 },
484 'verbose:on': {
485 'LINKFLAGS': ['/VERBOSE']
486 },
487 'library:shared': {
488 'CPPDEFINES': ['USING_V8_SHARED']
489 },
490 'prof:on': {
491 'LINKFLAGS': ['/MAP']
492 },
493 'mode:release': {
494 'CCFLAGS': ['/O2'],
495 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
496 'msvcrt:static': {
497 'CCFLAGS': ['/MT']
498 },
499 'msvcrt:shared': {
500 'CCFLAGS': ['/MD']
501 },
502 'msvcltcg:on': {
503 'CCFLAGS': ['/GL'],
504 'LINKFLAGS': ['/LTCG'],
505 }
506 },
507 'arch:ia32': {
508 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'],
509 'LINKFLAGS': ['/MACHINE:X86']
510 },
511 'arch:x64': {
512 'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
Steve Block3ce2e202009-11-05 08:53:23 +0000513 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2091752']
Steve Blocka7e24c12009-10-30 11:49:00 +0000514 },
515 'mode:debug': {
516 'CCFLAGS': ['/Od'],
517 'LINKFLAGS': ['/DEBUG'],
518 'msvcrt:static': {
519 'CCFLAGS': ['/MTd']
520 },
521 'msvcrt:shared': {
522 'CCFLAGS': ['/MDd']
523 }
524 }
525 }
526}
527
528
529D8_FLAGS = {
530 'gcc': {
531 'console:readline': {
532 'LIBS': ['readline']
533 },
534 'os:linux': {
535 'LIBS': ['pthread'],
536 },
537 'os:macos': {
538 'LIBS': ['pthread'],
539 },
540 'os:freebsd': {
541 'LIBS': ['pthread'],
542 },
Leon Clarked91b9f72010-01-27 17:25:45 +0000543 'os:solaris': {
544 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'],
545 'LINKFLAGS': ['-mt']
546 },
Steve Blockd0582a62009-12-15 09:54:21 +0000547 'os:openbsd': {
548 'LIBS': ['pthread'],
549 },
Steve Blocka7e24c12009-10-30 11:49:00 +0000550 'os:android': {
551 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib'],
552 'LINKFLAGS': ANDROID_LINKFLAGS,
553 'LIBS': ['log', 'c', 'stdc++', 'm'],
554 },
555 'os:win32': {
556 'LIBS': ['winmm', 'ws2_32'],
557 },
558 },
559 'msvc': {
560 'all': {
561 'LIBS': ['winmm', 'ws2_32']
562 }
563 }
564}
565
566
567SUFFIXES = {
568 'release': '',
569 'debug': '_g'
570}
571
572
573def Abort(message):
574 print message
575 sys.exit(1)
576
577
578def GuessToolchain(os):
579 tools = Environment()['TOOLS']
580 if 'gcc' in tools:
581 return 'gcc'
582 elif 'msvc' in tools:
583 return 'msvc'
584 else:
585 return None
586
587
588OS_GUESS = utils.GuessOS()
589TOOLCHAIN_GUESS = GuessToolchain(OS_GUESS)
590ARCH_GUESS = utils.GuessArchitecture()
591
592
593SIMPLE_OPTIONS = {
594 'toolchain': {
595 'values': ['gcc', 'msvc'],
596 'default': TOOLCHAIN_GUESS,
597 'help': 'the toolchain to use (' + TOOLCHAIN_GUESS + ')'
598 },
599 'os': {
Leon Clarked91b9f72010-01-27 17:25:45 +0000600 'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd', 'solaris'],
Steve Blocka7e24c12009-10-30 11:49:00 +0000601 'default': OS_GUESS,
602 'help': 'the os to build for (' + OS_GUESS + ')'
603 },
604 'arch': {
605 'values':['arm', 'ia32', 'x64'],
606 'default': ARCH_GUESS,
607 'help': 'the architecture to build for (' + ARCH_GUESS + ')'
608 },
609 'regexp': {
610 'values': ['native', 'interpreted'],
611 'default': 'native',
612 'help': 'Whether to use native or interpreted regexp implementation'
613 },
614 'snapshot': {
615 'values': ['on', 'off', 'nobuild'],
616 'default': 'off',
617 'help': 'build using snapshots for faster start-up'
618 },
619 'prof': {
620 'values': ['on', 'off', 'oprofile'],
621 'default': 'off',
622 'help': 'enable profiling of build target'
623 },
624 'library': {
625 'values': ['static', 'shared'],
626 'default': 'static',
627 'help': 'the type of library to produce'
628 },
629 'profilingsupport': {
630 'values': ['on', 'off'],
631 'default': 'on',
632 'help': 'enable profiling of JavaScript code'
633 },
634 'debuggersupport': {
635 'values': ['on', 'off'],
636 'default': 'on',
637 'help': 'enable debugging of JavaScript code'
638 },
639 'soname': {
640 'values': ['on', 'off'],
641 'default': 'off',
642 'help': 'turn on setting soname for Linux shared library'
643 },
644 'msvcrt': {
645 'values': ['static', 'shared'],
646 'default': 'static',
647 'help': 'the type of Microsoft Visual C++ runtime library to use'
648 },
649 'msvcltcg': {
650 'values': ['on', 'off'],
651 'default': 'on',
652 'help': 'use Microsoft Visual C++ link-time code generation'
653 },
654 'simulator': {
655 'values': ['arm', 'none'],
656 'default': 'none',
657 'help': 'build with simulator'
658 },
659 'disassembler': {
660 'values': ['on', 'off'],
661 'default': 'off',
662 'help': 'enable the disassembler to inspect generated code'
663 },
664 'sourcesignatures': {
665 'values': ['MD5', 'timestamp'],
666 'default': 'MD5',
667 'help': 'set how the build system detects file changes'
668 },
669 'console': {
670 'values': ['dumb', 'readline'],
671 'default': 'dumb',
672 'help': 'the console to use for the d8 shell'
673 },
674 'verbose': {
675 'values': ['on', 'off'],
676 'default': 'off',
677 'help': 'more output from compiler and linker'
678 },
679 'visibility': {
680 'values': ['default', 'hidden'],
681 'default': 'hidden',
682 'help': 'shared library symbol visibility'
Leon Clarkee46be812010-01-19 14:06:41 +0000683 },
684 'armvariant': {
685 'values': ['arm', 'thumb2', 'none'],
686 'default': 'none',
687 'help': 'generate thumb2 instructions instead of arm instructions (default)'
Steve Blocka7e24c12009-10-30 11:49:00 +0000688 }
689}
690
691
692def GetOptions():
693 result = Options()
694 result.Add('mode', 'compilation mode (debug, release)', 'release')
Leon Clarkee46be812010-01-19 14:06:41 +0000695 result.Add('sample', 'build sample (shell, process, lineprocessor)', '')
Steve Blocka7e24c12009-10-30 11:49:00 +0000696 result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '')
697 result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '')
698 for (name, option) in SIMPLE_OPTIONS.iteritems():
699 help = '%s (%s)' % (name, ", ".join(option['values']))
700 result.Add(name, help, option.get('default'))
701 return result
702
703
704def GetVersionComponents():
705 MAJOR_VERSION_PATTERN = re.compile(r"#define\s+MAJOR_VERSION\s+(.*)")
706 MINOR_VERSION_PATTERN = re.compile(r"#define\s+MINOR_VERSION\s+(.*)")
707 BUILD_NUMBER_PATTERN = re.compile(r"#define\s+BUILD_NUMBER\s+(.*)")
708 PATCH_LEVEL_PATTERN = re.compile(r"#define\s+PATCH_LEVEL\s+(.*)")
709
710 patterns = [MAJOR_VERSION_PATTERN,
711 MINOR_VERSION_PATTERN,
712 BUILD_NUMBER_PATTERN,
713 PATCH_LEVEL_PATTERN]
714
715 source = open(join(root_dir, 'src', 'version.cc')).read()
716 version_components = []
717 for pattern in patterns:
718 match = pattern.search(source)
719 if match:
720 version_components.append(match.group(1).strip())
721 else:
722 version_components.append('0')
723
724 return version_components
725
726
727def GetVersion():
728 version_components = GetVersionComponents()
729
730 if version_components[len(version_components) - 1] == '0':
731 version_components.pop()
732 return '.'.join(version_components)
733
734
735def GetSpecificSONAME():
736 SONAME_PATTERN = re.compile(r"#define\s+SONAME\s+\"(.*)\"")
737
738 source = open(join(root_dir, 'src', 'version.cc')).read()
739 match = SONAME_PATTERN.search(source)
740
741 if match:
742 return match.group(1).strip()
743 else:
744 return ''
745
746
747def SplitList(str):
748 return [ s for s in str.split(",") if len(s) > 0 ]
749
750
751def IsLegal(env, option, values):
752 str = env[option]
753 for s in SplitList(str):
754 if not s in values:
755 Abort("Illegal value for option %s '%s'." % (option, s))
756 return False
757 return True
758
759
760def VerifyOptions(env):
761 if not IsLegal(env, 'mode', ['debug', 'release']):
762 return False
Leon Clarkee46be812010-01-19 14:06:41 +0000763 if not IsLegal(env, 'sample', ["shell", "process", "lineprocessor"]):
Steve Blocka7e24c12009-10-30 11:49:00 +0000764 return False
765 if not IsLegal(env, 'regexp', ["native", "interpreted"]):
766 return False
767 if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on':
768 Abort("Profiling on windows only supported for static library.")
769 if env['prof'] == 'oprofile' and env['os'] != 'linux':
770 Abort("OProfile is only supported on Linux.")
771 if env['os'] == 'win32' and env['soname'] == 'on':
772 Abort("Shared Object soname not applicable for Windows.")
773 if env['soname'] == 'on' and env['library'] == 'static':
774 Abort("Shared Object soname not applicable for static library.")
775 for (name, option) in SIMPLE_OPTIONS.iteritems():
776 if (not option.get('default')) and (name not in ARGUMENTS):
777 message = ("A value for option %s must be specified (%s)." %
778 (name, ", ".join(option['values'])))
779 Abort(message)
780 if not env[name] in option['values']:
781 message = ("Unknown %s value '%s'. Possible values are (%s)." %
782 (name, env[name], ", ".join(option['values'])))
783 Abort(message)
784
785
786class BuildContext(object):
787
788 def __init__(self, options, env_overrides, samples):
789 self.library_targets = []
790 self.mksnapshot_targets = []
791 self.cctest_targets = []
792 self.sample_targets = []
793 self.d8_targets = []
794 self.options = options
795 self.env_overrides = env_overrides
796 self.samples = samples
797 self.use_snapshot = (options['snapshot'] != 'off')
798 self.build_snapshot = (options['snapshot'] == 'on')
799 self.flags = None
800
801 def AddRelevantFlags(self, initial, flags):
802 result = initial.copy()
803 toolchain = self.options['toolchain']
804 if toolchain in flags:
805 self.AppendFlags(result, flags[toolchain].get('all'))
806 for option in sorted(self.options.keys()):
807 value = self.options[option]
808 self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
809 self.AppendFlags(result, flags.get('all'))
810 return result
811
812 def AddRelevantSubFlags(self, options, flags):
813 self.AppendFlags(options, flags.get('all'))
814 for option in sorted(self.options.keys()):
815 value = self.options[option]
816 self.AppendFlags(options, flags.get(option + ':' + value))
817
818 def GetRelevantSources(self, source):
819 result = []
820 result += source.get('all', [])
821 for (name, value) in self.options.iteritems():
822 source_value = source.get(name + ':' + value, [])
823 if type(source_value) == dict:
824 result += self.GetRelevantSources(source_value)
825 else:
826 result += source_value
827 return sorted(result)
828
829 def AppendFlags(self, options, added):
830 if not added:
831 return
832 for (key, value) in added.iteritems():
833 if key.find(':') != -1:
834 self.AddRelevantSubFlags(options, { key: value })
835 else:
836 if not key in options:
837 options[key] = value
838 else:
839 prefix = options[key]
840 if isinstance(prefix, StringTypes): prefix = prefix.split()
841 options[key] = prefix + value
842
843 def ConfigureObject(self, env, input, **kw):
844 if (kw.has_key('CPPPATH') and env.has_key('CPPPATH')):
845 kw['CPPPATH'] += env['CPPPATH']
846 if self.options['library'] == 'static':
847 return env.StaticObject(input, **kw)
848 else:
849 return env.SharedObject(input, **kw)
850
851 def ApplyEnvOverrides(self, env):
852 if not self.env_overrides:
853 return
854 if type(env['ENV']) == DictType:
855 env['ENV'].update(**self.env_overrides)
856 else:
857 env['ENV'] = self.env_overrides
858
859
860def PostprocessOptions(options):
861 # Adjust architecture if the simulator option has been set
862 if (options['simulator'] != 'none') and (options['arch'] != options['simulator']):
863 if 'arch' in ARGUMENTS:
864 # Print a warning if arch has explicitly been set
865 print "Warning: forcing architecture to match simulator (%s)" % options['simulator']
866 options['arch'] = options['simulator']
867 if (options['prof'] != 'off') and (options['profilingsupport'] == 'off'):
868 # Print a warning if profiling is enabled without profiling support
869 print "Warning: forcing profilingsupport on when prof is on"
870 options['profilingsupport'] = 'on'
Leon Clarkee46be812010-01-19 14:06:41 +0000871 if (options['armvariant'] == 'none' and options['arch'] == 'arm'):
872 options['armvariant'] = 'arm'
873 if (options['armvariant'] != 'none' and options['arch'] != 'arm'):
874 options['armvariant'] = 'none'
Steve Blocka7e24c12009-10-30 11:49:00 +0000875
876
877def ParseEnvOverrides(arg, imports):
878 # The environment overrides are in the format NAME0:value0,NAME1:value1,...
879 # The environment imports are in the format NAME0,NAME1,...
880 overrides = {}
881 for var in imports.split(','):
882 if var in os.environ:
883 overrides[var] = os.environ[var]
884 for override in arg.split(','):
885 pos = override.find(':')
886 if pos == -1:
887 continue
888 overrides[override[:pos].strip()] = override[pos+1:].strip()
889 return overrides
890
891
892def BuildSpecific(env, mode, env_overrides):
893 options = {'mode': mode}
894 for option in SIMPLE_OPTIONS:
895 options[option] = env[option]
896 PostprocessOptions(options)
897
898 context = BuildContext(options, env_overrides, samples=SplitList(env['sample']))
899
900 # Remove variables which can't be imported from the user's external
901 # environment into a construction environment.
902 user_environ = os.environ.copy()
903 try:
904 del user_environ['ENV']
905 except KeyError:
906 pass
907
908 library_flags = context.AddRelevantFlags(user_environ, LIBRARY_FLAGS)
909 v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
910 mksnapshot_flags = context.AddRelevantFlags(library_flags, MKSNAPSHOT_EXTRA_FLAGS)
911 dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
912 cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS)
913 sample_flags = context.AddRelevantFlags(user_environ, SAMPLE_FLAGS)
914 d8_flags = context.AddRelevantFlags(library_flags, D8_FLAGS)
915
916 context.flags = {
917 'v8': v8_flags,
918 'mksnapshot': mksnapshot_flags,
919 'dtoa': dtoa_flags,
920 'cctest': cctest_flags,
921 'sample': sample_flags,
922 'd8': d8_flags
923 }
924
925 # Generate library base name.
926 target_id = mode
927 suffix = SUFFIXES[target_id]
928 library_name = 'v8' + suffix
929 version = GetVersion()
930 if context.options['soname'] == 'on':
931 # When building shared object with SONAME version the library name.
932 library_name += '-' + version
933 env['LIBRARY'] = library_name
934
935 # Generate library SONAME if required by the build.
936 if context.options['soname'] == 'on':
937 soname = GetSpecificSONAME()
938 if soname == '':
939 soname = 'lib' + library_name + '.so'
940 env['SONAME'] = soname
941
942 # Build the object files by invoking SCons recursively.
943 (object_files, shell_files, mksnapshot) = env.SConscript(
944 join('src', 'SConscript'),
945 build_dir=join('obj', target_id),
946 exports='context',
947 duplicate=False
948 )
949
950 context.mksnapshot_targets.append(mksnapshot)
951
952 # Link the object files into a library.
953 env.Replace(**context.flags['v8'])
Leon Clarked91b9f72010-01-27 17:25:45 +0000954
Steve Blocka7e24c12009-10-30 11:49:00 +0000955 context.ApplyEnvOverrides(env)
956 if context.options['library'] == 'static':
957 library = env.StaticLibrary(library_name, object_files)
958 else:
959 # There seems to be a glitch in the way scons decides where to put
960 # PDB files when compiling using MSVC so we specify it manually.
961 # This should not affect any other platforms.
962 pdb_name = library_name + '.dll.pdb'
963 library = env.SharedLibrary(library_name, object_files, PDB=pdb_name)
964 context.library_targets.append(library)
965
966 d8_env = Environment()
967 d8_env.Replace(**context.flags['d8'])
Leon Clarkee46be812010-01-19 14:06:41 +0000968 context.ApplyEnvOverrides(d8_env)
Steve Blocka7e24c12009-10-30 11:49:00 +0000969 shell = d8_env.Program('d8' + suffix, object_files + shell_files)
970 context.d8_targets.append(shell)
971
972 for sample in context.samples:
973 sample_env = Environment(LIBRARY=library_name)
974 sample_env.Replace(**context.flags['sample'])
975 context.ApplyEnvOverrides(sample_env)
976 sample_object = sample_env.SConscript(
977 join('samples', 'SConscript'),
978 build_dir=join('obj', 'sample', sample, target_id),
979 exports='sample context',
980 duplicate=False
981 )
982 sample_name = sample + suffix
983 sample_program = sample_env.Program(sample_name, sample_object)
984 sample_env.Depends(sample_program, library)
985 context.sample_targets.append(sample_program)
986
987 cctest_program = env.SConscript(
988 join('test', 'cctest', 'SConscript'),
989 build_dir=join('obj', 'test', target_id),
990 exports='context object_files',
991 duplicate=False
992 )
993 context.cctest_targets.append(cctest_program)
994
995 return context
996
997
998def Build():
999 opts = GetOptions()
1000 env = Environment(options=opts)
1001 Help(opts.GenerateHelpText(env))
1002 VerifyOptions(env)
1003 env_overrides = ParseEnvOverrides(env['env'], env['importenv'])
1004
1005 SourceSignatures(env['sourcesignatures'])
1006
1007 libraries = []
1008 mksnapshots = []
1009 cctests = []
1010 samples = []
1011 d8s = []
1012 modes = SplitList(env['mode'])
1013 for mode in modes:
1014 context = BuildSpecific(env.Copy(), mode, env_overrides)
1015 libraries += context.library_targets
1016 mksnapshots += context.mksnapshot_targets
1017 cctests += context.cctest_targets
1018 samples += context.sample_targets
1019 d8s += context.d8_targets
1020
1021 env.Alias('library', libraries)
1022 env.Alias('mksnapshot', mksnapshots)
1023 env.Alias('cctests', cctests)
1024 env.Alias('sample', samples)
1025 env.Alias('d8', d8s)
1026
1027 if env['sample']:
1028 env.Default('sample')
1029 else:
1030 env.Default('library')
1031
1032
1033# We disable deprecation warnings because we need to be able to use
1034# env.Copy without getting warnings for compatibility with older
1035# version of scons. Also, there's a bug in some revisions that
1036# doesn't allow this flag to be set, so we swallow any exceptions.
1037# Lovely.
1038try:
1039 SetOption('warn', 'no-deprecated')
1040except:
1041 pass
1042
1043
1044Build()