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