Updated V8 from git://github.com/v8/v8.git to 57f8959fb264354ba1a2e5118db512f588917061
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / SConstruct
1 # Copyright 2012 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
28 import platform
29 import re
30 import subprocess
31 import sys
32 import os
33 from os.path import join, dirname, abspath
34 from types import DictType, StringTypes
35 root_dir = dirname(File('SConstruct').rfile().abspath)
36 src_dir = join(root_dir, 'src')
37 sys.path.insert(0, join(root_dir, 'tools'))
38 import js2c, utils
39
40 # ARM_TARGET_LIB is the path to the dynamic library to use on the target
41 # machine if cross-compiling to an arm machine. You will also need to set
42 # the additional cross-compiling environment variables to the cross compiler.
43 ARM_TARGET_LIB = os.environ.get('ARM_TARGET_LIB')
44 if ARM_TARGET_LIB:
45   ARM_LINK_FLAGS = ['-Wl,-rpath=' + ARM_TARGET_LIB + '/lib:' +
46                      ARM_TARGET_LIB + '/usr/lib',
47                     '-Wl,--dynamic-linker=' + ARM_TARGET_LIB +
48                     '/lib/ld-linux.so.3']
49 else:
50   ARM_LINK_FLAGS = []
51
52 GCC_EXTRA_CCFLAGS = []
53 GCC_DTOA_EXTRA_CCFLAGS = []
54
55 LIBRARY_FLAGS = {
56   'all': {
57     'CPPPATH': [src_dir],
58     'regexp:interpreted': {
59       'CPPDEFINES': ['V8_INTERPRETED_REGEXP']
60     },
61     'mode:debug': {
62       'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT']
63     },
64     'objectprint:on': {
65       'CPPDEFINES':   ['OBJECT_PRINT'],
66     },
67     'debuggersupport:on': {
68       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT'],
69     },
70     'inspector:on': {
71       'CPPDEFINES':   ['INSPECTOR'],
72     },
73     'fasttls:off': {
74       'CPPDEFINES':   ['V8_NO_FAST_TLS'],
75     },
76     'liveobjectlist:on': {
77       'CPPDEFINES':   ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR',
78                        'LIVE_OBJECT_LIST', 'OBJECT_PRINT'],
79     }
80   },
81   'gcc': {
82     'all': {
83       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
84       'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
85     },
86     'visibility:hidden': {
87       # Use visibility=default to disable this.
88       'CXXFLAGS':     ['-fvisibility=hidden']
89     },
90     'strictaliasing:off': {
91       'CCFLAGS':      ['-fno-strict-aliasing']
92     },
93     'mode:debug': {
94       'CCFLAGS':      ['-g', '-O0'],
95       'CPPDEFINES':   ['ENABLE_DISASSEMBLER', 'DEBUG'],
96     },
97     'mode:release': {
98       'CCFLAGS':      ['-O3', '-fomit-frame-pointer', '-fdata-sections',
99                        '-ffunction-sections'],
100     },
101     'os:linux': {
102       'CCFLAGS':      ['-ansi'] + GCC_EXTRA_CCFLAGS,
103       'library:shared': {
104         'CPPDEFINES': ['V8_SHARED'],
105         'LIBS': ['pthread']
106       }
107     },
108     'os:macos': {
109       'CCFLAGS':      ['-ansi', '-mmacosx-version-min=10.4'],
110       'library:shared': {
111         'CPPDEFINES': ['V8_SHARED']
112       }
113     },
114     'os:freebsd': {
115       'CPPPATH' : [src_dir, '/usr/local/include'],
116       'LIBPATH' : ['/usr/local/lib'],
117       'CCFLAGS':      ['-ansi'],
118       'LIBS': ['execinfo']
119     },
120     'os:openbsd': {
121       'CPPPATH' : [src_dir, '/usr/local/include'],
122       'LIBPATH' : ['/usr/local/lib'],
123       'CCFLAGS':      ['-ansi'],
124     },
125     'os:solaris': {
126       # On Solaris, to get isinf, INFINITY, fpclassify and other macros one
127       # needs to define __C99FEATURES__.
128       'CPPDEFINES': ['__C99FEATURES__'],
129       'CPPPATH' : [src_dir, '/usr/local/include'],
130       'LIBPATH' : ['/usr/local/lib'],
131       'CCFLAGS':      ['-ansi'],
132     },
133     'os:netbsd': {
134       'CPPPATH' : [src_dir, '/usr/pkg/include'],
135       'LIBPATH' : ['/usr/pkg/lib'],
136     },
137     'os:win32': {
138       'CCFLAGS':      ['-DWIN32'],
139       'CXXFLAGS':     ['-DWIN32'],
140     },
141     'arch:ia32': {
142       'CPPDEFINES':   ['V8_TARGET_ARCH_IA32'],
143       'CCFLAGS':      ['-m32'],
144       'LINKFLAGS':    ['-m32']
145     },
146     'arch:arm': {
147       'CPPDEFINES':   ['V8_TARGET_ARCH_ARM'],
148       'unalignedaccesses:on' : {
149         'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=1']
150       },
151       'unalignedaccesses:off' : {
152         'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=0']
153       },
154       'armeabi:soft' : {
155         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
156         'simulator:none': {
157           'CCFLAGS':     ['-mfloat-abi=soft'],
158         }
159       },
160       'armeabi:softfp' : {
161         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
162         'vfp3:on': {
163           'CPPDEFINES' : ['CAN_USE_VFP_INSTRUCTIONS']
164         },
165         'simulator:none': {
166           'CCFLAGS':     ['-mfloat-abi=softfp'],
167         }
168       },
169       'armeabi:hard' : {
170         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1'],
171         'vfp3:on': {
172           'CPPDEFINES' : ['CAN_USE_VFP_INSTRUCTIONS']
173         },
174         'simulator:none': {
175           'CCFLAGS':     ['-mfloat-abi=hard'],
176         }
177       }
178     },
179     'simulator:arm': {
180       'CCFLAGS':      ['-m32'],
181       'LINKFLAGS':    ['-m32'],
182     },
183     'arch:mips': {
184       'CPPDEFINES':   ['V8_TARGET_ARCH_MIPS'],
185       'mips_arch_variant:mips32r2': {
186         'CPPDEFINES':    ['_MIPS_ARCH_MIPS32R2']
187       },
188       'mips_arch_variant:loongson': {
189         'CPPDEFINES':    ['_MIPS_ARCH_LOONGSON']
190       },
191       'simulator:none': {
192         'CCFLAGS':      ['-EL'],
193         'LINKFLAGS':    ['-EL'],
194         'mips_arch_variant:mips32r2': {
195           'CCFLAGS':      ['-mips32r2', '-Wa,-mips32r2']
196         },
197         'mips_arch_variant:mips32r1': {
198           'CCFLAGS':      ['-mips32', '-Wa,-mips32']
199         },
200         'mips_arch_variant:loongson': {
201           'CCFLAGS':      ['-march=mips3', '-Wa,-march=mips3']
202         },
203         'library:static': {
204           'LINKFLAGS':    ['-static', '-static-libgcc']
205         },
206         'mipsabi:softfloat': {
207           'CCFLAGS':      ['-msoft-float'],
208           'LINKFLAGS':    ['-msoft-float']
209         },
210         'mipsabi:hardfloat': {
211           'CCFLAGS':      ['-mhard-float'],
212           'LINKFLAGS':    ['-mhard-float']
213         }
214       }
215     },
216     'simulator:mips': {
217       'CCFLAGS':      ['-m32'],
218       'LINKFLAGS':    ['-m32'],
219       'mipsabi:softfloat': {
220         'CPPDEFINES':    ['__mips_soft_float=1'],
221         'fpu:on': {
222           'CPPDEFINES' : ['CAN_USE_FPU_INSTRUCTIONS']
223         }
224       },
225       'mipsabi:hardfloat': {
226         'CPPDEFINES':    ['__mips_hard_float=1', 'CAN_USE_FPU_INSTRUCTIONS'],
227       }
228     },
229     'arch:x64': {
230       'CPPDEFINES':   ['V8_TARGET_ARCH_X64'],
231       'CCFLAGS':      ['-m64'],
232       'LINKFLAGS':    ['-m64'],
233     },
234     'gdbjit:on': {
235       'CPPDEFINES':   ['ENABLE_GDB_JIT_INTERFACE']
236     },
237     'compress_startup_data:bz2': {
238       'CPPDEFINES':   ['COMPRESS_STARTUP_DATA_BZ2']
239     }
240   },
241   'msvc': {
242     'all': {
243       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
244       'CXXFLAGS':     ['/GR-', '/Gy'],
245       'CPPDEFINES':   ['WIN32'],
246       'LINKFLAGS':    ['/INCREMENTAL:NO', '/NXCOMPAT', '/IGNORE:4221'],
247       'CCPDBFLAGS':   ['/Zi']
248     },
249     'verbose:off': {
250       'DIALECTFLAGS': ['/nologo'],
251       'ARFLAGS':      ['/NOLOGO']
252     },
253     'arch:ia32': {
254       'CPPDEFINES':   ['V8_TARGET_ARCH_IA32', '_USE_32BIT_TIME_T'],
255       'LINKFLAGS':    ['/MACHINE:X86'],
256       'ARFLAGS':      ['/MACHINE:X86']
257     },
258     'arch:x64': {
259       'CPPDEFINES':   ['V8_TARGET_ARCH_X64'],
260       'LINKFLAGS':    ['/MACHINE:X64'],
261       'ARFLAGS':      ['/MACHINE:X64']
262     },
263     'mode:debug': {
264       'CCFLAGS':      ['/Od', '/Gm'],
265       'CPPDEFINES':   ['_DEBUG', 'ENABLE_DISASSEMBLER', 'DEBUG'],
266       'LINKFLAGS':    ['/DEBUG'],
267       'msvcrt:static': {
268         'CCFLAGS': ['/MTd']
269       },
270       'msvcrt:shared': {
271         'CCFLAGS': ['/MDd']
272       }
273     },
274     'mode:release': {
275       'CCFLAGS':      ['/O2'],
276       'LINKFLAGS':    ['/OPT:REF', '/OPT:ICF'],
277       'msvcrt:static': {
278         'CCFLAGS': ['/MT']
279       },
280       'msvcrt:shared': {
281         'CCFLAGS': ['/MD']
282       },
283       'msvcltcg:on': {
284         'CCFLAGS':      ['/GL'],
285         'ARFLAGS':      ['/LTCG'],
286         'pgo:off': {
287           'LINKFLAGS':    ['/LTCG'],
288         },
289         'pgo:instrument': {
290           'LINKFLAGS':    ['/LTCG:PGI']
291         },
292         'pgo:optimize': {
293           'LINKFLAGS':    ['/LTCG:PGO']
294         }
295       }
296     }
297   }
298 }
299
300
301 V8_EXTRA_FLAGS = {
302   'gcc': {
303     'all': {
304       'WARNINGFLAGS': ['-Wall',
305                        '-Werror',
306                        '-W',
307                        '-Wno-unused-parameter',
308                        '-Woverloaded-virtual',
309                        '-Wnon-virtual-dtor']
310     },
311     'os:win32': {
312       'WARNINGFLAGS': ['-pedantic',
313                        '-Wno-long-long',
314                        '-Wno-pedantic-ms-format'],
315       'library:shared': {
316         'LIBS': ['winmm', 'ws2_32']
317       }
318     },
319     'os:linux': {
320       'WARNINGFLAGS': ['-pedantic'],
321       'library:shared': {
322         'soname:on': {
323           'LINKFLAGS': ['-Wl,-soname,${SONAME}']
324         }
325       }
326     },
327     'os:macos': {
328       'WARNINGFLAGS': ['-pedantic']
329     },
330     'arch:arm': {
331       # This is to silence warnings about ABI changes that some versions of the
332       # CodeSourcery G++ tool chain produce for each occurrence of varargs.
333       'WARNINGFLAGS': ['-Wno-abi']
334     },
335     'disassembler:on': {
336       'CPPDEFINES':   ['ENABLE_DISASSEMBLER']
337     }
338   },
339   'msvc': {
340     'all': {
341       'WARNINGFLAGS': ['/W3', '/WX', '/wd4351', '/wd4355', '/wd4800']
342     },
343     'library:shared': {
344       'CPPDEFINES': ['BUILDING_V8_SHARED'],
345       'LIBS': ['winmm', 'ws2_32']
346     },
347     'arch:arm': {
348       'CPPDEFINES':   ['V8_TARGET_ARCH_ARM'],
349       # /wd4996 is to silence the warning about sscanf
350       # used by the arm simulator.
351       'WARNINGFLAGS': ['/wd4996']
352     },
353     'arch:mips': {
354       'CPPDEFINES':   ['V8_TARGET_ARCH_MIPS'],
355       'mips_arch_variant:mips32r2': {
356         'CPPDEFINES':    ['_MIPS_ARCH_MIPS32R2']
357       },
358     },
359     'disassembler:on': {
360       'CPPDEFINES':   ['ENABLE_DISASSEMBLER']
361     }
362   }
363 }
364
365
366 MKSNAPSHOT_EXTRA_FLAGS = {
367   'gcc': {
368     'os:linux': {
369       'LIBS': ['pthread'],
370     },
371     'os:macos': {
372       'LIBS': ['pthread'],
373     },
374     'os:freebsd': {
375       'LIBS': ['execinfo', 'pthread']
376     },
377     'os:solaris': {
378       'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'],
379       'LINKFLAGS': ['-mt']
380     },
381     'os:openbsd': {
382       'LIBS': ['execinfo', 'pthread']
383     },
384     'os:win32': {
385       'LIBS': ['winmm', 'ws2_32'],
386     },
387     'os:netbsd': {
388       'LIBS': ['execinfo', 'pthread']
389     },
390     'compress_startup_data:bz2': {
391       'os:linux': {
392         'LIBS': ['bz2']
393       }
394     },
395   },
396   'msvc': {
397     'all': {
398       'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
399       'LIBS': ['winmm', 'ws2_32']
400     }
401   }
402 }
403
404
405 DTOA_EXTRA_FLAGS = {
406   'gcc': {
407     'all': {
408       'WARNINGFLAGS': ['-Werror', '-Wno-uninitialized'],
409       'CCFLAGS': GCC_DTOA_EXTRA_CCFLAGS
410     }
411   },
412   'msvc': {
413     'all': {
414       'WARNINGFLAGS': ['/WX', '/wd4018', '/wd4244']
415     }
416   }
417 }
418
419
420 CCTEST_EXTRA_FLAGS = {
421   'all': {
422     'CPPPATH': [src_dir],
423     'library:shared': {
424       'CPPDEFINES': ['USING_V8_SHARED']
425     },
426   },
427   'gcc': {
428     'all': {
429       'LIBPATH':      [abspath('.')],
430       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
431       'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
432       'LINKFLAGS':    ['$CCFLAGS'],
433     },
434     'os:linux': {
435       'LIBS':         ['pthread'],
436       'CCFLAGS':      ['-Wno-unused-but-set-variable'],
437     },
438     'os:macos': {
439       'LIBS':         ['pthread'],
440     },
441     'os:freebsd': {
442       'LIBS':         ['execinfo', 'pthread']
443     },
444     'os:solaris': {
445       'LIBS':         ['m', 'pthread', 'socket', 'nsl', 'rt'],
446       'LINKFLAGS':    ['-mt']
447     },
448     'os:openbsd': {
449       'LIBS':         ['execinfo', 'pthread']
450     },
451     'os:win32': {
452       'LIBS': ['winmm', 'ws2_32']
453     },
454     'os:netbsd': {
455       'LIBS':         ['execinfo', 'pthread']
456     },
457     'arch:arm': {
458       'LINKFLAGS':   ARM_LINK_FLAGS
459     },
460   },
461   'msvc': {
462     'all': {
463       'CPPDEFINES': ['_HAS_EXCEPTIONS=0'],
464       'LIBS': ['winmm', 'ws2_32']
465     },
466     'arch:ia32': {
467       'CPPDEFINES': ['V8_TARGET_ARCH_IA32']
468     },
469     'arch:x64': {
470       'CPPDEFINES':   ['V8_TARGET_ARCH_X64'],
471       'LINKFLAGS': ['/STACK:2097152']
472     },
473   }
474 }
475
476
477 SAMPLE_FLAGS = {
478   'all': {
479     'CPPPATH': [join(root_dir, 'include')],
480     'library:shared': {
481       'CPPDEFINES': ['USING_V8_SHARED']
482     },
483   },
484   'gcc': {
485     'all': {
486       'LIBPATH':      ['.'],
487       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
488       'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
489       'LINKFLAGS':    ['$CCFLAGS'],
490     },
491     'os:linux': {
492       'LIBS':         ['pthread'],
493     },
494     'os:macos': {
495       'LIBS':         ['pthread'],
496     },
497     'os:freebsd': {
498       'LIBPATH' :     ['/usr/local/lib'],
499       'LIBS':         ['execinfo', 'pthread']
500     },
501     'os:solaris': {
502       # On Solaris, to get isinf, INFINITY, fpclassify and other macros one
503       # needs to define __C99FEATURES__.
504       'CPPDEFINES': ['__C99FEATURES__'],
505       'LIBPATH' :     ['/usr/local/lib'],
506       'LIBS':         ['m', 'pthread', 'socket', 'nsl', 'rt'],
507       'LINKFLAGS':    ['-mt']
508     },
509     'os:openbsd': {
510       'LIBPATH' :     ['/usr/local/lib'],
511       'LIBS':         ['execinfo', 'pthread']
512     },
513     'os:win32': {
514       'LIBS':         ['winmm', 'ws2_32']
515     },
516     'os:netbsd': {
517       'LIBPATH' :     ['/usr/pkg/lib'],
518       'LIBS':         ['execinfo', 'pthread']
519     },
520     'arch:arm': {
521       'LINKFLAGS':   ARM_LINK_FLAGS,
522       'armeabi:soft' : {
523         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
524         'simulator:none': {
525           'CCFLAGS':     ['-mfloat-abi=soft'],
526         }
527       },
528       'armeabi:softfp' : {
529         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
530         'simulator:none': {
531           'CCFLAGS':     ['-mfloat-abi=softfp'],
532         }
533       },
534       'armeabi:hard' : {
535         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1'],
536         'vfp3:on': {
537           'CPPDEFINES' : ['CAN_USE_VFP_INSTRUCTIONS']
538         },
539         'simulator:none': {
540           'CCFLAGS':     ['-mfloat-abi=hard'],
541         }
542       }
543     },
544     'arch:ia32': {
545       'CCFLAGS':      ['-m32'],
546       'LINKFLAGS':    ['-m32']
547     },
548     'arch:x64': {
549       'CCFLAGS':      ['-m64'],
550       'LINKFLAGS':    ['-m64']
551     },
552     'arch:mips': {
553       'CPPDEFINES':   ['V8_TARGET_ARCH_MIPS'],
554       'mips_arch_variant:mips32r2': {
555         'CPPDEFINES':    ['_MIPS_ARCH_MIPS32R2']
556       },
557       'mips_arch_variant:loongson': {
558         'CPPDEFINES':    ['_MIPS_ARCH_LOONGSON']
559       },
560       'simulator:none': {
561         'CCFLAGS':      ['-EL'],
562         'LINKFLAGS':    ['-EL'],
563         'mips_arch_variant:mips32r2': {
564           'CCFLAGS':      ['-mips32r2', '-Wa,-mips32r2']
565         },
566         'mips_arch_variant:mips32r1': {
567           'CCFLAGS':      ['-mips32', '-Wa,-mips32']
568         },
569         'mips_arch_variant:loongson': {
570           'CCFLAGS':      ['-march=mips3', '-Wa,-march=mips3']
571         },
572         'library:static': {
573           'LINKFLAGS':    ['-static', '-static-libgcc']
574         },
575         'mipsabi:softfloat': {
576           'CCFLAGS':      ['-msoft-float'],
577           'LINKFLAGS':    ['-msoft-float']
578         },
579         'mipsabi:hardfloat': {
580           'CCFLAGS':      ['-mhard-float'],
581           'LINKFLAGS':    ['-mhard-float'],
582           'fpu:on': {
583             'CPPDEFINES' : ['CAN_USE_FPU_INSTRUCTIONS']
584           }
585         }
586       }
587     },
588     'simulator:arm': {
589       'CCFLAGS':      ['-m32'],
590       'LINKFLAGS':    ['-m32']
591     },
592     'simulator:mips': {
593       'CCFLAGS':      ['-m32'],
594       'LINKFLAGS':    ['-m32']
595     },
596     'mode:release': {
597       'CCFLAGS':      ['-O2']
598     },
599     'mode:debug': {
600       'CCFLAGS':      ['-g', '-O0'],
601       'CPPDEFINES':   ['DEBUG']
602     },
603     'compress_startup_data:bz2': {
604       'CPPDEFINES':   ['COMPRESS_STARTUP_DATA_BZ2'],
605       'os:linux': {
606         'LIBS':       ['bz2']
607       }
608     },
609   },
610   'msvc': {
611     'all': {
612       'LIBS': ['winmm', 'ws2_32']
613     },
614     'verbose:off': {
615       'CCFLAGS': ['/nologo'],
616       'LINKFLAGS': ['/NOLOGO']
617     },
618     'verbose:on': {
619       'LINKFLAGS': ['/VERBOSE']
620     },
621     'prof:on': {
622       'LINKFLAGS': ['/MAP']
623     },
624     'mode:release': {
625       'CCFLAGS':   ['/O2'],
626       'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
627       'msvcrt:static': {
628         'CCFLAGS': ['/MT']
629       },
630       'msvcrt:shared': {
631         'CCFLAGS': ['/MD']
632       },
633       'msvcltcg:on': {
634         'CCFLAGS':      ['/GL'],
635         'pgo:off': {
636           'LINKFLAGS':    ['/LTCG'],
637         },
638       },
639       'pgo:instrument': {
640         'LINKFLAGS':    ['/LTCG:PGI']
641       },
642       'pgo:optimize': {
643         'LINKFLAGS':    ['/LTCG:PGO']
644       }
645     },
646     'arch:ia32': {
647       'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'],
648       'LINKFLAGS': ['/MACHINE:X86']
649     },
650     'arch:x64': {
651       'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'],
652       'LINKFLAGS': ['/MACHINE:X64', '/STACK:2097152']
653     },
654     'mode:debug': {
655       'CCFLAGS':    ['/Od'],
656       'LINKFLAGS':  ['/DEBUG'],
657       'CPPDEFINES': ['DEBUG'],
658       'msvcrt:static': {
659         'CCFLAGS':  ['/MTd']
660       },
661       'msvcrt:shared': {
662         'CCFLAGS':  ['/MDd']
663       }
664     }
665   }
666 }
667
668
669 PREPARSER_FLAGS = {
670   'all': {
671     'CPPPATH': [join(root_dir, 'include'), src_dir],
672     'library:shared': {
673       'CPPDEFINES': ['USING_V8_SHARED']
674     },
675   },
676   'gcc': {
677     'all': {
678       'LIBPATH':      ['.'],
679       'CCFLAGS':      ['$DIALECTFLAGS', '$WARNINGFLAGS'],
680       'CXXFLAGS':     ['-fno-rtti', '-fno-exceptions'],
681       'LINKFLAGS':    ['$CCFLAGS'],
682     },
683     'os:win32': {
684       'LIBS':         ['winmm', 'ws2_32']
685     },
686     'arch:arm': {
687       'LINKFLAGS':   ARM_LINK_FLAGS,
688       'armeabi:soft' : {
689         'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
690         'simulator:none': {
691           'CCFLAGS':     ['-mfloat-abi=soft'],
692         }
693       },
694       'armeabi:softfp' : {
695         'simulator:none': {
696           'CCFLAGS':     ['-mfloat-abi=softfp'],
697         }
698       },
699       'armeabi:hard' : {
700         'simulator:none': {
701           'CCFLAGS':     ['-mfloat-abi=hard'],
702         }
703       }
704     },
705     'arch:ia32': {
706       'CCFLAGS':      ['-m32'],
707       'LINKFLAGS':    ['-m32']
708     },
709     'arch:x64': {
710       'CCFLAGS':      ['-m64'],
711       'LINKFLAGS':    ['-m64']
712     },
713     'arch:mips': {
714       'CPPDEFINES':   ['V8_TARGET_ARCH_MIPS'],
715       'mips_arch_variant:mips32r2': {
716         'CPPDEFINES':    ['_MIPS_ARCH_MIPS32R2']
717       },
718       'mips_arch_variant:loongson': {
719         'CPPDEFINES':    ['_MIPS_ARCH_LOONGSON']
720       },
721       'simulator:none': {
722         'CCFLAGS':      ['-EL'],
723         'LINKFLAGS':    ['-EL'],
724         'mips_arch_variant:mips32r2': {
725           'CCFLAGS':      ['-mips32r2', '-Wa,-mips32r2']
726         },
727         'mips_arch_variant:mips32r1': {
728           'CCFLAGS':      ['-mips32', '-Wa,-mips32']
729         },
730         'mips_arch_variant:loongson': {
731           'CCFLAGS':      ['-march=mips3', '-Wa,-march=mips3']
732         },
733         'library:static': {
734           'LINKFLAGS':    ['-static', '-static-libgcc']
735         },
736         'mipsabi:softfloat': {
737           'CCFLAGS':      ['-msoft-float'],
738           'LINKFLAGS':    ['-msoft-float']
739         },
740         'mipsabi:hardfloat': {
741           'CCFLAGS':      ['-mhard-float'],
742           'LINKFLAGS':    ['-mhard-float']
743         }
744       }
745     },
746     'simulator:arm': {
747       'CCFLAGS':      ['-m32'],
748       'LINKFLAGS':    ['-m32']
749     },
750     'simulator:mips': {
751       'CCFLAGS':      ['-m32'],
752       'LINKFLAGS':    ['-m32'],
753       'mipsabi:softfloat': {
754         'CPPDEFINES':    ['__mips_soft_float=1'],
755       },
756       'mipsabi:hardfloat': {
757         'CPPDEFINES':    ['__mips_hard_float=1'],
758       }
759     },
760     'mode:release': {
761       'CCFLAGS':      ['-O2']
762     },
763     'mode:debug': {
764       'CCFLAGS':      ['-g', '-O0'],
765       'CPPDEFINES':   ['DEBUG']
766     },
767     'os:freebsd': {
768       'LIBPATH' : ['/usr/local/lib'],
769     },
770   },
771   'msvc': {
772     'all': {
773       'LIBS': ['winmm', 'ws2_32']
774     },
775     'verbose:off': {
776       'CCFLAGS': ['/nologo'],
777       'LINKFLAGS': ['/NOLOGO']
778     },
779     'verbose:on': {
780       'LINKFLAGS': ['/VERBOSE']
781     },
782     'prof:on': {
783       'LINKFLAGS': ['/MAP']
784     },
785     'mode:release': {
786       'CCFLAGS':   ['/O2'],
787       'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
788       'msvcrt:static': {
789         'CCFLAGS': ['/MT']
790       },
791       'msvcrt:shared': {
792         'CCFLAGS': ['/MD']
793       },
794       'msvcltcg:on': {
795         'CCFLAGS':      ['/GL'],
796         'pgo:off': {
797           'LINKFLAGS':    ['/LTCG'],
798         },
799       },
800       'pgo:instrument': {
801         'LINKFLAGS':    ['/LTCG:PGI']
802       },
803       'pgo:optimize': {
804         'LINKFLAGS':    ['/LTCG:PGO']
805       }
806     },
807     'arch:ia32': {
808       'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'],
809       'LINKFLAGS': ['/MACHINE:X86']
810     },
811     'arch:x64': {
812       'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'],
813       'LINKFLAGS': ['/MACHINE:X64', '/STACK:2097152']
814     },
815     'mode:debug': {
816       'CCFLAGS':    ['/Od'],
817       'LINKFLAGS':  ['/DEBUG'],
818       'CPPDEFINES': ['DEBUG'],
819       'msvcrt:static': {
820         'CCFLAGS':  ['/MTd']
821       },
822       'msvcrt:shared': {
823         'CCFLAGS':  ['/MDd']
824       }
825     }
826   }
827 }
828
829
830 D8_FLAGS = {
831   'all': {
832     'library:shared': {
833       'CPPDEFINES': ['V8_SHARED'],
834       'LIBS': ['v8'],
835       'LIBPATH': ['.']
836     },
837   },
838   'gcc': {
839     'all': {
840       'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
841       'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'],
842       'LINKFLAGS': ['$CCFLAGS'],
843     },
844     'console:readline': {
845       'LIBS': ['readline']
846     },
847     'os:linux': {
848       'LIBS': ['pthread'],
849     },
850     'os:macos': {
851       'LIBS': ['pthread'],
852     },
853     'os:freebsd': {
854       'LIBS': ['pthread'],
855     },
856     'os:solaris': {
857       'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'],
858       'LINKFLAGS': ['-mt']
859     },
860     'os:openbsd': {
861       'LIBS': ['pthread'],
862     },
863     'os:win32': {
864       'LIBS': ['winmm', 'ws2_32'],
865     },
866     'os:netbsd': {
867       'LIBS': ['pthread'],
868     },
869     'arch:arm': {
870       'LINKFLAGS':   ARM_LINK_FLAGS
871     },
872     'compress_startup_data:bz2': {
873       'CPPDEFINES':   ['COMPRESS_STARTUP_DATA_BZ2'],
874       'os:linux': {
875         'LIBS': ['bz2']
876       }
877     }
878   },
879   'msvc': {
880     'all': {
881       'LIBS': ['winmm', 'ws2_32']
882     },
883     'verbose:off': {
884       'CCFLAGS': ['/nologo'],
885       'LINKFLAGS': ['/NOLOGO']
886     },
887     'verbose:on': {
888       'LINKFLAGS': ['/VERBOSE']
889     },
890     'prof:on': {
891       'LINKFLAGS': ['/MAP']
892     },
893     'mode:release': {
894       'CCFLAGS':   ['/O2'],
895       'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'],
896       'msvcrt:static': {
897         'CCFLAGS': ['/MT']
898       },
899       'msvcrt:shared': {
900         'CCFLAGS': ['/MD']
901       },
902       'msvcltcg:on': {
903         'CCFLAGS':      ['/GL'],
904         'pgo:off': {
905           'LINKFLAGS':    ['/LTCG'],
906         },
907       },
908       'pgo:instrument': {
909         'LINKFLAGS':    ['/LTCG:PGI']
910       },
911       'pgo:optimize': {
912         'LINKFLAGS':    ['/LTCG:PGO']
913       }
914     },
915     'arch:ia32': {
916       'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'],
917       'LINKFLAGS': ['/MACHINE:X86']
918     },
919     'arch:x64': {
920       'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'],
921       'LINKFLAGS': ['/MACHINE:X64', '/STACK:2097152']
922     },
923     'mode:debug': {
924       'CCFLAGS':    ['/Od'],
925       'LINKFLAGS':  ['/DEBUG'],
926       'CPPDEFINES': ['DEBUG'],
927       'msvcrt:static': {
928         'CCFLAGS':  ['/MTd']
929       },
930       'msvcrt:shared': {
931         'CCFLAGS':  ['/MDd']
932       }
933     }
934   }
935 }
936
937
938 SUFFIXES = {
939   'release': '',
940   'debug': '_g'
941 }
942
943
944 def Abort(message):
945   print message
946   sys.exit(1)
947
948
949 def GuessOS(env):
950   return utils.GuessOS()
951
952
953 def GuessArch(env):
954   return utils.GuessArchitecture()
955
956
957 def GuessToolchain(env):
958   tools = env['TOOLS']
959   if 'gcc' in tools:
960     return 'gcc'
961   elif 'msvc' in tools:
962     return 'msvc'
963   else:
964     return None
965
966
967 def GuessVisibility(env):
968   os = env['os']
969   toolchain = env['toolchain'];
970   if (os == 'win32' or os == 'cygwin') and toolchain == 'gcc':
971     # MinGW / Cygwin can't do it.
972     return 'default'
973   elif os == 'solaris':
974     return 'default'
975   else:
976     return 'hidden'
977
978
979 def GuessStrictAliasing(env):
980   # There seems to be a problem with gcc 4.5.x.
981   # See http://code.google.com/p/v8/issues/detail?id=884
982   # It can be worked around by disabling strict aliasing.
983   toolchain = env['toolchain'];
984   if toolchain == 'gcc':
985     env = Environment(tools=['gcc'])
986     # The gcc version should be available in env['CCVERSION'],
987     # but when scons detects msvc this value is not set.
988     version = subprocess.Popen([env['CC'], '-dumpversion'],
989         stdout=subprocess.PIPE).communicate()[0]
990     if version.find('4.5') == 0:
991       return 'off'
992   return 'default'
993
994
995 PLATFORM_OPTIONS = {
996   'arch': {
997     'values': ['arm', 'ia32', 'x64', 'mips'],
998     'guess': GuessArch,
999     'help': 'the architecture to build for'
1000   },
1001   'os': {
1002     'values': ['freebsd', 'linux', 'macos', 'win32', 'openbsd', 'solaris', 'cygwin', 'netbsd'],
1003     'guess': GuessOS,
1004     'help': 'the os to build for'
1005   },
1006   'toolchain': {
1007     'values': ['gcc', 'msvc'],
1008     'guess': GuessToolchain,
1009     'help': 'the toolchain to use'
1010   }
1011 }
1012
1013 SIMPLE_OPTIONS = {
1014   'regexp': {
1015     'values': ['native', 'interpreted'],
1016     'default': 'native',
1017     'help': 'Whether to use native or interpreted regexp implementation'
1018   },
1019   'snapshot': {
1020     'values': ['on', 'off', 'nobuild'],
1021     'default': 'off',
1022     'help': 'build using snapshots for faster start-up'
1023   },
1024   'prof': {
1025     'values': ['on', 'off'],
1026     'default': 'off',
1027     'help': 'enable profiling of build target'
1028   },
1029   'gdbjit': {
1030     'values': ['on', 'off'],
1031     'default': 'off',
1032     'help': 'enable GDB JIT interface'
1033   },
1034   'library': {
1035     'values': ['static', 'shared'],
1036     'default': 'static',
1037     'help': 'the type of library to produce'
1038   },
1039   'objectprint': {
1040     'values': ['on', 'off'],
1041     'default': 'off',
1042     'help': 'enable object printing'
1043   },
1044   'profilingsupport': {
1045     'values': ['on', 'off'],
1046     'default': 'on',
1047     'help': 'enable profiling of JavaScript code'
1048   },
1049   'debuggersupport': {
1050     'values': ['on', 'off'],
1051     'default': 'on',
1052     'help': 'enable debugging of JavaScript code'
1053   },
1054   'inspector': {
1055     'values': ['on', 'off'],
1056     'default': 'off',
1057     'help': 'enable inspector features'
1058   },
1059   'liveobjectlist': {
1060     'values': ['on', 'off'],
1061     'default': 'off',
1062     'help': 'enable live object list features in the debugger'
1063   },
1064   'soname': {
1065     'values': ['on', 'off'],
1066     'default': 'off',
1067     'help': 'turn on setting soname for Linux shared library'
1068   },
1069   'msvcrt': {
1070     'values': ['static', 'shared'],
1071     'default': 'static',
1072     'help': 'the type of Microsoft Visual C++ runtime library to use'
1073   },
1074   'msvcltcg': {
1075     'values': ['on', 'off'],
1076     'default': 'on',
1077     'help': 'use Microsoft Visual C++ link-time code generation'
1078   },
1079   'simulator': {
1080     'values': ['arm', 'mips', 'none'],
1081     'default': 'none',
1082     'help': 'build with simulator'
1083   },
1084   'unalignedaccesses': {
1085     'values': ['default', 'on', 'off'],
1086     'default': 'default',
1087     'help': 'set whether the ARM target supports unaligned accesses'
1088   },
1089   'disassembler': {
1090     'values': ['on', 'off'],
1091     'default': 'off',
1092     'help': 'enable the disassembler to inspect generated code'
1093   },
1094   'fasttls': {
1095     'values': ['on', 'off'],
1096     'default': 'on',
1097     'help': 'enable fast thread local storage support '
1098             '(if available on the current architecture/platform)'
1099   },
1100   'sourcesignatures': {
1101     'values': ['MD5', 'timestamp'],
1102     'default': 'MD5',
1103     'help': 'set how the build system detects file changes'
1104   },
1105   'console': {
1106     'values': ['dumb', 'readline'],
1107     'default': 'dumb',
1108     'help': 'the console to use for the d8 shell'
1109   },
1110   'verbose': {
1111     'values': ['on', 'off'],
1112     'default': 'off',
1113     'help': 'more output from compiler and linker'
1114   },
1115   'visibility': {
1116     'values': ['default', 'hidden'],
1117     'guess': GuessVisibility,
1118     'help': 'shared library symbol visibility'
1119   },
1120   'strictaliasing': {
1121     'values': ['default', 'off'],
1122     'guess': GuessStrictAliasing,
1123     'help': 'assume strict aliasing while optimizing'
1124   },
1125   'pgo': {
1126     'values': ['off', 'instrument', 'optimize'],
1127     'default': 'off',
1128     'help': 'select profile guided optimization variant',
1129   },
1130   'armeabi': {
1131     'values': ['hard', 'softfp', 'soft'],
1132     'default': 'softfp',
1133     'help': 'generate calling conventiont according to selected ARM EABI variant'
1134   },
1135   'mipsabi': {
1136     'values': ['hardfloat', 'softfloat', 'none'],
1137     'default': 'hardfloat',
1138     'help': 'generate calling conventiont according to selected mips ABI'
1139   },
1140   'mips_arch_variant': {
1141     'values': ['mips32r2', 'mips32r1', 'loongson'],
1142     'default': 'mips32r2',
1143     'help': 'mips variant'
1144   },
1145   'compress_startup_data': {
1146     'values': ['off', 'bz2'],
1147     'default': 'off',
1148     'help': 'compress startup data (snapshot) [Linux only]'
1149   },
1150   'vfp3': {
1151     'values': ['on', 'off'],
1152     'default': 'on',
1153     'help': 'use vfp3 instructions when building the snapshot [Arm only]'
1154   },
1155   'fpu': {
1156     'values': ['on', 'off'],
1157     'default': 'on',
1158     'help': 'use fpu instructions when building the snapshot [MIPS only]'
1159   },
1160
1161 }
1162
1163 ALL_OPTIONS = dict(PLATFORM_OPTIONS, **SIMPLE_OPTIONS)
1164
1165
1166 def AddOptions(options, result):
1167   guess_env = Environment(options=result)
1168   for (name, option) in options.iteritems():
1169     if 'guess' in option:
1170       # Option has a guess function
1171       guess = option.get('guess')
1172       default = guess(guess_env)
1173     else:
1174       # Option has a fixed default
1175       default = option.get('default')
1176     help = '%s (%s)' % (option.get('help'), ", ".join(option['values']))
1177     result.Add(name, help, default)
1178
1179
1180 def GetOptions():
1181   result = Options()
1182   result.Add('mode', 'compilation mode (debug, release)', 'release')
1183   result.Add('sample', 'build sample (shell, process, lineprocessor)', '')
1184   result.Add('cache', 'directory to use for scons build cache', '')
1185   result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '')
1186   result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '')
1187   AddOptions(PLATFORM_OPTIONS, result)
1188   AddOptions(SIMPLE_OPTIONS, result)
1189   return result
1190
1191
1192 def GetTools(opts):
1193   env = Environment(options=opts)
1194   os = env['os']
1195   toolchain = env['toolchain']
1196   if os == 'win32' and toolchain == 'gcc':
1197     return ['mingw']
1198   elif os == 'win32' and toolchain == 'msvc':
1199     return ['msvc', 'mslink', 'mslib', 'msvs']
1200   else:
1201     return ['default']
1202
1203
1204 def GetVersionComponents():
1205   MAJOR_VERSION_PATTERN = re.compile(r"#define\s+MAJOR_VERSION\s+(.*)")
1206   MINOR_VERSION_PATTERN = re.compile(r"#define\s+MINOR_VERSION\s+(.*)")
1207   BUILD_NUMBER_PATTERN = re.compile(r"#define\s+BUILD_NUMBER\s+(.*)")
1208   PATCH_LEVEL_PATTERN = re.compile(r"#define\s+PATCH_LEVEL\s+(.*)")
1209
1210   patterns = [MAJOR_VERSION_PATTERN,
1211               MINOR_VERSION_PATTERN,
1212               BUILD_NUMBER_PATTERN,
1213               PATCH_LEVEL_PATTERN]
1214
1215   source = open(join(root_dir, 'src', 'version.cc')).read()
1216   version_components = []
1217   for pattern in patterns:
1218     match = pattern.search(source)
1219     if match:
1220       version_components.append(match.group(1).strip())
1221     else:
1222       version_components.append('0')
1223
1224   return version_components
1225
1226
1227 def GetVersion():
1228   version_components = GetVersionComponents()
1229
1230   if version_components[len(version_components) - 1] == '0':
1231     version_components.pop()
1232   return '.'.join(version_components)
1233
1234
1235 def GetSpecificSONAME():
1236   SONAME_PATTERN = re.compile(r"#define\s+SONAME\s+\"(.*)\"")
1237
1238   source = open(join(root_dir, 'src', 'version.cc')).read()
1239   match = SONAME_PATTERN.search(source)
1240
1241   if match:
1242     return match.group(1).strip()
1243   else:
1244     return ''
1245
1246
1247 def SplitList(str):
1248   return [ s for s in str.split(",") if len(s) > 0 ]
1249
1250
1251 def IsLegal(env, option, values):
1252   str = env[option]
1253   for s in SplitList(str):
1254     if not s in values:
1255       Abort("Illegal value for option %s '%s'." % (option, s))
1256       return False
1257   return True
1258
1259
1260 def VerifyOptions(env):
1261   if not IsLegal(env, 'mode', ['debug', 'release']):
1262     return False
1263   if not IsLegal(env, 'sample', ["shell", "process", "lineprocessor"]):
1264     return False
1265   if not IsLegal(env, 'regexp', ["native", "interpreted"]):
1266     return False
1267   if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on':
1268     Abort("Profiling on windows only supported for static library.")
1269   if env['gdbjit'] == 'on' and ((env['os'] != 'linux' and env['os'] != 'macos') or (env['arch'] != 'ia32' and env['arch'] != 'x64' and env['arch'] != 'arm')):
1270     Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux/OSX target.")
1271   if env['os'] == 'win32' and env['soname'] == 'on':
1272     Abort("Shared Object soname not applicable for Windows.")
1273   if env['soname'] == 'on' and env['library'] == 'static':
1274     Abort("Shared Object soname not applicable for static library.")
1275   if env['os'] != 'win32' and env['pgo'] != 'off':
1276     Abort("Profile guided optimization only supported on Windows.")
1277   if env['cache'] and not os.path.isdir(env['cache']):
1278     Abort("The specified cache directory does not exist.")
1279   if not (env['arch'] == 'arm' or env['simulator'] == 'arm') and ('unalignedaccesses' in ARGUMENTS):
1280     print env['arch']
1281     print env['simulator']
1282     Abort("Option unalignedaccesses only supported for the ARM architecture.")
1283   if env['os'] != 'linux' and env['compress_startup_data'] != 'off':
1284     Abort("Startup data compression is only available on Linux")
1285   for (name, option) in ALL_OPTIONS.iteritems():
1286     if (not name in env):
1287       message = ("A value for option %s must be specified (%s)." %
1288           (name, ", ".join(option['values'])))
1289       Abort(message)
1290     if not env[name] in option['values']:
1291       message = ("Unknown %s value '%s'.  Possible values are (%s)." %
1292           (name, env[name], ", ".join(option['values'])))
1293       Abort(message)
1294
1295
1296 class BuildContext(object):
1297
1298   def __init__(self, options, env_overrides, samples):
1299     self.library_targets = []
1300     self.mksnapshot_targets = []
1301     self.cctest_targets = []
1302     self.sample_targets = []
1303     self.d8_targets = []
1304     self.options = options
1305     self.env_overrides = env_overrides
1306     self.samples = samples
1307     self.preparser_targets = []
1308     self.use_snapshot = (options['snapshot'] != 'off')
1309     self.build_snapshot = (options['snapshot'] == 'on')
1310     self.flags = None
1311
1312   def AddRelevantFlags(self, initial, flags):
1313     result = initial.copy()
1314     toolchain = self.options['toolchain']
1315     if toolchain in flags:
1316       self.AppendFlags(result, flags[toolchain].get('all'))
1317       for option in sorted(self.options.keys()):
1318         value = self.options[option]
1319         self.AppendFlags(result, flags[toolchain].get(option + ':' + value))
1320     self.AppendFlags(result, flags.get('all'))
1321     return result
1322
1323   def AddRelevantSubFlags(self, options, flags):
1324     self.AppendFlags(options, flags.get('all'))
1325     for option in sorted(self.options.keys()):
1326       value = self.options[option]
1327       self.AppendFlags(options, flags.get(option + ':' + value))
1328
1329   def GetRelevantSources(self, source):
1330     result = []
1331     result += source.get('all', [])
1332     for (name, value) in self.options.iteritems():
1333       source_value = source.get(name + ':' + value, [])
1334       if type(source_value) == dict:
1335         result += self.GetRelevantSources(source_value)
1336       else:
1337         result += source_value
1338     return sorted(result)
1339
1340   def AppendFlags(self, options, added):
1341     if not added:
1342       return
1343     for (key, value) in added.iteritems():
1344       if key.find(':') != -1:
1345         self.AddRelevantSubFlags(options, { key: value })
1346       else:
1347         if not key in options:
1348           options[key] = value
1349         else:
1350           prefix = options[key]
1351           if isinstance(prefix, StringTypes): prefix = prefix.split()
1352           options[key] = prefix + value
1353
1354   def ConfigureObject(self, env, input, **kw):
1355     if (kw.has_key('CPPPATH') and env.has_key('CPPPATH')):
1356       kw['CPPPATH'] += env['CPPPATH']
1357     if self.options['library'] == 'static':
1358       return env.StaticObject(input, **kw)
1359     else:
1360       return env.SharedObject(input, **kw)
1361
1362   def ApplyEnvOverrides(self, env):
1363     if not self.env_overrides:
1364       return
1365     if type(env['ENV']) == DictType:
1366       env['ENV'].update(**self.env_overrides)
1367     else:
1368       env['ENV'] = self.env_overrides
1369
1370
1371 def PostprocessOptions(options, os):
1372   # Adjust architecture if the simulator option has been set
1373   if (options['simulator'] != 'none') and (options['arch'] != options['simulator']):
1374     if 'arch' in ARGUMENTS:
1375       # Print a warning if arch has explicitly been set
1376       print "Warning: forcing architecture to match simulator (%s)" % options['simulator']
1377     options['arch'] = options['simulator']
1378   if (options['prof'] != 'off') and (options['profilingsupport'] == 'off'):
1379     # Print a warning if profiling is enabled without profiling support
1380     print "Warning: forcing profilingsupport on when prof is on"
1381     options['profilingsupport'] = 'on'
1382   if os == 'win32' and options['pgo'] != 'off' and options['msvcltcg'] == 'off':
1383     if 'msvcltcg' in ARGUMENTS:
1384       print "Warning: forcing msvcltcg on as it is required for pgo (%s)" % options['pgo']
1385     options['msvcltcg'] = 'on'
1386   if (options['mipsabi'] != 'none') and (options['arch'] != 'mips') and (options['simulator'] != 'mips'):
1387     options['mipsabi'] = 'none'
1388   if options['liveobjectlist'] == 'on':
1389     if (options['debuggersupport'] != 'on') or (options['mode'] == 'release'):
1390       # Print a warning that liveobjectlist will implicitly enable the debugger
1391       print "Warning: forcing debuggersupport on for liveobjectlist"
1392     options['debuggersupport'] = 'on'
1393     options['inspector'] = 'on'
1394     options['objectprint'] = 'on'
1395
1396
1397 def ParseEnvOverrides(arg, imports):
1398   # The environment overrides are in the format NAME0:value0,NAME1:value1,...
1399   # The environment imports are in the format NAME0,NAME1,...
1400   overrides = {}
1401   for var in imports.split(','):
1402     if var in os.environ:
1403       overrides[var] = os.environ[var]
1404   for override in arg.split(','):
1405     pos = override.find(':')
1406     if pos == -1:
1407       continue
1408     overrides[override[:pos].strip()] = override[pos+1:].strip()
1409   return overrides
1410
1411
1412 def BuildSpecific(env, mode, env_overrides, tools):
1413   options = {'mode': mode}
1414   for option in ALL_OPTIONS:
1415     options[option] = env[option]
1416   PostprocessOptions(options, env['os'])
1417
1418   context = BuildContext(options, env_overrides, samples=SplitList(env['sample']))
1419
1420   # Remove variables which can't be imported from the user's external
1421   # environment into a construction environment.
1422   user_environ = os.environ.copy()
1423   try:
1424     del user_environ['ENV']
1425   except KeyError:
1426     pass
1427
1428   library_flags = context.AddRelevantFlags(user_environ, LIBRARY_FLAGS)
1429   v8_flags = context.AddRelevantFlags(library_flags, V8_EXTRA_FLAGS)
1430   mksnapshot_flags = context.AddRelevantFlags(library_flags, MKSNAPSHOT_EXTRA_FLAGS)
1431   dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS)
1432   cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS)
1433   sample_flags = context.AddRelevantFlags(user_environ, SAMPLE_FLAGS)
1434   preparser_flags = context.AddRelevantFlags(user_environ, PREPARSER_FLAGS)
1435   d8_flags = context.AddRelevantFlags(library_flags, D8_FLAGS)
1436
1437   context.flags = {
1438     'v8': v8_flags,
1439     'mksnapshot': mksnapshot_flags,
1440     'dtoa': dtoa_flags,
1441     'cctest': cctest_flags,
1442     'sample': sample_flags,
1443     'd8': d8_flags,
1444     'preparser': preparser_flags
1445   }
1446
1447   # Generate library base name.
1448   target_id = mode
1449   suffix = SUFFIXES[target_id]
1450   library_name = 'v8' + suffix
1451   preparser_library_name = 'v8preparser' + suffix
1452   version = GetVersion()
1453   if context.options['soname'] == 'on':
1454     # When building shared object with SONAME version the library name.
1455     library_name += '-' + version
1456
1457   # Generate library SONAME if required by the build.
1458   if context.options['soname'] == 'on':
1459     soname = GetSpecificSONAME()
1460     if soname == '':
1461       soname = 'lib' + library_name + '.so'
1462     env['SONAME'] = soname
1463
1464   # Build the object files by invoking SCons recursively.
1465   d8_env = Environment(tools=tools)
1466   d8_env.Replace(**context.flags['d8'])
1467   (object_files, shell_files, mksnapshot, preparser_files) = env.SConscript(
1468     join('src', 'SConscript'),
1469     build_dir=join('obj', target_id),
1470     exports='context tools d8_env',
1471     duplicate=False
1472   )
1473
1474   context.mksnapshot_targets.append(mksnapshot)
1475
1476   # Link the object files into a library.
1477   env.Replace(**context.flags['v8'])
1478
1479   context.ApplyEnvOverrides(env)
1480   if context.options['library'] == 'static':
1481     library = env.StaticLibrary(library_name, object_files)
1482     preparser_library = env.StaticLibrary(preparser_library_name,
1483                                           preparser_files)
1484   else:
1485     # There seems to be a glitch in the way scons decides where to put
1486     # PDB files when compiling using MSVC so we specify it manually.
1487     # This should not affect any other platforms.
1488     pdb_name = library_name + '.dll.pdb'
1489     library = env.SharedLibrary(library_name, object_files, PDB=pdb_name)
1490     preparser_pdb_name = preparser_library_name + '.dll.pdb';
1491     preparser_soname = 'lib' + preparser_library_name + '.so';
1492     preparser_library = env.SharedLibrary(preparser_library_name,
1493                                           preparser_files,
1494                                           PDB=preparser_pdb_name,
1495                                           SONAME=preparser_soname)
1496   context.library_targets.append(library)
1497   context.library_targets.append(preparser_library)
1498
1499   context.ApplyEnvOverrides(d8_env)
1500   if context.options['library'] == 'static':
1501     shell = d8_env.Program('d8' + suffix, object_files + shell_files)
1502   else:
1503     shell = d8_env.Program('d8' + suffix, shell_files)
1504     d8_env.Depends(shell, library)
1505   context.d8_targets.append(shell)
1506
1507   for sample in context.samples:
1508     sample_env = Environment(tools=tools)
1509     sample_env.Replace(**context.flags['sample'])
1510     sample_env.Prepend(LIBS=[library_name])
1511     context.ApplyEnvOverrides(sample_env)
1512     sample_object = sample_env.SConscript(
1513       join('samples', 'SConscript'),
1514       build_dir=join('obj', 'sample', sample, target_id),
1515       exports='sample context tools',
1516       duplicate=False
1517     )
1518     sample_name = sample + suffix
1519     sample_program = sample_env.Program(sample_name, sample_object)
1520     sample_env.Depends(sample_program, library)
1521     context.sample_targets.append(sample_program)
1522
1523   cctest_env = env.Copy()
1524   cctest_env.Prepend(LIBS=[library_name])
1525   cctest_program = cctest_env.SConscript(
1526     join('test', 'cctest', 'SConscript'),
1527     build_dir=join('obj', 'test', target_id),
1528     exports='context object_files tools',
1529     duplicate=False
1530   )
1531   context.cctest_targets.append(cctest_program)
1532
1533   preparser_env = env.Copy()
1534   preparser_env.Replace(**context.flags['preparser'])
1535   preparser_env.Prepend(LIBS=[preparser_library_name])
1536   context.ApplyEnvOverrides(preparser_env)
1537   preparser_object = preparser_env.SConscript(
1538     join('preparser', 'SConscript'),
1539     build_dir=join('obj', 'preparser', target_id),
1540     exports='context tools',
1541     duplicate=False
1542   )
1543   preparser_name = join('obj', 'preparser', target_id, 'preparser')
1544   preparser_program = preparser_env.Program(preparser_name, preparser_object);
1545   preparser_env.Depends(preparser_program, preparser_library)
1546   context.preparser_targets.append(preparser_program)
1547
1548   return context
1549
1550
1551 def Build():
1552   opts = GetOptions()
1553   tools = GetTools(opts)
1554   env = Environment(options=opts, tools=tools)
1555
1556   Help(opts.GenerateHelpText(env))
1557   VerifyOptions(env)
1558   env_overrides = ParseEnvOverrides(env['env'], env['importenv'])
1559
1560   SourceSignatures(env['sourcesignatures'])
1561
1562   libraries = []
1563   mksnapshots = []
1564   cctests = []
1565   samples = []
1566   preparsers = []
1567   d8s = []
1568   modes = SplitList(env['mode'])
1569   for mode in modes:
1570     context = BuildSpecific(env.Copy(), mode, env_overrides, tools)
1571     libraries += context.library_targets
1572     mksnapshots += context.mksnapshot_targets
1573     cctests += context.cctest_targets
1574     samples += context.sample_targets
1575     preparsers += context.preparser_targets
1576     d8s += context.d8_targets
1577
1578   env.Alias('library', libraries)
1579   env.Alias('mksnapshot', mksnapshots)
1580   env.Alias('cctests', cctests)
1581   env.Alias('sample', samples)
1582   env.Alias('d8', d8s)
1583   env.Alias('preparser', preparsers)
1584
1585   if env['sample']:
1586     env.Default('sample')
1587   else:
1588     env.Default('library')
1589
1590   if env['cache']:
1591     CacheDir(env['cache'])
1592
1593 # We disable deprecation warnings because we need to be able to use
1594 # env.Copy without getting warnings for compatibility with older
1595 # version of scons.  Also, there's a bug in some revisions that
1596 # doesn't allow this flag to be set, so we swallow any exceptions.
1597 # Lovely.
1598 try:
1599   SetOption('warn', 'no-deprecated')
1600 except:
1601   pass
1602
1603
1604 Build()