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
28import platform
29import re
30import subprocess
31import sys
32import os
33from os.path import join, dirname, abspath
34from types import DictType, StringTypes
35root_dir = dirname(File('SConstruct').rfile().abspath)
36src_dir = join(root_dir, 'src')
37sys.path.insert(0, join(root_dir, 'tools'))
38import 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.
43ARM_TARGET_LIB = os.environ.get('ARM_TARGET_LIB')
44if 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']
49else:
50  ARM_LINK_FLAGS = []
51
52GCC_EXTRA_CCFLAGS = []
53GCC_DTOA_EXTRA_CCFLAGS = []
54
55LIBRARY_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
301V8_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
366MKSNAPSHOT_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
405DTOA_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
420CCTEST_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
477SAMPLE_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
669PREPARSER_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
830D8_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
938SUFFIXES = {
939  'release': '',
940  'debug': '_g'
941}
942
943
944def Abort(message):
945  print message
946  sys.exit(1)
947
948
949def GuessOS(env):
950  return utils.GuessOS()
951
952
953def GuessArch(env):
954  return utils.GuessArchitecture()
955
956
957def 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
967def 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
979def 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
995PLATFORM_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
1013SIMPLE_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
1163ALL_OPTIONS = dict(PLATFORM_OPTIONS, **SIMPLE_OPTIONS)
1164
1165
1166def 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
1180def 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
1192def 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
1204def 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
1227def 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
1235def 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
1247def SplitList(str):
1248  return [ s for s in str.split(",") if len(s) > 0 ]
1249
1250
1251def 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
1260def 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
1296class 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
1371def 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
1397def 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
1412def 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
1551def 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.
1598try:
1599  SetOption('warn', 'no-deprecated')
1600except:
1601  pass
1602
1603
1604Build()
1605