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

Side by Side Diff: pylib/gyp/generator/ninja.py

Issue 8400082: Ninja: separate dependencies for compile steps vs actions/rules/copies (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2011 Google Inc. All rights reserved. 3 # Copyright (c) 2011 Google Inc. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 import gyp 7 import gyp
8 import gyp.common 8 import gyp.common
9 import gyp.system_test 9 import gyp.system_test
10 import os.path 10 import os.path
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 213
214 if len(targets) > 1: 214 if len(targets) > 1:
215 stamp = self.GypPathToUniqueOutput(name + '.stamp') 215 stamp = self.GypPathToUniqueOutput(name + '.stamp')
216 targets = self.ninja.build(stamp, 'stamp', targets) 216 targets = self.ninja.build(stamp, 'stamp', targets)
217 self.ninja.newline() 217 self.ninja.newline()
218 return targets 218 return targets
219 219
220 def WriteSpec(self, spec, config): 220 def WriteSpec(self, spec, config):
221 """The main entry point for NinjaWriter: write the build rules for a spec. 221 """The main entry point for NinjaWriter: write the build rules for a spec.
222 222
223 Returns the path to the build output, or None.""" 223 Returns the path to the build output, or None, and a list of targets for
224 dependencies of its compile steps."""
224 225
225 self.name = spec['target_name'] 226 self.name = spec['target_name']
226 self.toolset = spec['toolset'] 227 self.toolset = spec['toolset']
227 228
228 if spec['type'] == 'settings': 229 if spec['type'] == 'settings':
229 # TODO: 'settings' is not actually part of gyp; it was 230 # TODO: 'settings' is not actually part of gyp; it was
230 # accidentally introduced somehow into just the Linux build files. 231 # accidentally introduced somehow into just the Linux build files.
231 # Remove this (or make it an error) once all the users are fixed. 232 # Remove this (or make it an error) once all the users are fixed.
232 print ("WARNING: %s uses invalid type 'settings'. " % self.name + 233 print ("WARNING: %s uses invalid type 'settings'. " % self.name +
233 "Please fix the source gyp file to use type 'none'.") 234 "Please fix the source gyp file to use type 'none'.")
234 print "See http://code.google.com/p/chromium/issues/detail?id=96629 ." 235 print "See http://code.google.com/p/chromium/issues/detail?id=96629 ."
235 spec['type'] = 'none' 236 spec['type'] = 'none'
236 237
237 # Compute predepends for all rules. 238 # Compute predepends for all rules.
238 # prebuild is the dependencies this target depends on before 239 # actions_depends is the dependencies this target depends on before running
239 # running any of its internal steps. 240 # any of its action/rule/copy steps.
240 prebuild = [] 241 # compile_depends is the dependencies this target depends on before running
242 # any of its compile steps.
243 actions_depends = []
244 compile_depends = []
241 if 'dependencies' in spec: 245 if 'dependencies' in spec:
242 for dep in spec['dependencies']: 246 for dep in spec['dependencies']:
243 if dep in self.target_outputs: 247 if dep in self.target_outputs:
244 prebuild.append(self.target_outputs[dep][0]) 248 input, precompile_input, linkable = self.target_outputs[dep]
245 prebuild = self.WriteCollapsedDependencies('predepends', prebuild) 249 actions_depends.append(input)
250 compile_depends.extend(precompile_input)
251 actions_depends = self.WriteCollapsedDependencies('actions_depends',
252 actions_depends)
246 253
247 # Write out actions, rules, and copies. These must happen before we 254 # Write out actions, rules, and copies. These must happen before we
248 # compile any sources, so compute a list of predependencies for sources 255 # compile any sources, so compute a list of predependencies for sources
249 # while we do it. 256 # while we do it.
250 extra_sources = [] 257 extra_sources = []
251 sources_predepends = self.WriteActionsRulesCopies(spec, extra_sources, 258 sources_depends = self.WriteActionsRulesCopies(spec, extra_sources,
252 prebuild) 259 actions_depends)
260
261 # If we have actions/rules/copies, we depend directly on those, but
262 # otherwise we depend on dependent target's actions/rules/copies etc.
263 # We never need to explicitly depend on previous target's link steps,
264 # because no compile ever depends on them.
265 compile_depends = self.WriteCollapsedDependencies('compile_depends',
266 sources_depends or compile_depends)
253 267
254 # Write out the compilation steps, if any. 268 # Write out the compilation steps, if any.
255 link_deps = [] 269 link_deps = []
256 sources = spec.get('sources', []) + extra_sources 270 sources = spec.get('sources', []) + extra_sources
257 if sources: 271 if sources:
258 link_deps = self.WriteSources(config, sources, 272 link_deps = self.WriteSources(config, sources, compile_depends)
259 sources_predepends or prebuild)
260 # Some actions/rules output 'sources' that are already object files. 273 # Some actions/rules output 'sources' that are already object files.
261 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')] 274 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')]
262 275
263 # The final output of our target depends on the last output of the 276 # The final output of our target depends on the last output of the
264 # above steps. 277 # above steps.
265 output = None 278 output = None
266 final_deps = link_deps or sources_predepends or prebuild 279 final_deps = link_deps or sources_depends or actions_depends
267 if final_deps: 280 if final_deps:
268 output = self.WriteTarget(spec, config, final_deps) 281 output = self.WriteTarget(spec, config, final_deps)
269 if self.name != output and self.toolset == 'target': 282 if self.name != output and self.toolset == 'target':
270 # Write a short name to build this target. This benefits both the 283 # Write a short name to build this target. This benefits both the
271 # "build chrome" case as well as the gyp tests, which expect to be 284 # "build chrome" case as well as the gyp tests, which expect to be
272 # able to run actions and build libraries by their short name. 285 # able to run actions and build libraries by their short name.
273 self.ninja.build(self.name, 'phony', output) 286 self.ninja.build(self.name, 'phony', output)
274 return output 287 return output, compile_depends
275 288
276 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild): 289 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild):
277 """Write out the Actions, Rules, and Copies steps. Return any outputs 290 """Write out the Actions, Rules, and Copies steps. Return any outputs
278 of these steps (or a stamp file if there are lots of outputs).""" 291 of these steps (or a stamp file if there are lots of outputs)."""
279 outputs = [] 292 outputs = []
280 293
281 if 'actions' in spec: 294 if 'actions' in spec:
282 outputs += self.WriteActions(spec['actions'], extra_sources, prebuild) 295 outputs += self.WriteActions(spec['actions'], extra_sources, prebuild)
283 if 'rules' in spec: 296 if 'rules' in spec:
284 outputs += self.WriteRules(spec['rules'], extra_sources, prebuild) 297 outputs += self.WriteRules(spec['rules'], extra_sources, prebuild)
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 477
465 implicit_deps = set() 478 implicit_deps = set()
466 if 'dependencies' in spec: 479 if 'dependencies' in spec:
467 # Two kinds of dependencies: 480 # Two kinds of dependencies:
468 # - Linkable dependencies (like a .a or a .so): add them to the link line. 481 # - Linkable dependencies (like a .a or a .so): add them to the link line.
469 # - Non-linkable dependencies (like a rule that generates a file 482 # - Non-linkable dependencies (like a rule that generates a file
470 # and writes a stamp file): add them to implicit_deps 483 # and writes a stamp file): add them to implicit_deps
471 if output_uses_linker: 484 if output_uses_linker:
472 extra_deps = set() 485 extra_deps = set()
473 for dep in spec['dependencies']: 486 for dep in spec['dependencies']:
474 input, linkable = self.target_outputs.get(dep, (None, False)) 487 input, _, linkable = self.target_outputs.get( dep, (None, [], False))
tony 2011/11/03 23:55:30 Nit: extra space before |dep|?
piman 2011/11/04 03:51:52 Done.
475 if not input: 488 if not input:
476 continue 489 continue
477 if linkable: 490 if linkable:
478 extra_deps.add(input) 491 extra_deps.add(input)
479 else: 492 else:
480 # TODO: Chrome-specific HACK. Chrome runs this lastchange rule on 493 # TODO: Chrome-specific HACK. Chrome runs this lastchange rule on
481 # every build, but we don't want to rebuild when it runs. 494 # every build, but we don't want to rebuild when it runs.
482 if 'lastchange' not in input: 495 if 'lastchange' not in input:
483 implicit_deps.add(input) 496 implicit_deps.add(input)
484 final_deps.extend(list(extra_deps)) 497 final_deps.extend(list(extra_deps))
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 output_file = os.path.join(obj, base_path, name + '.ninja') 728 output_file = os.path.join(obj, base_path, name + '.ninja')
716 spec = target_dicts[qualified_target] 729 spec = target_dicts[qualified_target]
717 config = spec['configurations'][config_name] 730 config = spec['configurations'][config_name]
718 731
719 writer = NinjaWriter(target_outputs, base_path, builddir, 732 writer = NinjaWriter(target_outputs, base_path, builddir,
720 OpenOutput(os.path.join(options.toplevel_dir, 733 OpenOutput(os.path.join(options.toplevel_dir,
721 builddir, 734 builddir,
722 output_file))) 735 output_file)))
723 master_ninja.subninja(output_file) 736 master_ninja.subninja(output_file)
724 737
725 output = writer.WriteSpec(spec, config) 738 output, compile_depends = writer.WriteSpec(spec, config)
726 if output: 739 if output:
727 linkable = spec['type'] in ('static_library', 'shared_library') 740 linkable = spec['type'] in ('static_library', 'shared_library')
728 target_outputs[qualified_target] = (output, linkable) 741 target_outputs[qualified_target] = (output, compile_depends, linkable)
729 742
730 if qualified_target in all_targets: 743 if qualified_target in all_targets:
731 all_outputs.add(output) 744 all_outputs.add(output)
732 745
733 if all_outputs: 746 if all_outputs:
734 master_ninja.build('all', 'phony', list(all_outputs)) 747 master_ninja.build('all', 'phony', list(all_outputs))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698