Merge tools/gyp from https://chromium.googlesource.com/external/gyp.git at 6760f5b1a4852fd6ccbe4ffc409d73edac445744

This commit was generated by merge_from_chromium.py.

Change-Id: I89d5410386f4fcadf1e51460560ef91b7379e1db
diff --git a/pylib/gyp/generator/analyzer.py b/pylib/gyp/generator/analyzer.py
index 37a9e80..9c2ef9f 100644
--- a/pylib/gyp/generator/analyzer.py
+++ b/pylib/gyp/generator/analyzer.py
@@ -128,16 +128,20 @@
     _AddSources(action['inputs'], base_path, base_path_components, results)
 
 
+def _ToLocalPath(toplevel_dir, path):
+  """Converts |path| to a path relative to |toplevel_dir|."""
+  if path == toplevel_dir:
+    return ''
+  if path.startswith(toplevel_dir + '/'):
+    return path[len(toplevel_dir) + len('/'):]
+  return path
+
+
 def _ExtractSources(target, target_dict, toplevel_dir):
   # |target| is either absolute or relative and in the format of the OS. Gyp
   # source paths are always posix. Convert |target| to a posix path relative to
   # |toplevel_dir_|. This is done to make it easy to build source paths.
-  base_path = _ToGypPath(target)
-  if base_path == toplevel_dir:
-    base_path = ''
-  elif base_path.startswith(toplevel_dir + '/'):
-    base_path = base_path[len(toplevel_dir) + len('/'):]
-  base_path = posixpath.dirname(base_path)
+  base_path = posixpath.dirname(_ToLocalPath(toplevel_dir, _ToGypPath(target)))
   base_path_components = base_path.split('/')
 
   # Add a trailing '/' so that _AddSources() can easily build paths.
@@ -223,10 +227,11 @@
     self.targets = set(config.get('targets', []))
 
 
-def _WasBuildFileModified(build_file, data, files):
+def _WasBuildFileModified(build_file, data, files, toplevel_dir):
   """Returns true if the build file |build_file| is either in |files| or
-  one of the files included by |build_file| is in |files|."""
-  if _ToGypPath(build_file) in files:
+  one of the files included by |build_file| is in |files|. |toplevel_dir| is
+  the root of the source tree."""
+  if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files:
     if debug:
       print 'gyp file modified', build_file
     return True
@@ -239,7 +244,7 @@
     # |included_files| are relative to the directory of the |build_file|.
     rel_include_file = \
         _ToGypPath(gyp.common.UnrelativePath(include_file, build_file))
-    if rel_include_file in files:
+    if _ToLocalPath(toplevel_dir, rel_include_file) in files:
       if debug:
         print 'included gyp file modified, gyp_file=', build_file, \
             'included file=', rel_include_file
@@ -309,7 +314,7 @@
     build_file = gyp.common.ParseQualifiedTarget(target_name)[0]
     if not build_file in build_file_in_files:
       build_file_in_files[build_file] = \
-          _WasBuildFileModified(build_file, data, files)
+          _WasBuildFileModified(build_file, data, files, toplevel_dir)
 
     if build_file in build_files:
       build_file_targets.add(target)
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py
index 4eafb71..3336a89 100644
--- a/pylib/gyp/generator/ninja.py
+++ b/pylib/gyp/generator/ninja.py
@@ -805,6 +805,8 @@
       self.ninja.variable('cxx', '$cxx_host')
       self.ninja.variable('ld', '$ld_host')
       self.ninja.variable('ldxx', '$ldxx_host')
+      self.ninja.variable('nm', '$nm_host')
+      self.ninja.variable('readelf', '$readelf_host')
 
     if self.flavor != 'mac' or len(self.archs) == 1:
       return self.WriteSourcesForArch(
@@ -1742,6 +1744,10 @@
   cc_host_global_setting = None
   cxx_host_global_setting = None
   clang_cl = None
+  nm = 'nm'
+  nm_host = 'nm'
+  readelf = 'readelf'
+  readelf_host = 'readelf'
 
   build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
   make_global_settings = data[build_file].get('make_global_settings', [])
@@ -1769,6 +1775,14 @@
       ld = os.path.join(build_to_root, value)
     if key == 'LD.host':
       ld_host = os.path.join(build_to_root, value)
+    if key == 'NM':
+      nm = os.path.join(build_to_root, value)
+    if key == 'NM.host':
+      nm_host = os.path.join(build_to_root, value)
+    if key == 'READELF':
+      readelf = os.path.join(build_to_root, value)
+    if key == 'READELF.host':
+      readelf_host = os.path.join(build_to_root, value)
     if key.endswith('_wrapper'):
       wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value)
 
@@ -1816,6 +1830,13 @@
     master_ninja.variable('ld', CommandWithWrapper('LINK', wrappers, ld))
     master_ninja.variable('ldxx', CommandWithWrapper('LINK', wrappers, ldxx))
     master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], ar))
+    if flavor != 'mac':
+      # Mac does not use readelf/nm for .TOC generation, so avoiding polluting
+      # the master ninja with extra unused variables.
+      master_ninja.variable(
+          'nm', GetEnvironFallback(['NM_target', 'NM'], nm))
+      master_ninja.variable(
+          'readelf', GetEnvironFallback(['READELF_target', 'READELF'], readelf))
 
   if generator_supports_multiple_toolsets:
     if not cc_host:
@@ -1824,6 +1845,9 @@
       cxx_host = cxx
 
     master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], ar_host))
+    master_ninja.variable('nm_host', GetEnvironFallback(['NM_host'], nm_host))
+    master_ninja.variable('readelf_host',
+                          GetEnvironFallback(['READELF_host'], readelf_host))
     cc_host = GetEnvironFallback(['CC_host'], cc_host)
     cxx_host = GetEnvironFallback(['CXX_host'], cxx_host)
 
@@ -1945,8 +1969,8 @@
         % { 'solink':
               '$ld -shared $ldflags -o $lib -Wl,-soname=$soname %(suffix)s',
             'extract_toc':
-              ('{ readelf -d $lib | grep SONAME ; '
-               'nm -gD -f p $lib | cut -f1-2 -d\' \'; }')})
+              ('{ $readelf -d $lib | grep SONAME ; '
+               '$nm -gD -f p $lib | cut -f1-2 -d\' \'; }')})
 
     master_ninja.rule(
       'solink',
diff --git a/test/compiler-override/compiler.gyp b/test/compiler-override/compiler-exe.gyp
similarity index 100%
rename from test/compiler-override/compiler.gyp
rename to test/compiler-override/compiler-exe.gyp
diff --git a/test/compiler-override/compiler-shared-lib.gyp b/test/compiler-override/compiler-shared-lib.gyp
new file mode 100644
index 0000000..d3e4316
--- /dev/null
+++ b/test/compiler-override/compiler-shared-lib.gyp
@@ -0,0 +1,16 @@
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'targets': [
+    {
+      'target_name': 'hello-lib',
+      'type': 'shared_library',
+      'sources': [
+        'test.c',
+        'cxxtest.cc',
+      ],
+    },
+  ],
+}
diff --git a/test/compiler-override/gyptest-compiler-env-toolchain.py b/test/compiler-override/gyptest-compiler-env-toolchain.py
new file mode 100644
index 0000000..c27be24
--- /dev/null
+++ b/test/compiler-override/gyptest-compiler-env-toolchain.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""
+Verifies that the user can override the compiler and linker using
+CC/CXX/NM/READELF environment variables.
+"""
+
+import TestGyp
+import os
+import copy
+import sys
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+if sys.platform == 'win32':
+  # cross compiling not supported by ninja on windows
+  # and make not supported on windows at all.
+  sys.exit(0)
+
+# Clear any existing compiler related env vars.
+for key in ['CC', 'CXX', 'LINK', 'CC_host', 'CXX_host', 'LINK_host',
+            'NM_target', 'READELF_target']:
+  if key in os.environ:
+    del os.environ[key]
+
+
+def CheckCompiler(test, gypfile, check_for, run_gyp):
+  if run_gyp:
+    test.run_gyp(gypfile)
+  test.build(gypfile)
+
+  test.must_contain_all_lines(test.stdout(), check_for)
+
+
+test = TestGyp.TestGyp(formats=['ninja'])
+# Must set the test format to something with a flavor (the part after the '-')
+# in order to test the desired behavior. Since we want to run a non-host
+# toolchain, we have to set the flavor to something that the ninja generator
+# doesn't know about, so it doesn't default to the host-specific tools (e.g.,
+# 'otool' on mac to generate the .TOC).
+#
+# Note that we can't just pass format=['ninja-some_toolchain'] to the
+# constructor above, because then this test wouldn't be recognized as a ninja
+# format test.
+test.formats = ['ninja-some_flavor']
+
+
+def TestTargetOverideSharedLib():
+  # The std output from nm and readelf is redirected to files, so we can't
+  # expect their output to appear. Instead, check for the files they create to
+  # see if they actually ran.
+  expected = ['my_cc.py', 'my_cxx.py', 'FOO']
+
+  # Check that CC, CXX, NM, READELF, set target compiler
+  env = {'CC': 'python %s/my_cc.py FOO' % here,
+         'CXX': 'python %s/my_cxx.py FOO' % here,
+         'NM': 'python %s/my_nm.py' % here,
+         'READELF': 'python %s/my_readelf.py' % here}
+
+  with TestGyp.LocalEnv(env):
+    CheckCompiler(test, 'compiler-shared-lib.gyp', expected, True)
+    test.must_contain(test.built_file_path('RAN_MY_NM'), 'RAN_MY_NM')
+    test.must_contain(test.built_file_path('RAN_MY_READELF'), 'RAN_MY_READELF')
+    test.unlink(test.built_file_path('RAN_MY_NM'))
+    test.unlink(test.built_file_path('RAN_MY_READELF'))
+
+  # Run the same tests once the eviron has been restored.  The generated
+  # projects should have embedded all the settings in the project files so the
+  # results should be the same.
+  CheckCompiler(test, 'compiler-shared-lib.gyp', expected, False)
+  test.must_contain(test.built_file_path('RAN_MY_NM'), 'RAN_MY_NM')
+  test.must_contain(test.built_file_path('RAN_MY_READELF'), 'RAN_MY_READELF')
+
+
+TestTargetOverideSharedLib()
+test.pass_test()
diff --git a/test/compiler-override/gyptest-compiler-env.py b/test/compiler-override/gyptest-compiler-env.py
index d13d692..6408ae1 100755
--- a/test/compiler-override/gyptest-compiler-env.py
+++ b/test/compiler-override/gyptest-compiler-env.py
@@ -15,7 +15,7 @@
 here = os.path.dirname(os.path.abspath(__file__))
 
 if sys.platform == 'win32':
-  # cross compiling not support by ninja on windows
+  # cross compiling not supported by ninja on windows
   # and make not supported on windows at all.
   sys.exit(0)
 
@@ -30,8 +30,6 @@
     test.run_gyp(gypfile)
   test.build(gypfile)
 
-  # We can't test to presence of my_ld.py in the output since
-  # ninja will use CXX_target as the linker regardless
   test.must_contain_all_lines(test.stdout(), check_for)
 
 
@@ -49,8 +47,7 @@
     os.environ['CXX'] = 'python %s/my_cxx.py FOO' % here
     os.environ['LINK'] = 'python %s/my_ld.py FOO_LINK' % here
 
-    CheckCompiler(test, 'compiler.gyp', expected,
-                  True)
+    CheckCompiler(test, 'compiler-exe.gyp', expected, True)
   finally:
     os.environ.clear()
     os.environ.update(oldenv)
@@ -58,8 +55,8 @@
   # Run the same tests once the eviron has been restored.  The
   # generated should have embedded all the settings in the
   # project files so the results should be the same.
-  CheckCompiler(test, 'compiler.gyp', expected,
-                False)
+  CheckCompiler(test, 'compiler-exe.gyp', expected, False)
+
 
 def TestTargetOverideCompilerOnly():
   # Same test again but with that CC, CXX and not LD
@@ -68,7 +65,7 @@
     os.environ['CC'] = 'python %s/my_cc.py FOO' % here
     os.environ['CXX'] = 'python %s/my_cxx.py FOO' % here
 
-    CheckCompiler(test, 'compiler.gyp',
+    CheckCompiler(test, 'compiler-exe.gyp',
                   ['my_cc.py', 'my_cxx.py', 'FOO'],
                   True)
   finally:
@@ -78,7 +75,7 @@
   # Run the same tests once the eviron has been restored.  The
   # generated should have embedded all the settings in the
   # project files so the results should be the same.
-  CheckCompiler(test, 'compiler.gyp',
+  CheckCompiler(test, 'compiler-exe.gyp',
                 ['my_cc.py', 'my_cxx.py', 'FOO'],
                 False)
 
diff --git a/test/compiler-override/my_nm.py b/test/compiler-override/my_nm.py
new file mode 100755
index 0000000..f0f1efc
--- /dev/null
+++ b/test/compiler-override/my_nm.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_NM', 'w') as f:
+  f.write('RAN_MY_NM')
diff --git a/test/compiler-override/my_readelf.py b/test/compiler-override/my_readelf.py
new file mode 100755
index 0000000..40e303c
--- /dev/null
+++ b/test/compiler-override/my_readelf.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_READELF', 'w') as f:
+  f.write('RAN_MY_READELF')
diff --git a/test/make_global_settings/full-toolchain/bar.cc b/test/make_global_settings/full-toolchain/bar.cc
new file mode 100644
index 0000000..afb422b
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/bar.cc
@@ -0,0 +1 @@
+#error Not a real source file
diff --git a/test/make_global_settings/full-toolchain/foo.c b/test/make_global_settings/full-toolchain/foo.c
new file mode 100644
index 0000000..afb422b
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/foo.c
@@ -0,0 +1 @@
+#error Not a real source file
diff --git a/test/make_global_settings/full-toolchain/gyptest-make_global_settings.py b/test/make_global_settings/full-toolchain/gyptest-make_global_settings.py
new file mode 100644
index 0000000..0dd148c
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/gyptest-make_global_settings.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies make_global_settings works with the full toolchain.
+"""
+
+import os
+import sys
+import TestGyp
+
+if sys.platform == 'win32':
+  # cross compiling not supported by ninja on windows
+  # and make not supported on windows at all.
+  sys.exit(0)
+
+test = TestGyp.TestGyp(formats=['ninja'])
+# Must set the test format to something with a flavor (the part after the '-')
+# in order to test the desired behavior. Since we want to run a non-host
+# toolchain, we have to set the flavor to something that the ninja generator
+# doesn't know about, so it doesn't default to the host-specific tools (e.g.,
+# 'otool' on mac to generate the .TOC).
+#
+# Note that we can't just pass format=['ninja-some_toolchain'] to the
+# constructor above, because then this test wouldn't be recognized as a ninja
+# format test.
+test.formats = ['ninja-some_flavor']
+
+gyp_file = 'make_global_settings.gyp'
+
+test.run_gyp(gyp_file,
+             # Teach the .gyp file about the location of my_nm.py and
+             # my_readelf.py, and the python executable.
+             '-Dworkdir=%s' % test.workdir,
+             '-Dpython=%s' % sys.executable)
+test.build(gyp_file, arguments=['-v'])
+
+expected = ['MY_CC', 'MY_CXX']
+test.must_contain_all_lines(test.stdout(), expected)
+
+test.must_contain(test.built_file_path('RAN_MY_NM'), 'RAN_MY_NM')
+test.must_contain(test.built_file_path('RAN_MY_READELF'), 'RAN_MY_READELF')
+
+test.pass_test()
diff --git a/test/make_global_settings/full-toolchain/make_global_settings.gyp b/test/make_global_settings/full-toolchain/make_global_settings.gyp
new file mode 100644
index 0000000..2c32663
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/make_global_settings.gyp
@@ -0,0 +1,22 @@
+# Copyright (c) 2013 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style licence that can be
+# found in the LICENSE file.
+
+{
+  'make_global_settings': [
+    ['CC', '/bin/echo MY_CC'],
+    ['CXX', '/bin/echo MY_CXX'],
+    ['NM', '<(python) <(workdir)/my_nm.py'],
+    ['READELF', '<(python) <(workdir)/my_readelf.py'],
+  ],
+  'targets': [
+    {
+      'target_name': 'test',
+      'type': 'shared_library',
+      'sources': [
+        'foo.c',
+        'bar.cc',
+      ],
+    },
+  ],
+}
diff --git a/test/make_global_settings/full-toolchain/my_nm.py b/test/make_global_settings/full-toolchain/my_nm.py
new file mode 100755
index 0000000..f0f1efc
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/my_nm.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_NM', 'w') as f:
+  f.write('RAN_MY_NM')
diff --git a/test/make_global_settings/full-toolchain/my_readelf.py b/test/make_global_settings/full-toolchain/my_readelf.py
new file mode 100755
index 0000000..40e303c
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/my_readelf.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_READELF', 'w') as f:
+  f.write('RAN_MY_READELF')