summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@78cadc50-ecff-11dd-a971-7dbc132099af>2012-09-11 22:19:08 +0000
committerthakis@chromium.org <thakis@chromium.org@78cadc50-ecff-11dd-a971-7dbc132099af>2012-09-11 22:19:08 +0000
commit986c94a9dbf47043bb0d346fb5cde86ab10feea6 (patch)
tree1e44749dec443e247dac9740773b5cd0683a9836
parent7fd6d6348eda44586628799a31fa6620aa47b124 (diff)
downloadgyp-986c94a9dbf47043bb0d346fb5cde86ab10feea6.tar.gz
ninja: Survive case-only file renames on case-insensitive filesystems.
See https://github.com/martine/ninja/issues/402 for more information. Review URL: https://chromiumcodereview.appspot.com/10907140 git-svn-id: http://gyp.googlecode.com/svn/trunk@1494 78cadc50-ecff-11dd-a971-7dbc132099af
-rw-r--r--pylib/gyp/generator/ninja.py19
-rw-r--r--test/rename/extension/file.c2
-rw-r--r--test/rename/extension/file.cc2
-rw-r--r--test/rename/extension/test.gyp13
-rw-r--r--test/rename/filecase/file.c1
-rw-r--r--test/rename/filecase/test-casesensitive.gyp15
-rw-r--r--test/rename/filecase/test.gyp14
-rw-r--r--test/rename/gyptest-extension.py28
-rw-r--r--test/rename/gyptest-filecase.py35
9 files changed, 125 insertions, 4 deletions
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py
index 4921e147..4571c25e 100644
--- a/pylib/gyp/generator/ninja.py
+++ b/pylib/gyp/generator/ninja.py
@@ -354,7 +354,8 @@ class NinjaWriter:
self.ninja.newline()
return targets[0]
- def WriteSpec(self, spec, config_name, generator_flags):
+ def WriteSpec(self, spec, config_name, generator_flags,
+ case_sensitive_filesystem):
"""The main entry point for NinjaWriter: write the build rules for a spec.
Returns a Target object, which represents the output paths for this spec.
@@ -428,7 +429,8 @@ class NinjaWriter:
self.xcode_settings, self.GypPathToNinja,
lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))
link_deps = self.WriteSources(
- config_name, config, sources, compile_depends_stamp, pch)
+ config_name, config, sources, compile_depends_stamp, pch,
+ case_sensitive_filesystem)
# Some actions/rules output 'sources' that are already object files.
link_deps += [self.GypPathToNinja(f)
for f in sources if f.endswith(self.obj_ext)]
@@ -705,7 +707,7 @@ class NinjaWriter:
bundle_depends.append(out)
def WriteSources(self, config_name, config, sources, predepends,
- precompiled_header):
+ precompiled_header, case_sensitive_filesystem):
"""Write build rules to compile all of |sources|."""
if self.toolset == 'host':
self.ninja.variable('ar', '$ar_host')
@@ -798,6 +800,12 @@ class NinjaWriter:
continue
input = self.GypPathToNinja(source)
output = self.GypPathToUniqueOutput(filename + obj_ext)
+ # Ninja's depfile handling gets confused when the case of a filename
+ # changes on a case-insensitive file system. To work around that, always
+ # convert .o filenames to lowercase on such file systems. See
+ # https://github.com/martine/ninja/issues/402 for details.
+ if not case_sensitive_filesystem:
+ output = output.lower()
implicit = precompiled_header.GetObjDependencies([input], [output])
self.ninja.build(output, command, input,
implicit=[gch for _, _, gch in implicit],
@@ -1296,6 +1304,8 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
master_ninja = ninja_syntax.Writer(
OpenOutput(os.path.join(toplevel_build, 'build.ninja')),
width=120)
+ case_sensitive_filesystem = not os.path.exists(
+ os.path.join(toplevel_build, 'BUILD.NINJA'))
# Put build-time support tools in out/{config_name}.
gyp.common.CopyTool(flavor, toplevel_build)
@@ -1682,7 +1692,8 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
flavor, abs_build_dir=abs_build_dir)
master_ninja.subninja(output_file)
- target = writer.WriteSpec(spec, config_name, generator_flags)
+ target = writer.WriteSpec(
+ spec, config_name, generator_flags, case_sensitive_filesystem)
if target:
if name != target.FinalOutput() and spec['toolset'] == 'target':
target_short_names.setdefault(name, []).append(target)
diff --git a/test/rename/extension/file.c b/test/rename/extension/file.c
new file mode 100644
index 00000000..5241aebb
--- /dev/null
+++ b/test/rename/extension/file.c
@@ -0,0 +1,2 @@
+#include <stdio.h>
+int main() { printf("C\n"); return 0; }
diff --git a/test/rename/extension/file.cc b/test/rename/extension/file.cc
new file mode 100644
index 00000000..e6c50f7d
--- /dev/null
+++ b/test/rename/extension/file.cc
@@ -0,0 +1,2 @@
+#include <stdio.h>
+int main() { printf("C++\n"); }
diff --git a/test/rename/extension/test.gyp b/test/rename/extension/test.gyp
new file mode 100644
index 00000000..16acdfb2
--- /dev/null
+++ b/test/rename/extension/test.gyp
@@ -0,0 +1,13 @@
+# 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': 'extrename',
+ 'type': 'executable',
+ 'sources': [ 'file.c', ],
+ },
+ ],
+}
+
diff --git a/test/rename/filecase/file.c b/test/rename/filecase/file.c
new file mode 100644
index 00000000..237c8ce1
--- /dev/null
+++ b/test/rename/filecase/file.c
@@ -0,0 +1 @@
+int main() {}
diff --git a/test/rename/filecase/test-casesensitive.gyp b/test/rename/filecase/test-casesensitive.gyp
new file mode 100644
index 00000000..48eaa6eb
--- /dev/null
+++ b/test/rename/filecase/test-casesensitive.gyp
@@ -0,0 +1,15 @@
+# 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': 'filecaserename_sensitive',
+ 'type': 'executable',
+ 'sources': [
+ 'FiLe.c',
+ 'fIlE.c',
+ ],
+ },
+ ],
+}
diff --git a/test/rename/filecase/test.gyp b/test/rename/filecase/test.gyp
new file mode 100644
index 00000000..eaee9337
--- /dev/null
+++ b/test/rename/filecase/test.gyp
@@ -0,0 +1,14 @@
+# 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': 'filecaserename',
+ 'type': 'executable',
+ 'sources': [
+ 'file.c',
+ ],
+ },
+ ],
+}
diff --git a/test/rename/gyptest-extension.py b/test/rename/gyptest-extension.py
new file mode 100644
index 00000000..03b7e1c7
--- /dev/null
+++ b/test/rename/gyptest-extension.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2010 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.
+
+"""
+Checks that files whose extension changes get rebuilt correctly.
+"""
+
+import os
+import TestGyp
+
+# .c -> .cc renames don't work with make. # XXX
+test = TestGyp.TestGyp()#formats=['!make'])
+CHDIR = 'extension'
+test.run_gyp('test.gyp', chdir=CHDIR)
+test.build('test.gyp', test.ALL, chdir=CHDIR)
+test.run_built_executable('extrename', stdout="C\n", chdir=CHDIR)
+
+test.write('extension/test.gyp',
+ test.read('extension/test.gyp').replace('file.c', 'file.cc'))
+test.run_gyp('test.gyp', chdir=CHDIR)
+test.build('test.gyp', test.ALL, chdir=CHDIR)
+test.run_built_executable('extrename', stdout="C++\n", chdir=CHDIR)
+
+test.pass_test()
+
diff --git a/test/rename/gyptest-filecase.py b/test/rename/gyptest-filecase.py
new file mode 100644
index 00000000..daed5180
--- /dev/null
+++ b/test/rename/gyptest-filecase.py
@@ -0,0 +1,35 @@
+#!/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.
+
+"""
+Checks that files whose file case changes get rebuilt correctly.
+"""
+
+import os
+import TestGyp
+
+test = TestGyp.TestGyp()
+CHDIR = 'filecase'
+test.run_gyp('test.gyp', chdir=CHDIR)
+test.build('test.gyp', test.ALL, chdir=CHDIR)
+
+os.rename('filecase/file.c', 'filecase/fIlE.c')
+test.write('filecase/test.gyp',
+ test.read('filecase/test.gyp').replace('file.c', 'fIlE.c'))
+test.run_gyp('test.gyp', chdir=CHDIR)
+test.build('test.gyp', test.ALL, chdir=CHDIR)
+
+
+# Check that having files that differ just in their case still work on
+# case-sensitive file systems.
+test.write('filecase/FiLe.c', 'int f(); int main() { return f(); }')
+test.write('filecase/fIlE.c', 'int f() { return 42; }')
+is_case_sensitive = test.read('filecase/FiLe.c') != test.read('filecase/fIlE.c')
+if is_case_sensitive:
+ test.run_gyp('test-casesensitive.gyp', chdir=CHDIR)
+ test.build('test-casesensitive.gyp', test.ALL, chdir=CHDIR)
+
+test.pass_test()