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 gyp | 5 import gyp |
6 import gyp.common | 6 import gyp.common |
7 import gyp.system_test | 7 import gyp.system_test |
8 import gyp.xcode_emulation | 8 import gyp.xcode_emulation |
9 import os.path | 9 import os.path |
10 import re | 10 import re |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 config_name, config, sources, compile_depends, | 272 config_name, config, sources, compile_depends, |
273 gyp.xcode_emulation.MacPrefixHeader( | 273 gyp.xcode_emulation.MacPrefixHeader( |
274 self.xcode_settings, self.GypPathToNinja, | 274 self.xcode_settings, self.GypPathToNinja, |
275 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) | 275 lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang))) |
276 # Some actions/rules output 'sources' that are already object files. | 276 # Some actions/rules output 'sources' that are already object files. |
277 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')] | 277 link_deps += [self.GypPathToNinja(f) for f in sources if f.endswith('.o')] |
278 | 278 |
279 # The final output of our target depends on the last output of the | 279 # The final output of our target depends on the last output of the |
280 # above steps. | 280 # above steps. |
281 output = output_binary = None | 281 output = output_binary = None |
282 final_deps = link_deps or sources_depends or actions_depends | 282 if link_deps or sources_depends or actions_depends: |
283 if final_deps: | |
284 output, output_binary = self.WriteTarget( | 283 output, output_binary = self.WriteTarget( |
285 spec, config_name, config, final_deps, mac_bundle_depends, | 284 spec, config_name, config, link_deps, |
285 sources_depends or actions_depends, mac_bundle_depends, | |
286 order_only=actions_depends) | 286 order_only=actions_depends) |
287 if self.name != output and self.toolset == 'target': | 287 if self.name != output and self.toolset == 'target': |
288 # Write a short name to build this target. This benefits both the | 288 # Write a short name to build this target. This benefits both the |
289 # "build chrome" case as well as the gyp tests, which expect to be | 289 # "build chrome" case as well as the gyp tests, which expect to be |
290 # able to run actions and build libraries by their short name. | 290 # able to run actions and build libraries by their short name. |
291 self.ninja.build(self.name, 'phony', output) | 291 self.ninja.build(self.name, 'phony', output) |
Evan Martin
2012/01/07 21:29:00
Hm, now I'm confused. Won't this write out this p
Nico
2012/01/07 21:32:33
Yes, that's the point of this change :-) output wi
| |
292 return output, output_binary, compile_depends | 292 return output, output_binary, compile_depends |
293 | 293 |
294 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild, | 294 def WriteActionsRulesCopies(self, spec, extra_sources, prebuild, |
295 mac_bundle_depends): | 295 mac_bundle_depends): |
296 """Write out the Actions, Rules, and Copies steps. Return any outputs | 296 """Write out the Actions, Rules, and Copies steps. Return any outputs |
297 of these steps (or a stamp file if there are lots of outputs).""" | 297 of these steps (or a stamp file if there are lots of outputs).""" |
298 outputs = [] | 298 outputs = [] |
299 extra_mac_bundle_resources = [] | 299 extra_mac_bundle_resources = [] |
300 | 300 |
301 if 'actions' in spec: | 301 if 'actions' in spec: |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 var_name = { | 565 var_name = { |
566 'c': 'cflags_pch_c', | 566 'c': 'cflags_pch_c', |
567 'cc': 'cflags_pch_cc', | 567 'cc': 'cflags_pch_cc', |
568 'm': 'cflags_pch_objc', | 568 'm': 'cflags_pch_objc', |
569 'mm': 'cflags_pch_objcc', | 569 'mm': 'cflags_pch_objcc', |
570 }[lang] | 570 }[lang] |
571 | 571 |
572 cmd = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }.get(lang) | 572 cmd = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', }.get(lang) |
573 self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)]) | 573 self.ninja.build(gch, cmd, input, variables=[(var_name, lang_flag)]) |
574 | 574 |
575 def WriteTarget(self, spec, config_name, config, final_deps, | 575 def WriteTarget(self, spec, config_name, config, link_deps, final_deps, |
576 mac_bundle_depends, order_only): | 576 mac_bundle_depends, order_only): |
577 if spec['type'] == 'none': | 577 if spec['type'] == 'none': |
578 # This target doesn't have any explicit final output, but is instead | 578 # This target doesn't have any explicit final output, but is instead |
579 # used for its effects before the final output (e.g. copies steps). | 579 # used for its effects before the final output (e.g. copies steps). |
580 # Reuse the existing output if it's easy. | 580 # Reuse the existing output if it's easy. |
581 if len(final_deps) == 1: | 581 if len(final_deps) == 1: |
582 return final_deps[0], final_deps[0] | 582 return final_deps[0], final_deps[0] |
583 # Otherwise, fall through to writing out a stamp file. | 583 # Otherwise, fall through to writing out a stamp file. |
584 | 584 |
585 if self.is_mac_bundle: | |
586 output = self.ComputeMacBundleOutput(spec) | |
587 output_binary = self.ComputeMacBundleBinaryOutput(spec) | |
588 mac_bundle_depends.append(output_binary) | |
589 else: | |
590 output = output_binary = self.ComputeOutput(spec) | |
591 | |
592 output_uses_linker = spec['type'] in ('executable', 'loadable_module', | 585 output_uses_linker = spec['type'] in ('executable', 'loadable_module', |
593 'shared_library') | 586 'shared_library') |
594 | 587 |
595 implicit_deps = set() | 588 implicit_deps = set() |
596 if 'dependencies' in spec: | 589 if 'dependencies' in spec: |
597 # Two kinds of dependencies: | 590 # Two kinds of dependencies: |
598 # - Linkable dependencies (like a .a or a .so): add them to the link line. | 591 # - Linkable dependencies (like a .a or a .so): add them to the link line. |
599 # - Non-linkable dependencies (like a rule that generates a file | 592 # - Non-linkable dependencies (like a rule that generates a file |
600 # and writes a stamp file): add them to implicit_deps | 593 # and writes a stamp file): add them to implicit_deps |
601 if output_uses_linker: | 594 if output_uses_linker: |
602 extra_deps = set() | 595 extra_deps = set() |
603 for dep in spec['dependencies']: | 596 for dep in spec['dependencies']: |
604 input, _, linkable = self.target_outputs.get(dep, (None, [], False)) | 597 input, _, linkable = self.target_outputs.get(dep, (None, [], False)) |
605 if not input: | 598 if not input: |
606 continue | 599 continue |
607 if linkable: | 600 if linkable: |
608 extra_deps.add(input) | 601 extra_deps.add(input) |
609 else: | 602 else: |
610 # TODO: Chrome-specific HACK. Chrome runs this lastchange rule on | 603 # TODO: Chrome-specific HACK. Chrome runs this lastchange rule on |
611 # every build, but we don't want to rebuild when it runs. | 604 # every build, but we don't want to rebuild when it runs. |
612 if 'lastchange' not in input: | 605 if 'lastchange' not in input: |
613 implicit_deps.add(input) | 606 implicit_deps.add(input) |
614 final_deps.extend(list(extra_deps)) | 607 link_deps.extend(list(extra_deps)) |
608 | |
609 if self.is_mac_bundle: | |
610 output = self.ComputeMacBundleOutput(spec) | |
611 output_binary = self.ComputeMacBundleBinaryOutput(spec) | |
612 if not link_deps: | |
613 output_binary = self.ComputeOutput(spec, type='none') | |
614 mac_bundle_depends.append(output_binary) | |
615 else: | |
616 output = output_binary = self.ComputeOutput(spec) | |
617 | |
615 command_map = { | 618 command_map = { |
616 'executable': 'link', | 619 'executable': 'link', |
617 'static_library': 'alink', | 620 'static_library': 'alink', |
618 'loadable_module': 'solink_module', | 621 'loadable_module': 'solink_module', |
619 'shared_library': 'solink', | 622 'shared_library': 'solink', |
620 'none': 'stamp', | 623 'none': 'stamp', |
621 } | 624 } |
622 command = command_map[spec['type']] | 625 command = command_map[spec['type']] |
623 | 626 |
627 if link_deps: | |
628 final_deps = link_deps | |
629 else: | |
630 command = 'stamp' | |
631 order_only += final_deps | |
632 final_deps = [] | |
633 | |
624 if output_uses_linker: | 634 if output_uses_linker: |
625 if self.flavor == 'mac': | 635 if self.flavor == 'mac': |
626 ldflags = self.xcode_settings.GetLdflags(config_name, | 636 ldflags = self.xcode_settings.GetLdflags(config_name, |
627 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), | 637 self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), |
628 self.GypPathToNinja) | 638 self.GypPathToNinja) |
629 else: | 639 else: |
630 ldflags = config.get('ldflags', []) | 640 ldflags = config.get('ldflags', []) |
631 self.WriteVariableList('ldflags', | 641 self.WriteVariableList('ldflags', |
632 gyp.common.uniquer(map(self.ExpandSpecial, | 642 gyp.common.uniquer(map(self.ExpandSpecial, |
633 ldflags))) | 643 ldflags))) |
(...skipping 28 matching lines...) Expand all Loading... | |
662 assert self.is_mac_bundle | 672 assert self.is_mac_bundle |
663 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']) | 673 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']) |
664 return os.path.join(path, self.xcode_settings.GetWrapperName()) | 674 return os.path.join(path, self.xcode_settings.GetWrapperName()) |
665 | 675 |
666 def ComputeMacBundleBinaryOutput(self, spec): | 676 def ComputeMacBundleBinaryOutput(self, spec): |
667 """Return the 'output' (full output path) to the binary in a bundle.""" | 677 """Return the 'output' (full output path) to the binary in a bundle.""" |
668 assert self.is_mac_bundle | 678 assert self.is_mac_bundle |
669 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']) | 679 path = self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']) |
670 return os.path.join(path, self.xcode_settings.GetExecutablePath()) | 680 return os.path.join(path, self.xcode_settings.GetExecutablePath()) |
671 | 681 |
672 def ComputeOutputFileName(self, spec): | 682 def ComputeOutputFileName(self, spec, type=None): |
673 """Compute the filename of the final output for the current target.""" | 683 """Compute the filename of the final output for the current target.""" |
684 if not type: | |
685 type = spec['type'] | |
674 | 686 |
675 # Compute filename prefix: the product prefix, or a default for | 687 # Compute filename prefix: the product prefix, or a default for |
676 # the product type. | 688 # the product type. |
677 DEFAULT_PREFIX = { | 689 DEFAULT_PREFIX = { |
678 'loadable_module': 'lib', | 690 'loadable_module': 'lib', |
679 'shared_library': 'lib', | 691 'shared_library': 'lib', |
680 'static_library': 'lib', | 692 'static_library': 'lib', |
681 } | 693 } |
682 prefix = spec.get('product_prefix', DEFAULT_PREFIX.get(spec['type'], '')) | 694 prefix = spec.get('product_prefix', DEFAULT_PREFIX.get(type, '')) |
683 | 695 |
684 # Compute filename extension: the product extension, or a default | 696 # Compute filename extension: the product extension, or a default |
685 # for the product type. | 697 # for the product type. |
686 DEFAULT_EXTENSION = { | 698 DEFAULT_EXTENSION = { |
687 'static_library': 'a', | 699 'static_library': 'a', |
688 'loadable_module': 'so', | 700 'loadable_module': 'so', |
689 'shared_library': 'so', | 701 'shared_library': 'so', |
690 } | 702 } |
691 extension = spec.get('product_extension', | 703 extension = spec.get('product_extension', |
692 DEFAULT_EXTENSION.get(spec['type'], '')) | 704 DEFAULT_EXTENSION.get(type, '')) |
693 if extension: | 705 if extension: |
694 extension = '.' + extension | 706 extension = '.' + extension |
695 | 707 |
696 if 'product_name' in spec: | 708 if 'product_name' in spec: |
697 # If we were given an explicit name, use that. | 709 # If we were given an explicit name, use that. |
698 target = spec['product_name'] | 710 target = spec['product_name'] |
699 else: | 711 else: |
700 # Otherwise, derive a name from the target name. | 712 # Otherwise, derive a name from the target name. |
701 target = spec['target_name'] | 713 target = spec['target_name'] |
702 if prefix == 'lib': | 714 if prefix == 'lib': |
703 # Snip out an extra 'lib' from libs if appropriate. | 715 # Snip out an extra 'lib' from libs if appropriate. |
704 target = StripPrefix(target, 'lib') | 716 target = StripPrefix(target, 'lib') |
705 | 717 |
706 if spec['type'] in ('static_library', 'loadable_module', 'shared_library', | 718 if type in ('static_library', 'loadable_module', 'shared_library', |
707 'executable'): | 719 'executable'): |
708 return '%s%s%s' % (prefix, target, extension) | 720 return '%s%s%s' % (prefix, target, extension) |
709 elif spec['type'] == 'none': | 721 elif type == 'none': |
710 return '%s.stamp' % target | 722 return '%s.stamp' % target |
711 else: | 723 else: |
712 raise 'Unhandled output type', spec['type'] | 724 raise 'Unhandled output type', type |
713 | 725 |
714 def ComputeOutput(self, spec): | 726 def ComputeOutput(self, spec, type=None): |
715 """Compute the path for the final output of the spec.""" | 727 """Compute the path for the final output of the spec.""" |
728 assert not self.is_mac_bundle or type | |
716 | 729 |
717 assert not self.is_mac_bundle | 730 if not type: |
731 type = spec['type'] | |
718 | 732 |
719 if self.flavor == 'mac' and spec['type'] in ( | 733 if self.flavor == 'mac' and type in ( |
720 'static_library', 'executable', 'shared_library', 'loadable_module'): | 734 'static_library', 'executable', 'shared_library', 'loadable_module'): |
721 filename = self.xcode_settings.GetExecutablePath() | 735 filename = self.xcode_settings.GetExecutablePath() |
722 else: | 736 else: |
723 filename = self.ComputeOutputFileName(spec) | 737 filename = self.ComputeOutputFileName(spec, type) |
724 | 738 |
725 if 'product_dir' in spec: | 739 if 'product_dir' in spec: |
726 path = os.path.join(spec['product_dir'], filename) | 740 path = os.path.join(spec['product_dir'], filename) |
727 return self.ExpandSpecial(path) | 741 return self.ExpandSpecial(path) |
728 | 742 |
729 # Some products go into the output root, libraries go into shared library | 743 # Some products go into the output root, libraries go into shared library |
730 # dir, and everything else goes into the normal place. | 744 # dir, and everything else goes into the normal place. |
731 type_in_output_root = ['executable', 'loadable_module'] | 745 type_in_output_root = ['executable', 'loadable_module'] |
732 if self.flavor == 'mac' and self.toolset == 'target': | 746 if self.flavor == 'mac' and self.toolset == 'target': |
733 type_in_output_root += ['shared_library', 'static_library'] | 747 type_in_output_root += ['shared_library', 'static_library'] |
734 | 748 |
735 if spec['type'] in type_in_output_root: | 749 if type in type_in_output_root: |
736 return filename | 750 return filename |
737 elif spec['type'] == 'shared_library': | 751 elif type == 'shared_library': |
738 libdir = 'lib' | 752 libdir = 'lib' |
739 if self.toolset != 'target': | 753 if self.toolset != 'target': |
740 libdir = 'lib/%s' % self.toolset | 754 libdir = 'lib/%s' % self.toolset |
741 return os.path.join(libdir, filename) | 755 return os.path.join(libdir, filename) |
742 else: | 756 else: |
743 return self.GypPathToUniqueOutput(filename, qualified=False) | 757 return self.GypPathToUniqueOutput(filename, qualified=False) |
744 | 758 |
745 def WriteVariableList(self, var, values): | 759 def WriteVariableList(self, var, values): |
746 if values is None: | 760 if values is None: |
747 values = [] | 761 values = [] |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
994 # For bundles, the binary in the bundle is the right answer. | 1008 # For bundles, the binary in the bundle is the right answer. |
995 target_outputs[qualified_target] = ( | 1009 target_outputs[qualified_target] = ( |
996 output_binary, compile_depends, linkable) | 1010 output_binary, compile_depends, linkable) |
997 | 1011 |
998 # But for all_outputs, the bundle is the interesting bit. | 1012 # But for all_outputs, the bundle is the interesting bit. |
999 if qualified_target in all_targets: | 1013 if qualified_target in all_targets: |
1000 all_outputs.add(output) | 1014 all_outputs.add(output) |
1001 | 1015 |
1002 if all_outputs: | 1016 if all_outputs: |
1003 master_ninja.build('all', 'phony', list(all_outputs)) | 1017 master_ninja.build('all', 'phony', list(all_outputs)) |
OLD | NEW |