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

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

Issue 1066963002: Improve generated Makefile rules for rules with 2 outputs. (Closed) Base URL: https://chromium.googlesource.com/external/gyp.git@master
Patch Set: no changes Created 5 years, 8 months 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 | test/actions-multiple-outputs/gyptest-multiple-outputs.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pylib/gyp/generator/make.py
diff --git a/pylib/gyp/generator/make.py b/pylib/gyp/generator/make.py
index 64b2511f085cffd6aa3df3d7c2bc82a88a0f912f..16462be79d0674fe2178c6c3c8d0729c79262ab3 100644
--- a/pylib/gyp/generator/make.py
+++ b/pylib/gyp/generator/make.py
@@ -1019,7 +1019,8 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
# accidentally writing duplicate dummy rules for those outputs.
self.WriteLn('%s: obj := $(abs_obj)' % outputs[0])
self.WriteLn('%s: builddir := $(abs_builddir)' % outputs[0])
- self.WriteMakeRule(outputs, inputs + ['FORCE_DO_CMD'], actions)
+ self.WriteMakeRule(outputs, inputs, actions,
+ command="%s_%d" % (name, count))
# Spaces in rule filenames are not supported, but rule variables have
# spaces in them (e.g. RULE_INPUT_PATH expands to '$(abspath $<)').
# The spaces within the variables are valid, so remove the variables
@@ -1688,6 +1689,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
self.WriteMakeRule(outputs, inputs,
actions = ['$(call do_cmd,%s%s)' % (command, suffix)],
comment = comment,
+ command = command,
force = True)
# Add our outputs to the list of targets we read depfiles from.
# all_deps is only used for deps file reading, and for deps files we replace
@@ -1698,7 +1700,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
def WriteMakeRule(self, outputs, inputs, actions=None, comment=None,
- order_only=False, force=False, phony=False):
+ order_only=False, force=False, phony=False, command=None):
"""Write a Makefile rule, with some extra tricks.
outputs: a list of outputs for the rule (note: this is not directly
@@ -1711,6 +1713,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
force: if true, include FORCE_DO_CMD as an order-only dep
phony: if true, the rule does not actually generate the named output, the
output is just a name to run the rule
+ command: (optional) command name to generate unambiguous labels
"""
outputs = map(QuoteSpaces, outputs)
inputs = map(QuoteSpaces, inputs)
@@ -1719,44 +1722,38 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD
self.WriteLn('# ' + comment)
if phony:
self.WriteLn('.PHONY: ' + ' '.join(outputs))
- # TODO(evanm): just make order_only a list of deps instead of these hacks.
- if order_only:
- order_insert = '| '
- pick_output = ' '.join(outputs)
- else:
- order_insert = ''
- pick_output = outputs[0]
- if force:
- force_append = ' FORCE_DO_CMD'
- else:
- force_append = ''
if actions:
self.WriteLn("%s: TOOLSET := $(TOOLSET)" % outputs[0])
- self.WriteLn('%s: %s%s%s' % (pick_output, order_insert, ' '.join(inputs),
- force_append))
+ force_append = ' FORCE_DO_CMD' if force else ''
+
+ if order_only:
+ # Order only rule: Just write a simple rule.
+ # TODO(evanm): just make order_only a list of deps instead of this hack.
+ self.WriteLn('%s: | %s%s' %
+ (' '.join(outputs), ' '.join(inputs), force_append))
+ elif len(outputs) == 1:
+ # Regular rule, one output: Just write a simple rule.
+ self.WriteLn('%s: %s%s' % (outputs[0], ' '.join(inputs), force_append))
+ else:
+ # Regular rule, more than one output: Multiple outputs are tricky in
+ # make. We will write three rules:
+ # - All outputs depend on an intermediate file.
+ # - Make .INTERMEDIATE depend on the intermediate.
+ # - The intermediate file depends on the inputs and executes the
+ # actual command.
+ #
+ # For an explanation of the problem and several solutions that don't
+ # work, see this:
+ # http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html
+ intermediate = "%s.intermediate" % (command if command else self.target)
+ self.WriteLn('%s: %s' % (' '.join(outputs), intermediate))
+ self.WriteLn('%s: %s' % ('.INTERMEDIATE', intermediate))
+ self.WriteLn('%s: %s%s' %
+ (intermediate, ' '.join(inputs), force_append))
+
if actions:
for action in actions:
self.WriteLn('\t%s' % action)
- if not order_only and len(outputs) > 1:
- # If we have more than one output, a rule like
- # foo bar: baz
- # that for *each* output we must run the action, potentially
- # in parallel. That is not what we're trying to write -- what
- # we want is that we run the action once and it generates all
- # the files.
- # http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html
- # discusses this problem and has this solution:
- # 1) Write the naive rule that would produce parallel runs of
- # the action.
- # 2) Make the outputs seralized on each other, so we won't start
- # a parallel run until the first run finishes, at which point
- # we'll have generated all the outputs and we're done.
- self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0]))
- # Add a dummy command to the "extra outputs" rule, otherwise make seems to
- # think these outputs haven't (couldn't have?) changed, and thus doesn't
- # flag them as changed (i.e. include in '$?') when evaluating dependent
- # rules, which in turn causes do_cmd() to skip running dependent commands.
- self.WriteLn('%s: ;' % (' '.join(outputs[1:])))
self.WriteLn()
« no previous file with comments | « no previous file | test/actions-multiple-outputs/gyptest-multiple-outputs.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698