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