Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / driver / pnacl-driver.py
index 16d25f6..fa23f32 100755 (executable)
@@ -2,17 +2,17 @@
 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-#
-# IMPORTANT NOTE: If you make local mods to this file, you must run:
-#   %  pnacl/build.sh driver
-# in order for them to take effect in the scons build.  This command
-# updates the copy in the toolchain/ tree.
-#
-
-from driver_tools import *
+
+import re
+import subprocess
+
+from driver_tools import AddHostBinarySearchPath, DefaultOutputName, \
+    DefaultPCHOutputName, DriverChain, GetArch, ParseArgs, ParseTriple, \
+    Run, RunDriver, RunWithEnv, TempNameGen, UnrecognizedOption
 from driver_env import env
-from driver_log import Log
+from driver_log import DriverOpen, Log
 import filetype
+import pathtools
 
 EXTRA_ENV = {
   'ALLOW_TRANSLATE': '0',  # Allow bitcode translation before linking.
@@ -71,6 +71,8 @@ EXTRA_ENV = {
   'BIAS_MIPS32' : '-D__MIPS__ -D__mips__ -D__MIPSEL__',
   'BIAS_X8632'  : '-D__i386__ -D__i386 -D__i686 -D__i686__ -D__pentium4__',
   'BIAS_X8664'  : '-D__amd64__ -D__amd64 -D__x86_64__ -D__x86_64 -D__core2__',
+  'BIAS_ARM_NONSFI': '${BIAS_ARM} -D__native_client_nonsfi__',
+  'BIAS_X8632_NONSFI': '${BIAS_X8632} -D__native_client_nonsfi__',
   'FRONTEND_TRIPLE' : 'le32-unknown-nacl',
 
   'OPT_LEVEL'   : '',  # Default for most tools is 0, but we need to know
@@ -94,13 +96,13 @@ EXTRA_ENV = {
                           # using the -isystem flag.
 
   'ISYSTEM_BUILTIN':
-    '${BASE_USR}/local/include ' +
+    '${BASE_USR}/usr/include ' +
     '${ISYSTEM_CLANG} ' +
     '${ISYSTEM_CXX} ' +
     '${BASE_USR}/include ' +
     '${BASE_SDK}/include ',
 
-  'ISYSTEM_CLANG'  : '${BASE_LLVM}/lib/clang/3.3/include',
+  'ISYSTEM_CLANG'  : '${BASE_LLVM}/lib/clang/${CLANG_VER}/include',
 
   'ISYSTEM_CXX' :
     '${INCLUDE_CXX_HEADERS && STDINCCXX ? ${ISYSTEM_CXX_include_paths}}',
@@ -153,7 +155,7 @@ EXTRA_ENV = {
 
   # IS_CXX is set by pnacl-clang and pnacl-clang++ programmatically
   'CC' : '${IS_CXX ? ${CLANGXX} : ${CLANG}}',
-  'RUN_CC': '${CC} -emit-llvm ${mode} ${CC_FLAGS} ' +
+  'RUN_CC': '${CC} ${emit_llvm_flag} ${mode} ${CC_FLAGS} ' +
             '${@AddPrefix:-isystem :ISYSTEM} ' +
             '-x${typespec} "${infile}" -o ${output}',
 }
@@ -262,7 +264,6 @@ CustomPatterns = [
   ( '(--pnacl-allow-nexe-build-id)', AddLDFlag),
   ( '(--pnacl-disable-abi-check)',  AddLDFlag),
   ( '(--pnacl-disable-pass=.+)',    AddLLVMPassDisableFlag),
-  ( '(--pnacl-allow-dev-intrinsics)', AddLDFlag),
 ]
 
 GCCPatterns = [
@@ -316,6 +317,13 @@ GCCPatterns = [
                        "env.append('ISYSTEM_USER', pathtools.normalize($0))"),
   ( ('-I', '(.+)'),    "env.append('CC_FLAGS', '-I'+pathtools.normalize($0))"),
   ( '-I(.+)',          "env.append('CC_FLAGS', '-I'+pathtools.normalize($0))"),
+  # -I is passed through, so we allow -isysroot and pass it through as well.
+  # However -L is intercepted and interpreted, so it would take more work
+  # to handle -sysroot w/ libraries.
+  ( ('-isysroot', '(.+)'),
+        "env.append('CC_FLAGS', '-isysroot ' + pathtools.normalize($0))"),
+  ( '-isysroot(.+)',
+        "env.append('CC_FLAGS', '-isysroot ' + pathtools.normalize($0))"),
 
   # NOTE: the -iquote =DIR syntax (substitute = with sysroot) doesn't work.
   # Clang just says: ignoring nonexistent directory "=DIR"
@@ -331,6 +339,7 @@ GCCPatterns = [
 
   ( ('(-include)','(.+)'),    AddCCFlag),
   ( ('(-include.+)'),         AddCCFlag),
+  ( '(--relocatable-pch)',    AddCCFlag),
   ( '(-g)',                   AddCCFlag),
   ( '(-W.*)',                 AddCCFlag),
   ( '(-w)',                   AddCCFlag),
@@ -446,7 +455,6 @@ def DriverOutputTypes(driver_flag, compiling_to_native):
 
 
 def ReadDriverRevision():
-  nacl_version = 'unknown'
   rev_file = env.getone('DRIVER_REV_FILE')
   # Might be an SVN version or a GIT hash (depending on the NaCl src client)
   nacl_ver = DriverOpen(rev_file, 'rb').readlines()[0]
@@ -491,17 +499,25 @@ def main(argv):
   # If -arch was given, we are compiling directly to native code
   compiling_to_native = GetArch() is not None
 
-  if env.getbool('ALLOW_NATIVE') and not compiling_to_native:
-    Log.Fatal("--pnacl-allow-native without -arch is not meaningful.")
+  if env.getbool('ALLOW_NATIVE'):
+    if not compiling_to_native:
+      Log.Fatal("--pnacl-allow-native without -arch is not meaningful.")
+    # For native/mixed links, also bring in the native libgcc and
+    # libcrt_platform to avoid link failure if pre-translated native
+    # code needs functions from it.
+    env.append('LD_FLAGS', env.eval('-L${LIBS_NATIVE_ARCH}'))
+    env.append('STDLIBS', '-lgcc')
+    env.append('STDLIBS', '-lcrt_platform')
+
 
   if not env.get('STDLIB'):
     # Default C++ Standard Library.
     SetStdLib('libc++')
 
-  inputs = env.get('INPUTS')
+  flags_and_inputs = env.get('INPUTS')
   output = env.getone('OUTPUT')
 
-  if len(inputs) == 0:
+  if len(flags_and_inputs) == 0:
     if env.getbool('VERBOSE'):
       # -v can be invoked without any inputs. Runs the original
       # command without modifying the commandline for this case.
@@ -512,6 +528,24 @@ def main(argv):
 
   gcc_mode = env.getone('GCC_MODE')
   output_type = DriverOutputTypes(gcc_mode, compiling_to_native)
+  # INPUTS consists of actual input files and a subset of flags like -Wl,<foo>.
+  # Create a version with just the files.
+  inputs = [f for f in flags_and_inputs if not IsFlag(f)]
+  header_inputs = [f for f in inputs
+                   if filetype.IsHeaderType(filetype.FileType(f))]
+  # Handle PCH case specially (but only for a limited sense...)
+  if header_inputs and gcc_mode != '-E':
+    # We only handle doing pre-compiled headers for all inputs or not at
+    # all at the moment. This is because DriverOutputTypes only assumes
+    # one type of output, depending on the "gcc_mode" flag. When mixing
+    # header inputs w/ non-header inputs, some of the outputs will be
+    # pch while others will be output_type. We would also need to modify
+    # the input->output chaining for the needs_linking case.
+    if len(header_inputs) != len(inputs):
+      Log.Fatal('mixed compiling of headers and source not supported')
+    CompileHeaders(header_inputs, output)
+    return 0
+
   needs_linking = (gcc_mode == '')
 
   if env.getbool('NEED_DASH_E') and gcc_mode != '-E':
@@ -520,17 +554,13 @@ def main(argv):
   # There are multiple input files and no linking is being done.
   # There will be multiple outputs. Handle this case separately.
   if not needs_linking:
-    # Filter out flags
-    inputs = [f for f in inputs if not IsFlag(f)]
     if output != '' and len(inputs) > 1:
       Log.Fatal('Cannot have -o with -c, -S, or -E and multiple inputs: %s',
                 repr(inputs))
 
     for f in inputs:
-      if IsFlag(f):
-        continue
       intype = filetype.FileType(f)
-      if not filetype.IsSourceType(intype):
+      if not (filetype.IsSourceType(intype) or filetype.IsHeaderType(intype)):
         if ((output_type == 'pp' and intype != 'S') or
             (output_type == 'll') or
             (output_type == 'po' and intype != 'll') or
@@ -554,27 +584,27 @@ def main(argv):
 
   if output == '':
     output = pathtools.normalize('a.out')
-  namegen = TempNameGen(inputs, output)
+  namegen = TempNameGen(flags_and_inputs, output)
 
   # Compile all source files (c/c++/ll) to .po
-  for i in xrange(0, len(inputs)):
-    if IsFlag(inputs[i]):
+  for i in xrange(0, len(flags_and_inputs)):
+    if IsFlag(flags_and_inputs[i]):
       continue
-    intype = filetype.FileType(inputs[i])
+    intype = filetype.FileType(flags_and_inputs[i])
     if filetype.IsSourceType(intype) or intype == 'll':
-      inputs[i] = CompileOne(inputs[i], 'po', namegen)
+      flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'po', namegen)
 
   # Compile all .s/.S to .o
   if env.getbool('ALLOW_NATIVE'):
-    for i in xrange(0, len(inputs)):
-      if IsFlag(inputs[i]):
+    for i in xrange(0, len(flags_and_inputs)):
+      if IsFlag(flags_and_inputs[i]):
         continue
-      intype = filetype.FileType(inputs[i])
+      intype = filetype.FileType(flags_and_inputs[i])
       if intype in ('s','S'):
-        inputs[i] = CompileOne(inputs[i], 'o', namegen)
+        flags_and_inputs[i] = CompileOne(flags_and_inputs[i], 'o', namegen)
 
   # We should only be left with .po and .o and libraries
-  for f in inputs:
+  for f in flags_and_inputs:
     if IsFlag(f):
       continue
     intype = filetype.FileType(f)
@@ -586,7 +616,7 @@ def main(argv):
 
   # Fix the user-specified linker arguments
   ld_inputs = []
-  for f in inputs:
+  for f in flags_and_inputs:
     if f.startswith('-Xlinker='):
       ld_inputs.append(f[len('-Xlinker='):])
     elif f.startswith('-Wl,'):
@@ -603,12 +633,20 @@ def main(argv):
   ld_args = env.get('LD_ARGS')
   ld_flags = env.get('LD_FLAGS')
 
-  RunDriver('ld', ld_flags + ld_args + ['-o', output])
+  RunDriver('pnacl-ld', ld_flags + ld_args + ['-o', output])
   return 0
 
 def IsFlag(f):
   return f.startswith('-')
 
+def CompileHeaders(header_inputs, output):
+  if output != '' and len(header_inputs) > 1:
+      Log.Fatal('Cannot have -o <out> and compile multiple header files: %s',
+                repr(header_inputs))
+  for f in header_inputs:
+    f_output = output if output else DefaultPCHOutputName(f)
+    RunCC(f, f_output, mode='', emit_llvm_flag='')
+
 def CompileOne(infile, output_type, namegen, output = None):
   if output is None:
     output = namegen.TempNameForInput(infile, output_type)
@@ -618,15 +656,16 @@ def CompileOne(infile, output_type, namegen, output = None):
   chain.run()
   return output
 
-def RunCC(infile, output, mode):
+def RunCC(infile, output, mode, emit_llvm_flag='-emit-llvm'):
   intype = filetype.FileType(infile)
   typespec = filetype.FileTypeToGCCType(intype)
-  include_cxx_headers = (env.get('LANGUAGE') == 'CXX') or (intype == 'c++')
+  include_cxx_headers = ((env.get('LANGUAGE') == 'CXX') or
+                         (intype in ('c++', 'c++-header')))
   env.setbool('INCLUDE_CXX_HEADERS', include_cxx_headers)
   if IsStdinInput(infile):
     infile = '-'
   RunWithEnv("${RUN_CC}", infile=infile, output=output,
-                          mode=mode,
+                          emit_llvm_flag=emit_llvm_flag, mode=mode,
                           typespec=typespec)
 
 def RunLLVMAS(infile, output):
@@ -634,12 +673,13 @@ def RunLLVMAS(infile, output):
     infile = '-'
   # This is a bitcode only step - so get rid of "-arch xxx" which
   # might be inherited from the current invocation
-  RunDriver('as', [infile, '-o', output], suppress_inherited_arch_args=True)
+  RunDriver('pnacl-as', [infile, '-o', output],
+            suppress_inherited_arch_args=True)
 
 def RunNativeAS(infile, output):
   if IsStdinInput(infile):
     infile = '-'
-  RunDriver('as', [infile, '-o', output])
+  RunDriver('pnacl-as', [infile, '-o', output])
 
 def RunTranslate(infile, output, mode):
   if not env.getbool('ALLOW_TRANSLATE'):
@@ -651,13 +691,13 @@ def RunTranslate(infile, output, mode):
                                        infile, '-o', output]
   if env.getbool('PIC'):
     args += ['-fPIC']
-  RunDriver('translate', args)
+  RunDriver('pnacl-translate', args)
 
 
 def RunOpt(infile, outfile, pass_list):
   filtered_list = [pass_option for pass_option in pass_list
                    if pass_option not in env.get('LLVM_PASSES_TO_DISABLE')]
-  RunDriver('opt', filtered_list + [infile, '-o', outfile])
+  RunDriver('pnacl-opt', filtered_list + [infile, '-o', outfile])
 
 
 def SetupChain(chain, input_type, output_type):
@@ -671,6 +711,13 @@ def SetupChain(chain, input_type, output_type):
   if cur_type == output_type:
     return
 
+  # header file -> pre-process
+  if filetype.IsHeaderType(cur_type) and output_type == 'pp':
+    chain.add(RunCC, 'cpp', mode='-E')
+    cur_type = 'pp'
+  if cur_type == output_type:
+    return
+
   # source file -> ll
   if (filetype.IsSourceType(cur_type) and
      (env.getbool('FORCE_INTERMEDIATE_LL') or output_type == 'll')):