Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1003)

Unified Diff: pylib/gyp/generator/ninja.py

Issue 1506733002: GYP: Make GYP build deterministic (Closed) Base URL: https://chromium.googlesource.com/external/gyp.git@master
Patch Set: Clearer naming, better understanding Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pylib/gyp/input.py » ('j') | pylib/gyp/input.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pylib/gyp/generator/ninja.py
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py
index b13affe0a172392ae115201874d5f44223b38c38..95aca57d3bdd188291a1f01bd9af3e48f09a4ad8 100644
--- a/pylib/gyp/generator/ninja.py
+++ b/pylib/gyp/generator/ninja.py
@@ -69,6 +69,9 @@ def StripPrefix(arg, prefix):
return arg[len(prefix):]
return arg
+def OrderDeterministically(l, **kwargs):
+ """ Sorts l so that it is ordered deterministically. """
+ return sorted(l, **kwargs)
mithro-old 2015/12/10 03:15:27 I think this should be in gyp.common with OrderedS
Zachary Forman 2015/12/30 02:18:43 Yeah, you caught me mid refactor. Good spot for it
def QuoteShellArgument(arg, flavor):
"""Quote a string such that it will be interpreted as a single argument
@@ -421,10 +424,10 @@ class NinjaWriter(object):
compile_depends.append(target.PreCompileInput())
actions_depends = filter(None, actions_depends)
compile_depends = filter(None, compile_depends)
- actions_depends = self.WriteCollapsedDependencies('actions_depends',
- actions_depends)
- compile_depends = self.WriteCollapsedDependencies('compile_depends',
- compile_depends)
+ actions_depends = self.WriteCollapsedDependencies(
+ 'actions_depends', OrderDeterministically(actions_depends))
+ compile_depends = self.WriteCollapsedDependencies(
+ 'compile_depends', OrderDeterministically(compile_depends))
self.target.preaction_stamp = actions_depends
self.target.precompile_stamp = compile_depends
@@ -559,7 +562,8 @@ class NinjaWriter(object):
if 'sources' in spec and self.flavor == 'win':
outputs += self.WriteWinIdlFiles(spec, prebuild)
- stamp = self.WriteCollapsedDependencies('actions_rules_copies', outputs)
+ stamp = self.WriteCollapsedDependencies('actions_rules_copies',
+ OrderDeterministically(outputs))
if self.is_mac_bundle:
xcassets = self.WriteMacBundleResources(
@@ -657,6 +661,8 @@ class NinjaWriter(object):
if '${%s}' % var in argument:
needed_variables.add(var)
+ needed_variables = OrderDeterministically(needed_variables)
+
def cygwin_munge(path):
# pylint: disable=cell-var-from-loop
if is_cygwin:
@@ -674,7 +680,7 @@ class NinjaWriter(object):
num_inputs += 1
if num_inputs > 2 and len(sources) > 2:
inputs = [self.WriteCollapsedDependencies(
- rule['rule_name'], inputs, order_only=prebuild)]
+ rule['rule_name'], OrderDeterministically(inputs), order_only=prebuild)]
prebuild = []
# For each source file, write an edge that generates all the outputs.
@@ -729,6 +735,8 @@ 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,
@@ -1134,6 +1142,8 @@ class NinjaWriter(object):
if not linkable or final_output != target.binary:
implicit_deps.add(final_output)
+ link_deps = OrderDeterministically(link_deps)
+
extra_bindings = []
if self.uses_cpp and self.flavor != 'win':
extra_bindings.append(('ld', '$ldxx'))
@@ -1250,13 +1260,13 @@ class NinjaWriter(object):
if pdbname:
output = [output, pdbname]
-
if len(solibs):
- extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs)))
+ extra_bindings.append(('solibs',
+ gyp.common.EncodePOSIXShellList(OrderDeterministically(solibs))))
ninja_file.build(output, command + command_suffix, link_deps,
- implicit=list(implicit_deps),
- order_only=list(order_deps),
+ implicit=OrderDeterministically(implicit_deps),
+ order_only=order_deps,
variables=extra_bindings)
return linked_binary
@@ -2337,9 +2347,10 @@ 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:
- master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in
- target_short_names[short_name]])
+
+ for short_name in OrderDeterministically(target_short_names):
+ master_ninja.build(short_name, 'phony', ([x.FinalOutput() for x in
+ target_short_names[short_name]]))
# Write phony targets for any empty targets that weren't written yet. As
# short names are not necessarily unique only do this for short names that
@@ -2348,12 +2359,14 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params,
if empty_target_names:
master_ninja.newline()
master_ninja.comment('Empty targets (output for completeness).')
- for name in sorted(empty_target_names):
+
+ # Iterate over empty target names in a deterministic order by sorting.
+ for name in OrderDeterministically(empty_target_names):
master_ninja.build(name, 'phony')
if all_outputs:
master_ninja.newline()
- master_ninja.build('all', 'phony', list(all_outputs))
+ master_ninja.build('all', 'phony', OrderDeterministically(all_outputs))
master_ninja.default(generator_flags.get('default_target', 'all'))
master_ninja_file.close()
« no previous file with comments | « no previous file | pylib/gyp/input.py » ('j') | pylib/gyp/input.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698