OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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) |
OLD | NEW |