Home | History | Annotate | Download | only in v8
      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 
     28 import platform
     29 import re
     30 import subprocess
     31 import sys
     32 import os
     33 from os.path import join, dirname, abspath
     34 from types import DictType, StringTypes
     35 root_dir = dirname(File('SConstruct').rfile().abspath)
     36 sys.path.insert(0, join(root_dir, 'tools'))
     37 import 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.
     42 ANDROID_TOP = os.environ.get('TOP')
     43 if 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.
     49 ARM_TARGET_LIB = os.environ.get('ARM_TARGET_LIB')
     50 if 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']
     55 else:
     56   ARM_LINK_FLAGS = []
     57 
     58 GCC_EXTRA_CCFLAGS = []
     59 GCC_DTOA_EXTRA_CCFLAGS = []
     60 
     61 ANDROID_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 
     83 ANDROID_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 
     94 ANDROID_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 
    105 LIBRARY_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 
    332 V8_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 
    386 MKSNAPSHOT_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 
    417 DTOA_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 
    432 CCTEST_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 
    495 SAMPLE_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 
    636 PREPARSER_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 
    780 D8_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 
    822 SUFFIXES = {
    823   'release': '',
    824   'debug': '_g'
    825 }
    826 
    827 
    828 def Abort(message):
    829   print message
    830   sys.exit(1)
    831 
    832 
    833 def GuessOS(env):
    834   return utils.GuessOS()
    835 
    836 
    837 def GuessArch(env):
    838   return utils.GuessArchitecture()
    839 
    840 
    841 def 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 
    851 def 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 
    863 def 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 
    879 PLATFORM_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 
    897 SIMPLE_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 
   1036 ALL_OPTIONS = dict(PLATFORM_OPTIONS, **SIMPLE_OPTIONS)
   1037 
   1038 
   1039 def 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 
   1053 def 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 
   1065 def 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 
   1077 def 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 
   1100 def 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 
   1108 def 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 
   1120 def SplitList(str):
   1121   return [ s for s in str.split(",") if len(s) > 0 ]
   1122 
   1123 
   1124 def 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 
   1133 def 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 
   1167 class 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 
   1242 def 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 
   1272 def 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 
   1287 def 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 
   1420 def 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.
   1467 try:
   1468   SetOption('warn', 'no-deprecated')
   1469 except:
   1470   pass
   1471 
   1472 
   1473 Build()
   1474