Index: pylib/gyp/generator/ninja.py |
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py |
index b13affe0a172392ae115201874d5f44223b38c38..89668f544741836a4e23dcba7b4d4f98f93a1631 100644 |
--- a/pylib/gyp/generator/ninja.py |
+++ b/pylib/gyp/generator/ninja.py |
@@ -729,10 +729,12 @@ class NinjaWriter(object): |
# WriteNewNinjaRule uses unique_name for creating an rsp file on win. |
extra_bindings.append(('unique_name', |
hashlib.md5(outputs[0]).hexdigest())) |
+ |
+ # Make sure we sort extra_bindings so that output is deterministic. |
self.ninja.build(outputs, rule_name, self.GypPathToNinja(source), |
implicit=inputs, |
order_only=prebuild, |
- variables=extra_bindings) |
+ variables=sorted(extra_bindings)) |
all_outputs.extend(outputs) |
@@ -1250,14 +1252,16 @@ class NinjaWriter(object): |
if pdbname: |
output = [output, pdbname] |
- |
+ # Sort the solibs here so that they're outputted deterministically. |
if len(solibs): |
- extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs))) |
+ extra_bindings.append(('solibs', |
+ gyp.common.EncodePOSIXShellList(sorted(solibs)))) |
+ # Sort outputs so that they're deterministically ordered. |
ninja_file.build(output, command + command_suffix, link_deps, |
- implicit=list(implicit_deps), |
- order_only=list(order_deps), |
- variables=extra_bindings) |
+ implicit=sorted(implicit_deps), |
+ order_only=sorted(order_deps), |
+ variables=sorted(extra_bindings)) |
return linked_binary |
def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): |
@@ -2254,7 +2258,8 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
master_ninja.newline() |
all_targets = set() |
- for build_file in params['build_files']: |
+ # Iterate over build files deterministically so they're consistently ordered. |
+ for build_file in sorted(params['build_files']): |
for target in gyp.common.AllTargets(target_list, |
target_dicts, |
os.path.normpath(build_file)): |
@@ -2337,7 +2342,9 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
# able to run actions and build libraries by their short name. |
master_ninja.newline() |
master_ninja.comment('Short names for targets.') |
- for short_name in target_short_names: |
+ |
+ # Iterate over the target short names in a deterministic order by sorting. |
+ for short_name in sorted(target_short_names): |
master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in |
target_short_names[short_name]]) |
@@ -2348,6 +2355,8 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, |
if empty_target_names: |
master_ninja.newline() |
master_ninja.comment('Empty targets (output for completeness).') |
+ |
+ # Iterate over empty target names in a deterministic order by sorting. |
for name in sorted(empty_target_names): |
master_ninja.build(name, 'phony') |