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

Side by Side 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: only update sources if process_outputs_as_sources 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/chained-rules/action.input » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import copy 5 import copy
6 import gyp 6 import gyp
7 import gyp.common 7 import gyp.common
8 import gyp.msvs_emulation 8 import gyp.msvs_emulation
9 import gyp.MSVSVersion 9 import gyp.MSVSVersion
10 import gyp.system_test 10 import gyp.system_test
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 297
298 assert targets == filter(None, targets), targets 298 assert targets == filter(None, targets), targets
299 if len(targets) == 0: 299 if len(targets) == 0:
300 return None 300 return None
301 if len(targets) > 1: 301 if len(targets) > 1:
302 stamp = self.GypPathToUniqueOutput(name + '.stamp') 302 stamp = self.GypPathToUniqueOutput(name + '.stamp')
303 targets = self.ninja.build(stamp, 'stamp', targets) 303 targets = self.ninja.build(stamp, 'stamp', targets)
304 self.ninja.newline() 304 self.ninja.newline()
305 return targets[0] 305 return targets[0]
306 306
307 def _SourcesHandledByRule(self, rule, sources):
308 """Get a list of files that from |sources| that |rule| handles."""
309 rule_ext = rule['extension']
310 result = []
311 for s in sources:
Evan Martin 2012/05/18 17:19:06 s/s/source/
scottmg 2012/05/18 18:06:30 Done.
312 if s.endswith('.' + rule_ext):
313 inputs, outputs = self._GetInputsAndOutputsForRule(rule, s)
314 if s in outputs:
315 # Don't the outputs of this rule with this rule, even if by
Evan Martin 2012/05/18 17:19:06 This comment accidentally a word.
scottmg 2012/05/18 18:06:30 Done.
316 # extension we ought to.
317 continue
318 result.append(s)
319 return result
320
321 def _GetInputsAndOutputsForRule(self, rule, source):
322 """Get the expanded inputs and outputs of the given |rule| for a
323 particular |source|."""
324 dirname, basename = os.path.split(source)
325 root, ext = os.path.splitext(basename)
326 outputs = [self.ExpandRuleVariables(o, root, dirname,
327 source, ext, basename)
328 for o in rule['outputs']]
329 inputs = [self.ExpandRuleVariables(i, root, dirname,
330 source, ext, basename)
331 for i in rule.get('inputs', [])]
332 return inputs, outputs
333
334 def _GetSources(self, spec):
335 """Get all sources for the given |spec|. In addition to the sources
336 directly specified in the gyp file, it includes sources generated by
337 actions and copies. Outputs of rules are not included because otherwise
338 rules that generate the same extension as they process cause much
339 confusion. Rule outputs are added when the rule is processed."""
340 sources = spec.get('sources', [])
341 for action in spec.get('actions', []):
342 #sources.extend(action['inputs'])
Evan Martin 2012/05/18 17:19:06 Probably should delete dead code
scottmg 2012/05/18 18:06:30 Done.
343 if int(action.get('process_outputs_as_sources', False)):
344 sources.extend(action.get('outputs', []))
345 for copy in spec.get('copies', []):
346 sources.extend(copy.get('files', []))
347 return set(sources)
348
349
307 def WriteSpec(self, spec, config_name, generator_flags): 350 def WriteSpec(self, spec, config_name, generator_flags):
308 """The main entry point for NinjaWriter: write the build rules for a spec. 351 """The main entry point for NinjaWriter: write the build rules for a spec.
309 352
310 Returns a Target object, which represents the output paths for this spec. 353 Returns a Target object, which represents the output paths for this spec.
311 Returns None if there are no outputs (e.g. a settings-only 'none' type 354 Returns None if there are no outputs (e.g. a settings-only 'none' type
312 target).""" 355 target)."""
313 356
314 self.config_name = config_name 357 self.config_name = config_name
315 self.name = spec['target_name'] 358 self.name = spec['target_name']
316 self.toolset = spec['toolset'] 359 self.toolset = spec['toolset']
(...skipping 25 matching lines...) Expand all
342 compile_depends.append(target.PreCompileInput()) 385 compile_depends.append(target.PreCompileInput())
343 actions_depends = filter(None, actions_depends) 386 actions_depends = filter(None, actions_depends)
344 compile_depends = filter(None, compile_depends) 387 compile_depends = filter(None, compile_depends)
345 actions_depends = self.WriteCollapsedDependencies('actions_depends', 388 actions_depends = self.WriteCollapsedDependencies('actions_depends',
346 actions_depends) 389 actions_depends)
347 compile_depends = self.WriteCollapsedDependencies('compile_depends', 390 compile_depends = self.WriteCollapsedDependencies('compile_depends',
348 compile_depends) 391 compile_depends)
349 self.target.preaction_stamp = actions_depends 392 self.target.preaction_stamp = actions_depends
350 self.target.precompile_stamp = compile_depends 393 self.target.precompile_stamp = compile_depends
351 394
395 # Build a list of sources. We do this as a pre-process so that we have
396 # access to generated outputs for actions for other actions and rules.
397 sources = self._GetSources(spec)
398
352 # Write out actions, rules, and copies. These must happen before we 399 # Write out actions, rules, and copies. These must happen before we
353 # compile any sources, so compute a list of predependencies for sources 400 # compile any sources, so compute a list of predependencies for sources
354 # while we do it. 401 # while we do it.
355 extra_sources = []
356 mac_bundle_depends = [] 402 mac_bundle_depends = []
357 self.target.actions_stamp = self.WriteActionsRulesCopies( 403 self.target.actions_stamp = self.WriteActionsRulesCopies(
358 spec, extra_sources, actions_depends, mac_bundle_depends) 404 spec, sources, actions_depends, mac_bundle_depends)
359 405
360 # If we have actions/rules/copies, we depend directly on those, but 406 # If we have actions/rules/copies, we depend directly on those, but
361 # otherwise we depend on dependent target's actions/rules/copies etc. 407 # otherwise we depend on dependent target's actions/rules/copies etc.
362 # We never need to explicitly depend on previous target's link steps, 408 # We never need to explicitly depend on previous target's link steps,
363 # because no compile ever depends on them. 409 # because no compile ever depends on them.
364 compile_depends_stamp = (self.target.actions_stamp or compile_depends) 410 compile_depends_stamp = (self.target.actions_stamp or compile_depends)
365 411
366 # Write out the compilation steps, if any. 412 # Write out the compilation steps, if any.
367 link_deps = [] 413 link_deps = []
368 sources = spec.get('sources', []) + extra_sources
369 if sources: 414 if sources:
370 link_deps = self.WriteSources( 415 link_deps = self.WriteSources(
371 config_name, config, sources, compile_depends_stamp, 416 config_name, config, sources, compile_depends_stamp,
372 gyp.xcode_emulation.MacPrefixHeader( 417 gyp.xcode_emulation.MacPrefixHeader(
373 self.xcode_settings, self.GypPathToNinja, 418 self.xcode_settings, self.GypPathToNinja,
374 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) 419 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang)))
375 # Some actions/rules output 'sources' that are already object files. 420 # Some actions/rules output 'sources' that are already object files.
376 link_deps += [self.GypPathToNinja(f) 421 link_deps += [self.GypPathToNinja(f)
377 for f in sources if f.endswith(self.obj_ext)] 422 for f in sources if f.endswith(self.obj_ext)]
378 423
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 def WriteWinIdlFiles(self, spec, prebuild): 475 def WriteWinIdlFiles(self, spec, prebuild):
431 """Writes rules to match MSVS's implicit idl handling.""" 476 """Writes rules to match MSVS's implicit idl handling."""
432 assert self.flavor == 'win' 477 assert self.flavor == 'win'
433 if self.msvs_settings.HasExplicitIdlRules(spec): 478 if self.msvs_settings.HasExplicitIdlRules(spec):
434 return [] 479 return []
435 outputs = [] 480 outputs = []
436 for source in filter(lambda x: x.endswith('.idl'), spec['sources']): 481 for source in filter(lambda x: x.endswith('.idl'), spec['sources']):
437 self._WinIdlRule(source, prebuild, outputs) 482 self._WinIdlRule(source, prebuild, outputs)
438 return outputs 483 return outputs
439 484
440 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild, 485 def WriteActionsRulesCopies(self, spec, sources, prebuild,
441 mac_bundle_depends): 486 mac_bundle_depends):
442 """Write out the Actions, Rules, and Copies steps. Return a path 487 """Write out the Actions, Rules, and Copies steps. Return a path
443 representing the outputs of these steps.""" 488 representing the outputs of these steps."""
444 outputs = [] 489 outputs = []
445 extra_mac_bundle_resources = [] 490 extra_mac_bundle_resources = []
446 491
447 if 'actions' in spec: 492 if 'actions' in spec:
448 outputs += self.WriteActions(spec['actions'], extra_sources, prebuild, 493 outputs += self.WriteActions(spec['actions'], sources, prebuild,
449 extra_mac_bundle_resources) 494 extra_mac_bundle_resources)
450 if 'rules' in spec: 495 if 'rules' in spec:
451 outputs += self.WriteRules(spec['rules'], extra_sources, prebuild, 496 outputs += self.WriteRules(spec['rules'], sources, prebuild,
452 extra_mac_bundle_resources) 497 extra_mac_bundle_resources)
453 if 'copies' in spec: 498 if 'copies' in spec:
454 outputs += self.WriteCopies(spec['copies'], prebuild) 499 outputs += self.WriteCopies(spec['copies'], prebuild)
455 500
456 if 'sources' in spec and self.flavor == 'win': 501 if 'sources' in spec and self.flavor == 'win':
457 outputs += self.WriteWinIdlFiles(spec, prebuild) 502 outputs += self.WriteWinIdlFiles(spec, prebuild)
458 503
459 stamp = self.WriteCollapsedDependencies('actions_rules_copies', outputs) 504 stamp = self.WriteCollapsedDependencies('actions_rules_copies', outputs)
460 505
461 if self.is_mac_bundle: 506 if self.is_mac_bundle:
(...skipping 11 matching lines...) Expand all
473 |message| is a hand-written description, or None if not available. 518 |message| is a hand-written description, or None if not available.
474 |fallback| is the gyp-level name of the step, usable as a fallback. 519 |fallback| is the gyp-level name of the step, usable as a fallback.
475 """ 520 """
476 if self.toolset != 'target': 521 if self.toolset != 'target':
477 verb += '(%s)' % self.toolset 522 verb += '(%s)' % self.toolset
478 if message: 523 if message:
479 return '%s %s' % (verb, self.ExpandSpecial(message)) 524 return '%s %s' % (verb, self.ExpandSpecial(message))
480 else: 525 else:
481 return '%s %s: %s' % (verb, self.name, fallback) 526 return '%s %s: %s' % (verb, self.name, fallback)
482 527
483 def WriteActions(self, actions, extra_sources, prebuild, 528 def WriteActions(self, actions, sources, prebuild,
484 extra_mac_bundle_resources): 529 extra_mac_bundle_resources):
485 # Actions cd into the base directory. 530 # Actions cd into the base directory.
486 env = self.GetXcodeEnv() 531 env = self.GetXcodeEnv()
487 if self.flavor == 'win': 532 if self.flavor == 'win':
488 env = self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR') 533 env = self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR')
489 all_outputs = [] 534 all_outputs = []
490 for action in actions: 535 for action in actions:
491 # First write out a rule for the action. 536 # First write out a rule for the action.
492 name = re.sub(r'[ {}$]', '_', action['action_name']) 537 name = re.sub(r'[ {}$]', '_', action['action_name'])
493 description = self.GenerateDescription('ACTION', 538 description = self.GenerateDescription('ACTION',
494 action.get('message', None), 539 action.get('message', None),
495 name) 540 name)
496 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action) 541 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action)
497 if self.flavor == 'win' else False) 542 if self.flavor == 'win' else False)
498 args = action['action'] 543 args = action['action']
499 args = [self.msvs_settings.ConvertVSMacros(arg, self.base_to_build) 544 args = [self.msvs_settings.ConvertVSMacros(arg, self.base_to_build)
500 for arg in args] if self.flavor == 'win' else args 545 for arg in args] if self.flavor == 'win' else args
501 rule_name = self.WriteNewNinjaRule(name, args, description, 546 rule_name = self.WriteNewNinjaRule(name, args, description,
502 is_cygwin, env=env) 547 is_cygwin, env=env)
503 548
504 inputs = [self.GypPathToNinja(i, env) for i in action['inputs']] 549 inputs = [self.GypPathToNinja(i, env) for i in action['inputs']]
505 if int(action.get('process_outputs_as_sources', False)):
506 extra_sources += action['outputs']
507 if int(action.get('process_outputs_as_mac_bundle_resources', False)): 550 if int(action.get('process_outputs_as_mac_bundle_resources', False)):
508 extra_mac_bundle_resources += action['outputs'] 551 extra_mac_bundle_resources += action['outputs']
509 outputs = [self.GypPathToNinja(o, env) for o in action['outputs']] 552 outputs = [self.GypPathToNinja(o, env) for o in action['outputs']]
510 553
511 # Then write out an edge using the rule. 554 # Then write out an edge using the rule.
512 self.ninja.build(outputs, rule_name, inputs, 555 self.ninja.build(outputs, rule_name, inputs,
513 order_only=prebuild) 556 order_only=prebuild)
514 all_outputs += outputs 557 all_outputs += outputs
515 558
516 self.ninja.newline() 559 self.ninja.newline()
517 560
518 return all_outputs 561 return all_outputs
519 562
520 def WriteRules(self, rules, extra_sources, prebuild, 563 def WriteRules(self, rules, sources, prebuild, extra_mac_bundle_resources):
521 extra_mac_bundle_resources):
Evan Martin 2012/05/18 17:19:06 It's so pleasing to see this param go, it always f
522 all_outputs = [] 564 all_outputs = []
523 for rule in rules: 565 for rule in rules:
524 # First write out a rule for the rule action. 566 # First write out a rule for the rule action.
525 name = rule['rule_name'] 567 name = rule['rule_name']
526 args = rule['action'] 568 args = rule['action']
527 description = self.GenerateDescription( 569 description = self.GenerateDescription(
528 'RULE', 570 'RULE',
529 rule.get('message', None), 571 rule.get('message', None),
530 ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name) 572 ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
531 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule) 573 is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule)
(...skipping 13 matching lines...) Expand all
545 for argument in args: 587 for argument in args:
546 for var in special_locals: 588 for var in special_locals:
547 if ('${%s}' % var) in argument: 589 if ('${%s}' % var) in argument:
548 needed_variables.add(var) 590 needed_variables.add(var)
549 591
550 def cygwin_munge(path): 592 def cygwin_munge(path):
551 if is_cygwin: 593 if is_cygwin:
552 return path.replace('\\', '/') 594 return path.replace('\\', '/')
553 return path 595 return path
554 596
597 rule_sources = self._SourcesHandledByRule(rule, sources)
555 # For each source file, write an edge that generates all the outputs. 598 # For each source file, write an edge that generates all the outputs.
556 for source in rule.get('rule_sources', []): 599 for source in rule_sources:
557 dirname, basename = os.path.split(source) 600 dirname, basename = os.path.split(source)
558 root, ext = os.path.splitext(basename) 601 root, ext = os.path.splitext(basename)
559 602 inputs, outputs = self._GetInputsAndOutputsForRule(rule, source)
560 # Gather the list of inputs and outputs, expanding $vars if possible.
561 outputs = [self.ExpandRuleVariables(o, root, dirname,
562 source, ext, basename)
563 for o in rule['outputs']]
564 inputs = [self.ExpandRuleVariables(i, root, dirname,
565 source, ext, basename)
566 for i in rule.get('inputs', [])]
567 603
568 if int(rule.get('process_outputs_as_sources', False)): 604 if int(rule.get('process_outputs_as_sources', False)):
569 extra_sources += outputs 605 sources.update(outputs)
570 if int(rule.get('process_outputs_as_mac_bundle_resources', False)): 606 if int(rule.get('process_outputs_as_mac_bundle_resources', False)):
571 extra_mac_bundle_resources += outputs 607 extra_mac_bundle_resources += outputs
572 608
573 extra_bindings = [] 609 extra_bindings = []
574 for var in needed_variables: 610 for var in needed_variables:
575 if var == 'root': 611 if var == 'root':
576 extra_bindings.append(('root', cygwin_munge(root))) 612 extra_bindings.append(('root', cygwin_munge(root)))
577 elif var == 'dirname': 613 elif var == 'dirname':
578 extra_bindings.append(('dirname', cygwin_munge(dirname))) 614 extra_bindings.append(('dirname', cygwin_munge(dirname)))
579 elif var == 'source': 615 elif var == 'source':
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 1523
1488 user_config = params.get('generator_flags', {}).get('config', None) 1524 user_config = params.get('generator_flags', {}).get('config', None)
1489 if user_config: 1525 if user_config:
1490 GenerateOutputForConfig(target_list, target_dicts, data, params, 1526 GenerateOutputForConfig(target_list, target_dicts, data, params,
1491 user_config) 1527 user_config)
1492 else: 1528 else:
1493 config_names = target_dicts[target_list[0]]['configurations'].keys() 1529 config_names = target_dicts[target_list[0]]['configurations'].keys()
1494 for config_name in config_names: 1530 for config_name in config_names:
1495 GenerateOutputForConfig(target_list, target_dicts, data, params, 1531 GenerateOutputForConfig(target_list, target_dicts, data, params,
1496 config_name) 1532 config_name)
OLDNEW
« 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