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 |