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

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

Issue 10381103: ninja: rules chained only by output of first one failing Base URL: https://gyp.googlecode.com/svn/trunk
Patch Set: exclude make Created 8 years, 7 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/chained-rules/action.input » ('j') | no next file with comments »
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 19dcc1bb7fe788a0323c5de4946ee84350b21e59..c069ee66d4f0f17a1f59865d77acdb9b4586f423 100644
--- a/pylib/gyp/generator/ninja.py
+++ b/pylib/gyp/generator/ninja.py
@@ -314,6 +314,48 @@ class NinjaWriter:
self.ninja.newline()
return targets[0]
+ def _SourcesHandledByRule(self, rule, sources):
+ """Get a list of files that from |sources| that |rule| handles."""
+ rule_ext = rule['extension']
+ result = []
+ for source in sources:
+ if source.endswith('.' + rule_ext):
+ inputs, outputs = self._GetInputsAndOutputsForRule(rule, source)
+ if source in outputs:
+ # Don't include the outputs of this rule, even if by extension we
+ # ought to.
+ continue
+ result.append(source)
+ return result
+
+ def _GetInputsAndOutputsForRule(self, rule, source):
+ """Get the expanded inputs and outputs of the given |rule| for a
+ particular |source|."""
+ dirname, basename = os.path.split(source)
+ root, ext = os.path.splitext(basename)
+ outputs = [self.ExpandRuleVariables(o, root, dirname,
+ source, ext, basename)
+ for o in rule['outputs']]
+ inputs = [self.ExpandRuleVariables(i, root, dirname,
+ source, ext, basename)
+ for i in rule.get('inputs', [])]
+ return inputs, outputs
+
+ def _GetSources(self, spec):
+ """Get all sources for the given |spec|. In addition to the sources
+ directly specified in the gyp file, it includes sources generated by
+ actions and copies. Outputs of rules are not included because otherwise
+ rules that generate the same extension as they process cause much
+ confusion. Rule outputs are added when the rule is processed."""
+ sources = spec.get('sources', [])
+ for action in spec.get('actions', []):
+ if int(action.get('process_outputs_as_sources', False)):
+ sources.extend(action.get('outputs', []))
+ for copy in spec.get('copies', []):
+ sources.extend(copy.get('files', []))
+ return set(sources)
+
+
def WriteSpec(self, spec, config_name, generator_flags):
"""The main entry point for NinjaWriter: write the build rules for a spec.
@@ -359,13 +401,16 @@ class NinjaWriter:
self.target.preaction_stamp = actions_depends
self.target.precompile_stamp = compile_depends
+ # Build a list of sources. We do this as a pre-process so that we have
+ # access to generated outputs for actions for other actions and rules.
+ sources = self._GetSources(spec)
+
# Write out actions, rules, and copies. These must happen before we
# compile any sources, so compute a list of predependencies for sources
# while we do it.
- extra_sources = []
mac_bundle_depends = []
self.target.actions_stamp = self.WriteActionsRulesCopies(
- spec, extra_sources, actions_depends, mac_bundle_depends)
+ spec, sources, actions_depends, mac_bundle_depends)
# If we have actions/rules/copies, we depend directly on those, but
# otherwise we depend on dependent target's actions/rules/copies etc.
@@ -375,7 +420,6 @@ class NinjaWriter:
# Write out the compilation steps, if any.
link_deps = []
- sources = spec.get('sources', []) + extra_sources
if sources:
link_deps = self.WriteSources(
config_name, config, sources, compile_depends_stamp,
@@ -447,7 +491,7 @@ class NinjaWriter:
self._WinIdlRule(source, prebuild, outputs)
return outputs
- def WriteActionsRulesCopies(self, spec, extra_sources, prebuild,
+ def WriteActionsRulesCopies(self, spec, sources, prebuild,
mac_bundle_depends):
"""Write out the Actions, Rules, and Copies steps. Return a path
representing the outputs of these steps."""
@@ -455,10 +499,10 @@ class NinjaWriter:
extra_mac_bundle_resources = []
if 'actions' in spec:
- outputs += self.WriteActions(spec['actions'], extra_sources, prebuild,
+ outputs += self.WriteActions(spec['actions'], sources, prebuild,
extra_mac_bundle_resources)
if 'rules' in spec:
- outputs += self.WriteRules(spec['rules'], extra_sources, prebuild,
+ outputs += self.WriteRules(spec['rules'], sources, prebuild,
extra_mac_bundle_resources)
if 'copies' in spec:
outputs += self.WriteCopies(spec['copies'], prebuild)
@@ -490,7 +534,7 @@ class NinjaWriter:
else:
return '%s %s: %s' % (verb, self.name, fallback)
- def WriteActions(self, actions, extra_sources, prebuild,
+ def WriteActions(self, actions, sources, prebuild,
extra_mac_bundle_resources):
# Actions cd into the base directory.
env = self.GetXcodeEnv()
@@ -512,8 +556,6 @@ class NinjaWriter:
is_cygwin, env=env)
inputs = [self.GypPathToNinja(i, env) for i in action['inputs']]
- if int(action.get('process_outputs_as_sources', False)):
- extra_sources += action['outputs']
if int(action.get('process_outputs_as_mac_bundle_resources', False)):
extra_mac_bundle_resources += action['outputs']
outputs = [self.GypPathToNinja(o, env) for o in action['outputs']]
@@ -527,8 +569,7 @@ class NinjaWriter:
return all_outputs
- def WriteRules(self, rules, extra_sources, prebuild,
- extra_mac_bundle_resources):
+ def WriteRules(self, rules, sources, prebuild, extra_mac_bundle_resources):
all_outputs = []
for rule in rules:
# First write out a rule for the rule action.
@@ -562,21 +603,15 @@ class NinjaWriter:
return path.replace('\\', '/')
return path
+ rule_sources = self._SourcesHandledByRule(rule, sources)
# For each source file, write an edge that generates all the outputs.
- for source in rule.get('rule_sources', []):
+ for source in rule_sources:
dirname, basename = os.path.split(source)
root, ext = os.path.splitext(basename)
-
- # Gather the list of inputs and outputs, expanding $vars if possible.
- outputs = [self.ExpandRuleVariables(o, root, dirname,
- source, ext, basename)
- for o in rule['outputs']]
- inputs = [self.ExpandRuleVariables(i, root, dirname,
- source, ext, basename)
- for i in rule.get('inputs', [])]
+ inputs, outputs = self._GetInputsAndOutputsForRule(rule, source)
if int(rule.get('process_outputs_as_sources', False)):
- extra_sources += outputs
+ sources.update(outputs)
if int(rule.get('process_outputs_as_mac_bundle_resources', False)):
extra_mac_bundle_resources += outputs
« no previous file with comments | « no previous file | test/chained-rules/action.input » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698