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 """Xcode project file generator. | 5 """Xcode project file generator. |
6 | 6 |
7 This module is both an Xcode project file generator and a documentation of the | 7 This module is both an Xcode project file generator and a documentation of the |
8 Xcode project file format. Knowledge of the project file format was gained | 8 Xcode project file format. Knowledge of the project file format was gained |
9 based on extensive experience with Xcode, and by making changes to projects in | 9 based on extensive experience with Xcode, and by making changes to projects in |
10 Xcode.app and observing the resultant changes in the associated project files. | 10 Xcode.app and observing the resultant changes in the associated project files. |
(...skipping 2722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2733 cmp(x['ProjectRef'].Name().lower(), | 2733 cmp(x['ProjectRef'].Name().lower(), |
2734 y['ProjectRef'].Name().lower())) | 2734 y['ProjectRef'].Name().lower())) |
2735 else: | 2735 else: |
2736 # The link already exists. Pull out the relevnt data. | 2736 # The link already exists. Pull out the relevnt data. |
2737 project_ref_dict = self._other_pbxprojects[other_pbxproject] | 2737 project_ref_dict = self._other_pbxprojects[other_pbxproject] |
2738 product_group = project_ref_dict['ProductGroup'] | 2738 product_group = project_ref_dict['ProductGroup'] |
2739 project_ref = project_ref_dict['ProjectRef'] | 2739 project_ref = project_ref_dict['ProjectRef'] |
2740 | 2740 |
2741 self._SetUpProductReferences(other_pbxproject, product_group, project_ref) | 2741 self._SetUpProductReferences(other_pbxproject, product_group, project_ref) |
2742 | 2742 |
| 2743 inherit_unique_symroot = self._AllSymrootsUnique(other_pbxproject, False) |
| 2744 targets = other_pbxproject.GetProperty('targets') |
| 2745 if all(self._AllSymrootsUnique(t, inherit_unique_symroot) for t in targets): |
| 2746 dir_path = project_ref._properties['path'] |
| 2747 product_group._hashables.extend(dir_path) |
| 2748 |
2743 return [product_group, project_ref] | 2749 return [product_group, project_ref] |
2744 | 2750 |
| 2751 def _AllSymrootsUnique(self, target, inherit_unique_symroot): |
| 2752 # Returns True if all configurations have a unique 'SYMROOT' attribute. |
| 2753 # The value of inherit_unique_symroot decides, if a configuration is assumed |
| 2754 # to inherit a unique 'SYMROOT' attribute from its parent, if it doesn't |
| 2755 # define an explicit value for 'SYMROOT'. |
| 2756 symroots = self._DefinedSymroots(target) |
| 2757 for s in self._DefinedSymroots(target): |
| 2758 if (s is not None and not self._IsUniqueSymrootForTarget(s) or |
| 2759 s is None and not inherit_unique_symroot): |
| 2760 return False |
| 2761 return True if symroots else return inherit_unique_symroot |
| 2762 |
| 2763 def _DefinedSymroots(self, target): |
| 2764 # Returns all values for the 'SYMROOT' attribute defined in all |
| 2765 # configurations for this target. If any configuration doesn't define the |
| 2766 # 'SYMROOT' attribute, None is added to the returned set. If all |
| 2767 # configurations don't define the 'SYMROOT' attribute, an empty set is |
| 2768 # returned. |
| 2769 config_list = target.GetProperty('buildConfigurationList') |
| 2770 symroots = set() |
| 2771 for config in config_list.GetProperty('buildConfigurations'): |
| 2772 setting = config.GetProperty('buildSettings') |
| 2773 if 'SYMROOT' in setting: |
| 2774 symroots.add(setting['SYMROOT']) |
| 2775 else: |
| 2776 symroots.add(None) |
| 2777 if len(symroots) == 1 and None in symroots: |
| 2778 return set() |
| 2779 return symroots |
| 2780 |
| 2781 def _IsUniqueSymrootForTarget(self, symroot): |
| 2782 # This method returns True if all configurations in target contain a |
| 2783 # 'SYMROOT' attribute that is unique for the given target. A value is |
| 2784 # unique, if the Xcode macro '$SRCROOT' appears in it in any form. |
| 2785 uniquifier = ['$SRCROOT', '$(SRCROOT)'] |
| 2786 if any(x in symroot for x in uniquifier): |
| 2787 return True |
| 2788 return False |
| 2789 |
2745 def _SetUpProductReferences(self, other_pbxproject, product_group, | 2790 def _SetUpProductReferences(self, other_pbxproject, product_group, |
2746 project_ref): | 2791 project_ref): |
2747 # TODO(mark): This only adds references to products in other_pbxproject | 2792 # TODO(mark): This only adds references to products in other_pbxproject |
2748 # when they don't exist in this pbxproject. Perhaps it should also | 2793 # when they don't exist in this pbxproject. Perhaps it should also |
2749 # remove references from this pbxproject that are no longer present in | 2794 # remove references from this pbxproject that are no longer present in |
2750 # other_pbxproject. Perhaps it should update various properties if they | 2795 # other_pbxproject. Perhaps it should update various properties if they |
2751 # change. | 2796 # change. |
2752 for target in other_pbxproject._properties['targets']: | 2797 for target in other_pbxproject._properties['targets']: |
2753 if not isinstance(target, PBXNativeTarget): | 2798 if not isinstance(target, PBXNativeTarget): |
2754 continue | 2799 continue |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') | 2932 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') |
2888 for object in sorted(objects_by_class[class_name], | 2933 for object in sorted(objects_by_class[class_name], |
2889 cmp=lambda x, y: cmp(x.id, y.id)): | 2934 cmp=lambda x, y: cmp(x.id, y.id)): |
2890 object.Print(file) | 2935 object.Print(file) |
2891 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') | 2936 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') |
2892 | 2937 |
2893 if self._should_print_single_line: | 2938 if self._should_print_single_line: |
2894 self._XCPrint(file, 0, '}; ') | 2939 self._XCPrint(file, 0, '}; ') |
2895 else: | 2940 else: |
2896 self._XCPrint(file, 1, '};\n') | 2941 self._XCPrint(file, 1, '};\n') |
OLD | NEW |