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