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