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 1927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 | 1938 |
1939 | 1939 |
1940 class PBXCopyFilesBuildPhase(XCBuildPhase): | 1940 class PBXCopyFilesBuildPhase(XCBuildPhase): |
1941 _schema = XCBuildPhase._schema.copy() | 1941 _schema = XCBuildPhase._schema.copy() |
1942 _schema.update({ | 1942 _schema.update({ |
1943 'dstPath': [0, str, 0, 1], | 1943 'dstPath': [0, str, 0, 1], |
1944 'dstSubfolderSpec': [0, int, 0, 1], | 1944 'dstSubfolderSpec': [0, int, 0, 1], |
1945 'name': [0, str, 0, 0], | 1945 'name': [0, str, 0, 0], |
1946 }) | 1946 }) |
1947 | 1947 |
1948 # path_tree_re matches "$(DIR)/path" or just "$(DIR)". Match group 1 is | 1948 # path_tree_re matches "$(DIR)/path", "$(DIR)/$(DIR2)/path" or just "$(DIR)". |
1949 # "DIR", match group 3 is "path" or None. | 1949 # Match group 1 is "DIR", group 3 is "path" or "$(DIR2") or "$(DIR2)/path" |
1950 path_tree_re = re.compile('^\\$\\((.*)\\)(/(.*)|)$') | 1950 # or None. If group 3 is "path", group 4 will be None otherwise group 4 is |
| 1951 # "DIR2" and group 6 is "path". |
| 1952 path_tree_re = re.compile(r'^\$\((.*?)\)(/(\$\((.*?)\)(/(.*)|)|(.*)|)|)$') |
1951 | 1953 |
1952 # path_tree_to_subfolder maps names of Xcode variables to the associated | 1954 # path_tree_{first,second}_to_subfolder map names of Xcode variables to the |
1953 # dstSubfolderSpec property value used in a PBXCopyFilesBuildPhase object. | 1955 # associated dstSubfolderSpec property value used in a PBXCopyFilesBuildPhase |
1954 path_tree_to_subfolder = { | 1956 # object. |
1955 'BUILT_FRAMEWORKS_DIR': 10, # Frameworks Directory | 1957 path_tree_first_to_subfolder = { |
1956 'BUILT_PRODUCTS_DIR': 16, # Products Directory | 1958 # Types that can be chosen via the Xcode UI. |
1957 # Other types that can be chosen via the Xcode UI. | 1959 'BUILT_PRODUCTS_DIR': 16, # Products Directory |
1958 # TODO(mark): Map Xcode variable names to these. | 1960 'BUILT_FRAMEWORKS_DIR': 10, # Not an official Xcode macro. |
1959 # : 1, # Wrapper | 1961 # Existed before support for the |
1960 # : 6, # Executables: 6 | 1962 # names below was added. Maps to |
1961 # : 7, # Resources | 1963 # "Frameworks". |
1962 # : 15, # Java Resources | 1964 } |
1963 # : 11, # Shared Frameworks | 1965 |
1964 # : 12, # Shared Support | 1966 path_tree_second_to_subfolder = { |
1965 # : 13, # PlugIns | 1967 'WRAPPER_NAME': 1, # Wrapper |
| 1968 # Although Xcode's friendly name is "Executables", the destination |
| 1969 # is demonstrably the value of the build setting |
| 1970 # EXECUTABLE_FOLDER_PATH not EXECUTABLES_FOLDER_PATH. |
| 1971 'EXECUTABLE_FOLDER_PATH': 6, # Executables. |
| 1972 'UNLOCALIZED_RESOURCES_FOLDER_PATH': 7, # Resources |
| 1973 'JAVA_FOLDER_PATH': 15, # Java Resources |
| 1974 'FRAMEWORKS_FOLDER_PATH': 10, # Frameworks |
| 1975 'SHARED_FRAMEWORKS_FOLDER_PATH': 11, # Shared Frameworks |
| 1976 'SHARED_SUPPORT_FOLDER_PATH': 12, # Shared Support |
| 1977 'PLUGINS_FOLDER_PATH': 13, # PlugIns |
| 1978 # For XPC Services, Xcode sets both dstPath and dstSubfolderSpec. |
| 1979 # Note that it re-uses the BUILT_PRODUCTS_DIR value for |
| 1980 # dstSubfolderSpec. dstPath is set below. |
| 1981 'XPCSERVICES_FOLDER_PATH': 16, # XPC Services. |
1966 } | 1982 } |
1967 | 1983 |
1968 def Name(self): | 1984 def Name(self): |
1969 if 'name' in self._properties: | 1985 if 'name' in self._properties: |
1970 return self._properties['name'] | 1986 return self._properties['name'] |
1971 | 1987 |
1972 return 'CopyFiles' | 1988 return 'CopyFiles' |
1973 | 1989 |
1974 def FileGroup(self, path): | 1990 def FileGroup(self, path): |
1975 return self.PBXProjectAncestor().RootGroupForPath(path) | 1991 return self.PBXProjectAncestor().RootGroupForPath(path) |
1976 | 1992 |
1977 def SetDestination(self, path): | 1993 def SetDestination(self, path): |
1978 """Set the dstSubfolderSpec and dstPath properties from path. | 1994 """Set the dstSubfolderSpec and dstPath properties from path. |
1979 | 1995 |
1980 path may be specified in the same notation used for XCHierarchicalElements, | 1996 path may be specified in the same notation used for XCHierarchicalElements, |
1981 specifically, "$(DIR)/path". | 1997 specifically, "$(DIR)/path". |
1982 """ | 1998 """ |
1983 | 1999 |
1984 path_tree_match = self.path_tree_re.search(path) | 2000 path_tree_match = self.path_tree_re.search(path) |
1985 if path_tree_match: | 2001 if path_tree_match: |
1986 # Everything else needs to be relative to an Xcode variable. | 2002 path_tree = path_tree_match.group(1); |
1987 path_tree = path_tree_match.group(1) | 2003 if path_tree in self.path_tree_first_to_subfolder: |
1988 relative_path = path_tree_match.group(3) | 2004 subfolder = self.path_tree_first_to_subfolder[path_tree] |
1989 | 2005 relative_path = path_tree_match.group(3) |
1990 if path_tree in self.path_tree_to_subfolder: | |
1991 subfolder = self.path_tree_to_subfolder[path_tree] | |
1992 if relative_path is None: | 2006 if relative_path is None: |
1993 relative_path = '' | 2007 relative_path = '' |
| 2008 |
| 2009 if subfolder == 16 and path_tree_match.group(4) is not None: |
| 2010 # BUILT_PRODUCTS_DIR (16) is the first element in a path whose |
| 2011 # second element is possibly one of the variable names in |
| 2012 # path_tree_second_to_subfolder. Xcode sets the values of all these |
| 2013 # variables to relative paths so .gyp files must prefix them with |
| 2014 # BUILT_PRODUCTS_DIR, e.g. |
| 2015 # $(BUILT_PRODUCTS_DIR)/$(PLUGINS_FOLDER_PATH). Then |
| 2016 # xcode_emulation.py can export these variables with the same values |
| 2017 # as Xcode yet make & ninja files can determine the absolute path |
| 2018 # to the target. Xcode uses the dstSubfolderSpec value set here |
| 2019 # to determine the full path. |
| 2020 # |
| 2021 # An alternative of xcode_emulation.py setting the values to absolute |
| 2022 # paths when exporting these variables has been ruled out because |
| 2023 # then the values would be different depending on the build tool. |
| 2024 # |
| 2025 # Another alternative is to invent new names for the variables used |
| 2026 # to match to the subfolder indices in the second table. .gyp files |
| 2027 # then will not need to prepend $(BUILT_PRODUCTS_DIR) because |
| 2028 # xcode_emulation.py can set the values of those variables to |
| 2029 # the absolute paths when exporting. This is possibly the thinking |
| 2030 # behind BUILT_FRAMEWORKS_DIR which is used in exactly this manner. |
| 2031 # |
| 2032 # Requiring prepending BUILT_PRODUCTS_DIR has been chosen because |
| 2033 # this same way could be used to specify destinations in .gyp files |
| 2034 # that pre-date this addition to GYP. However they would only work |
| 2035 # with the Xcode generator. The previous version of xcode_emulation.py |
| 2036 # does not export these variables. Such files will get the benefit |
| 2037 # of the Xcode UI showing the proper destination name simply by |
| 2038 # regenerating the projects with this version of GYP. |
| 2039 path_tree = path_tree_match.group(4) |
| 2040 relative_path = path_tree_match.group(6) |
| 2041 separator = '/' |
| 2042 |
| 2043 if path_tree in self.path_tree_second_to_subfolder: |
| 2044 subfolder = self.path_tree_second_to_subfolder[path_tree] |
| 2045 if relative_path is None: |
| 2046 relative_path = '' |
| 2047 separator = '' |
| 2048 if path_tree == 'XPCSERVICES_FOLDER_PATH': |
| 2049 relative_path = '$(CONTENTS_FOLDER_PATH)/XPCServices' \ |
| 2050 + separator + relative_path |
| 2051 else: |
| 2052 # subfolder = 16 from above |
| 2053 # The second element of the path is an unrecognized variable. |
| 2054 # Include it and any remaining elements in relative_path. |
| 2055 relative_path = path_tree_match.group(3); |
| 2056 |
1994 else: | 2057 else: |
1995 # The path starts with an unrecognized Xcode variable | 2058 # The path starts with an unrecognized Xcode variable |
1996 # name like $(SRCROOT). Xcode will still handle this | 2059 # name like $(SRCROOT). Xcode will still handle this |
1997 # as an "absolute path" that starts with the variable. | 2060 # as an "absolute path" that starts with the variable. |
1998 subfolder = 0 | 2061 subfolder = 0 |
1999 relative_path = path | 2062 relative_path = path |
2000 elif path.startswith('/'): | 2063 elif path.startswith('/'): |
2001 # Special case. Absolute paths are in dstSubfolderSpec 0. | 2064 # Special case. Absolute paths are in dstSubfolderSpec 0. |
2002 subfolder = 0 | 2065 subfolder = 0 |
2003 relative_path = path[1:] | 2066 relative_path = path[1:] |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2922 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') | 2985 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') |
2923 for object in sorted(objects_by_class[class_name], | 2986 for object in sorted(objects_by_class[class_name], |
2924 cmp=lambda x, y: cmp(x.id, y.id)): | 2987 cmp=lambda x, y: cmp(x.id, y.id)): |
2925 object.Print(file) | 2988 object.Print(file) |
2926 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') | 2989 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') |
2927 | 2990 |
2928 if self._should_print_single_line: | 2991 if self._should_print_single_line: |
2929 self._XCPrint(file, 0, '}; ') | 2992 self._XCPrint(file, 0, '}; ') |
2930 else: | 2993 else: |
2931 self._XCPrint(file, 1, '};\n') | 2994 self._XCPrint(file, 1, '};\n') |
OLD | NEW |