Source release v3.1.0
This commit is contained in:
174
third_party/gyp/xcodeproj_file.py
vendored
174
third_party/gyp/xcodeproj_file.py
vendored
@@ -173,7 +173,7 @@ _escaped = re.compile('[\\\\"]|[\x00-\x1f]')
|
||||
|
||||
|
||||
# Used by SourceTreeAndPathFromPath
|
||||
_path_leading_variable = re.compile('^\$\((.*?)\)(/(.*))?$')
|
||||
_path_leading_variable = re.compile(r'^\$\((.*?)\)(/(.*))?$')
|
||||
|
||||
def SourceTreeAndPathFromPath(input_path):
|
||||
"""Given input_path, returns a tuple with sourceTree and path values.
|
||||
@@ -196,7 +196,7 @@ def SourceTreeAndPathFromPath(input_path):
|
||||
return (source_tree, output_path)
|
||||
|
||||
def ConvertVariablesToShellSyntax(input_string):
|
||||
return re.sub('\$\((.*?)\)', '${\\1}', input_string)
|
||||
return re.sub(r'\$\((.*?)\)', '${\\1}', input_string)
|
||||
|
||||
class XCObject(object):
|
||||
"""The abstract base of all class types used in Xcode project files.
|
||||
@@ -341,13 +341,13 @@ class XCObject(object):
|
||||
elif isinstance(value, dict):
|
||||
# dicts are never strong.
|
||||
if is_strong:
|
||||
raise TypeError, 'Strong dict for key ' + key + ' in ' + \
|
||||
self.__class__.__name__
|
||||
raise TypeError('Strong dict for key ' + key + ' in ' + \
|
||||
self.__class__.__name__)
|
||||
else:
|
||||
that._properties[key] = value.copy()
|
||||
else:
|
||||
raise TypeError, 'Unexpected type ' + value.__class__.__name__ + \
|
||||
' for key ' + key + ' in ' + self.__class__.__name__
|
||||
raise TypeError('Unexpected type ' + value.__class__.__name__ + \
|
||||
' for key ' + key + ' in ' + self.__class__.__name__)
|
||||
|
||||
return that
|
||||
|
||||
@@ -366,8 +366,7 @@ class XCObject(object):
|
||||
('name' in self._schema and self._schema['name'][3]):
|
||||
return self._properties['name']
|
||||
|
||||
raise NotImplementedError, \
|
||||
self.__class__.__name__ + ' must implement Name'
|
||||
raise NotImplementedError(self.__class__.__name__ + ' must implement Name')
|
||||
|
||||
def Comment(self):
|
||||
"""Return a comment string for the object.
|
||||
@@ -466,10 +465,10 @@ class XCObject(object):
|
||||
for descendant in descendants:
|
||||
if descendant.id in ids:
|
||||
other = ids[descendant.id]
|
||||
raise KeyError, \
|
||||
raise KeyError(
|
||||
'Duplicate ID %s, objects "%s" and "%s" in "%s"' % \
|
||||
(descendant.id, str(descendant._properties),
|
||||
str(other._properties), self._properties['rootObject'].Name())
|
||||
str(other._properties), self._properties['rootObject'].Name()))
|
||||
ids[descendant.id] = descendant
|
||||
|
||||
def Children(self):
|
||||
@@ -630,7 +629,7 @@ class XCObject(object):
|
||||
sep
|
||||
printable += end_tabs + '}'
|
||||
else:
|
||||
raise TypeError, "Can't make " + value.__class__.__name__ + ' printable'
|
||||
raise TypeError("Can't make " + value.__class__.__name__ + ' printable')
|
||||
|
||||
if comment != None:
|
||||
printable += ' ' + self._EncodeComment(comment)
|
||||
@@ -756,31 +755,31 @@ class XCObject(object):
|
||||
for property, value in properties.iteritems():
|
||||
# Make sure the property is in the schema.
|
||||
if not property in self._schema:
|
||||
raise KeyError, property + ' not in ' + self.__class__.__name__
|
||||
raise KeyError(property + ' not in ' + self.__class__.__name__)
|
||||
|
||||
# Make sure the property conforms to the schema.
|
||||
(is_list, property_type, is_strong) = self._schema[property][0:3]
|
||||
if is_list:
|
||||
if value.__class__ != list:
|
||||
raise TypeError, \
|
||||
raise TypeError(
|
||||
property + ' of ' + self.__class__.__name__ + \
|
||||
' must be list, not ' + value.__class__.__name__
|
||||
' must be list, not ' + value.__class__.__name__)
|
||||
for item in value:
|
||||
if not isinstance(item, property_type) and \
|
||||
not (item.__class__ == unicode and property_type == str):
|
||||
# Accept unicode where str is specified. str is treated as
|
||||
# UTF-8-encoded.
|
||||
raise TypeError, \
|
||||
raise TypeError(
|
||||
'item of ' + property + ' of ' + self.__class__.__name__ + \
|
||||
' must be ' + property_type.__name__ + ', not ' + \
|
||||
item.__class__.__name__
|
||||
item.__class__.__name__)
|
||||
elif not isinstance(value, property_type) and \
|
||||
not (value.__class__ == unicode and property_type == str):
|
||||
# Accept unicode where str is specified. str is treated as
|
||||
# UTF-8-encoded.
|
||||
raise TypeError, \
|
||||
raise TypeError(
|
||||
property + ' of ' + self.__class__.__name__ + ' must be ' + \
|
||||
property_type.__name__ + ', not ' + value.__class__.__name__
|
||||
property_type.__name__ + ', not ' + value.__class__.__name__)
|
||||
|
||||
# Checks passed, perform the assignment.
|
||||
if do_copy:
|
||||
@@ -804,9 +803,9 @@ class XCObject(object):
|
||||
elif isinstance(value, dict):
|
||||
self._properties[property] = value.copy()
|
||||
else:
|
||||
raise TypeError, "Don't know how to copy a " + \
|
||||
value.__class__.__name__ + ' object for ' + \
|
||||
property + ' in ' + self.__class__.__name__
|
||||
raise TypeError("Don't know how to copy a " + \
|
||||
value.__class__.__name__ + ' object for ' + \
|
||||
property + ' in ' + self.__class__.__name__)
|
||||
else:
|
||||
self._properties[property] = value
|
||||
|
||||
@@ -837,15 +836,15 @@ class XCObject(object):
|
||||
|
||||
# Schema validation.
|
||||
if not key in self._schema:
|
||||
raise KeyError, key + ' not in ' + self.__class__.__name__
|
||||
raise KeyError(key + ' not in ' + self.__class__.__name__)
|
||||
|
||||
(is_list, property_type, is_strong) = self._schema[key][0:3]
|
||||
if not is_list:
|
||||
raise TypeError, key + ' of ' + self.__class__.__name__ + ' must be list'
|
||||
raise TypeError(key + ' of ' + self.__class__.__name__ + ' must be list')
|
||||
if not isinstance(value, property_type):
|
||||
raise TypeError, 'item of ' + key + ' of ' + self.__class__.__name__ + \
|
||||
' must be ' + property_type.__name__ + ', not ' + \
|
||||
value.__class__.__name__
|
||||
raise TypeError('item of ' + key + ' of ' + self.__class__.__name__ + \
|
||||
' must be ' + property_type.__name__ + ', not ' + \
|
||||
value.__class__.__name__)
|
||||
|
||||
# If the property doesn't exist yet, create a new empty list to receive the
|
||||
# item.
|
||||
@@ -869,7 +868,7 @@ class XCObject(object):
|
||||
for property, attributes in self._schema.iteritems():
|
||||
(is_list, property_type, is_strong, is_required) = attributes[0:4]
|
||||
if is_required and not property in self._properties:
|
||||
raise KeyError, self.__class__.__name__ + ' requires ' + property
|
||||
raise KeyError(self.__class__.__name__ + ' requires ' + property)
|
||||
|
||||
def _SetDefaultsFromSchema(self):
|
||||
"""Assign object default values according to the schema. This will not
|
||||
@@ -1143,16 +1142,16 @@ class PBXGroup(XCHierarchicalElement):
|
||||
child_path = child.PathFromSourceTreeAndPath()
|
||||
if child_path:
|
||||
if child_path in self._children_by_path:
|
||||
raise ValueError, 'Found multiple children with path ' + child_path
|
||||
raise ValueError('Found multiple children with path ' + child_path)
|
||||
self._children_by_path[child_path] = child
|
||||
|
||||
if isinstance(child, PBXVariantGroup):
|
||||
child_name = child._properties.get('name', None)
|
||||
key = (child_name, child_path)
|
||||
if key in self._variant_children_by_name_and_path:
|
||||
raise ValueError, 'Found multiple PBXVariantGroup children with ' + \
|
||||
'name ' + str(child_name) + ' and path ' + \
|
||||
str(child_path)
|
||||
raise ValueError('Found multiple PBXVariantGroup children with ' + \
|
||||
'name ' + str(child_name) + ' and path ' + \
|
||||
str(child_path))
|
||||
self._variant_children_by_name_and_path[key] = child
|
||||
|
||||
def AppendChild(self, child):
|
||||
@@ -1493,6 +1492,7 @@ class PBXFileReference(XCFileLikeElement, XCContainerPortal, XCRemoteObject):
|
||||
'icns': 'image.icns',
|
||||
'java': 'sourcecode.java',
|
||||
'js': 'sourcecode.javascript',
|
||||
'kext': 'wrapper.kext',
|
||||
'm': 'sourcecode.c.objc',
|
||||
'mm': 'sourcecode.cpp.objcpp',
|
||||
'nib': 'wrapper.nib',
|
||||
@@ -1508,10 +1508,12 @@ class PBXFileReference(XCFileLikeElement, XCContainerPortal, XCRemoteObject):
|
||||
's': 'sourcecode.asm',
|
||||
'storyboard': 'file.storyboard',
|
||||
'strings': 'text.plist.strings',
|
||||
'swift': 'sourcecode.swift',
|
||||
'ttf': 'file',
|
||||
'xcassets': 'folder.assetcatalog',
|
||||
'xcconfig': 'text.xcconfig',
|
||||
'xcdatamodel': 'wrapper.xcdatamodel',
|
||||
'xcdatamodeld':'wrapper.xcdatamodeld',
|
||||
'xib': 'file.xib',
|
||||
'y': 'sourcecode.yacc',
|
||||
}
|
||||
@@ -1606,7 +1608,7 @@ class XCConfigurationList(XCObject):
|
||||
if configuration._properties['name'] == name:
|
||||
return configuration
|
||||
|
||||
raise KeyError, name
|
||||
raise KeyError(name)
|
||||
|
||||
def DefaultConfiguration(self):
|
||||
"""Convenience accessor to obtain the default XCBuildConfiguration."""
|
||||
@@ -1663,7 +1665,7 @@ class XCConfigurationList(XCObject):
|
||||
value = configuration_value
|
||||
else:
|
||||
if value != configuration_value:
|
||||
raise ValueError, 'Variant values for ' + key
|
||||
raise ValueError('Variant values for ' + key)
|
||||
|
||||
return value
|
||||
|
||||
@@ -1770,8 +1772,8 @@ class XCBuildPhase(XCObject):
|
||||
# added, either as a child or deeper descendant. The second item should
|
||||
# be a boolean indicating whether files should be added into hierarchical
|
||||
# groups or one single flat group.
|
||||
raise NotImplementedError, \
|
||||
self.__class__.__name__ + ' must implement FileGroup'
|
||||
raise NotImplementedError(
|
||||
self.__class__.__name__ + ' must implement FileGroup')
|
||||
|
||||
def _AddPathToDict(self, pbxbuildfile, path):
|
||||
"""Adds path to the dict tracking paths belonging to this build phase.
|
||||
@@ -1780,7 +1782,7 @@ class XCBuildPhase(XCObject):
|
||||
"""
|
||||
|
||||
if path in self._files_by_path:
|
||||
raise ValueError, 'Found multiple build files with path ' + path
|
||||
raise ValueError('Found multiple build files with path ' + path)
|
||||
self._files_by_path[path] = pbxbuildfile
|
||||
|
||||
def _AddBuildFileToDicts(self, pbxbuildfile, path=None):
|
||||
@@ -1835,8 +1837,8 @@ class XCBuildPhase(XCObject):
|
||||
# problem.
|
||||
if xcfilelikeelement in self._files_by_xcfilelikeelement and \
|
||||
self._files_by_xcfilelikeelement[xcfilelikeelement] != pbxbuildfile:
|
||||
raise ValueError, 'Found multiple build files for ' + \
|
||||
xcfilelikeelement.Name()
|
||||
raise ValueError('Found multiple build files for ' + \
|
||||
xcfilelikeelement.Name())
|
||||
self._files_by_xcfilelikeelement[xcfilelikeelement] = pbxbuildfile
|
||||
|
||||
def AppendBuildFile(self, pbxbuildfile, path=None):
|
||||
@@ -1950,6 +1952,7 @@ class PBXCopyFilesBuildPhase(XCBuildPhase):
|
||||
# path_tree_to_subfolder maps names of Xcode variables to the associated
|
||||
# dstSubfolderSpec property value used in a PBXCopyFilesBuildPhase object.
|
||||
path_tree_to_subfolder = {
|
||||
'BUILT_FRAMEWORKS_DIR': 10, # Frameworks Directory
|
||||
'BUILT_PRODUCTS_DIR': 16, # Products Directory
|
||||
# Other types that can be chosen via the Xcode UI.
|
||||
# TODO(mark): Map Xcode variable names to these.
|
||||
@@ -1957,7 +1960,6 @@ class PBXCopyFilesBuildPhase(XCBuildPhase):
|
||||
# : 6, # Executables: 6
|
||||
# : 7, # Resources
|
||||
# : 15, # Java Resources
|
||||
# : 10, # Frameworks
|
||||
# : 11, # Shared Frameworks
|
||||
# : 12, # Shared Support
|
||||
# : 13, # PlugIns
|
||||
@@ -2000,8 +2002,8 @@ class PBXCopyFilesBuildPhase(XCBuildPhase):
|
||||
subfolder = 0
|
||||
relative_path = path[1:]
|
||||
else:
|
||||
raise ValueError, 'Can\'t use path %s in a %s' % \
|
||||
(path, self.__class__.__name__)
|
||||
raise ValueError('Can\'t use path %s in a %s' % \
|
||||
(path, self.__class__.__name__))
|
||||
|
||||
self._properties['dstPath'] = relative_path
|
||||
self._properties['dstSubfolderSpec'] = subfolder
|
||||
@@ -2237,10 +2239,16 @@ class PBXNativeTarget(XCTarget):
|
||||
# Mapping from Xcode product-types to settings. The settings are:
|
||||
# filetype : used for explicitFileType in the project file
|
||||
# prefix : the prefix for the file name
|
||||
# suffix : the suffix for the filen ame
|
||||
# suffix : the suffix for the file name
|
||||
_product_filetypes = {
|
||||
'com.apple.product-type.application': ['wrapper.application',
|
||||
'', '.app'],
|
||||
'com.apple.product-type.application': ['wrapper.application',
|
||||
'', '.app'],
|
||||
'com.apple.product-type.application.watchapp': ['wrapper.application',
|
||||
'', '.app'],
|
||||
'com.apple.product-type.watchkit-extension': ['wrapper.app-extension',
|
||||
'', '.appex'],
|
||||
'com.apple.product-type.app-extension': ['wrapper.app-extension',
|
||||
'', '.appex'],
|
||||
'com.apple.product-type.bundle': ['wrapper.cfbundle',
|
||||
'', '.bundle'],
|
||||
'com.apple.product-type.framework': ['wrapper.framework',
|
||||
@@ -2253,8 +2261,12 @@ class PBXNativeTarget(XCTarget):
|
||||
'', ''],
|
||||
'com.apple.product-type.bundle.unit-test': ['wrapper.cfbundle',
|
||||
'', '.xctest'],
|
||||
'com.apple.product-type.bundle.ui-testing': ['wrapper.cfbundle',
|
||||
'', '.xctest'],
|
||||
'com.googlecode.gyp.xcode.bundle': ['compiled.mach-o.dylib',
|
||||
'', '.so'],
|
||||
'com.apple.product-type.kernel-extension': ['wrapper.kext',
|
||||
'', '.kext'],
|
||||
}
|
||||
|
||||
def __init__(self, properties=None, id=None, parent=None,
|
||||
@@ -2307,17 +2319,19 @@ class PBXNativeTarget(XCTarget):
|
||||
force_extension = suffix[1:]
|
||||
|
||||
if self._properties['productType'] == \
|
||||
'com.apple.product-type-bundle.unit.test':
|
||||
'com.apple.product-type-bundle.unit.test' or \
|
||||
self._properties['productType'] == \
|
||||
'com.apple.product-type-bundle.ui-testing':
|
||||
if force_extension is None:
|
||||
force_extension = suffix[1:]
|
||||
|
||||
if force_extension is not None:
|
||||
# If it's a wrapper (bundle), set WRAPPER_EXTENSION.
|
||||
# Extension override.
|
||||
suffix = '.' + force_extension
|
||||
if filetype.startswith('wrapper.'):
|
||||
self.SetBuildSetting('WRAPPER_EXTENSION', force_extension)
|
||||
else:
|
||||
# Extension override.
|
||||
suffix = '.' + force_extension
|
||||
self.SetBuildSetting('EXECUTABLE_EXTENSION', force_extension)
|
||||
|
||||
if filetype.startswith('compiled.mach-o.executable'):
|
||||
@@ -2733,8 +2747,53 @@ class PBXProject(XCContainerPortal):
|
||||
|
||||
self._SetUpProductReferences(other_pbxproject, product_group, project_ref)
|
||||
|
||||
inherit_unique_symroot = self._AllSymrootsUnique(other_pbxproject, False)
|
||||
targets = other_pbxproject.GetProperty('targets')
|
||||
if all(self._AllSymrootsUnique(t, inherit_unique_symroot) for t in targets):
|
||||
dir_path = project_ref._properties['path']
|
||||
product_group._hashables.extend(dir_path)
|
||||
|
||||
return [product_group, project_ref]
|
||||
|
||||
def _AllSymrootsUnique(self, target, inherit_unique_symroot):
|
||||
# Returns True if all configurations have a unique 'SYMROOT' attribute.
|
||||
# The value of inherit_unique_symroot decides, if a configuration is assumed
|
||||
# to inherit a unique 'SYMROOT' attribute from its parent, if it doesn't
|
||||
# define an explicit value for 'SYMROOT'.
|
||||
symroots = self._DefinedSymroots(target)
|
||||
for s in self._DefinedSymroots(target):
|
||||
if (s is not None and not self._IsUniqueSymrootForTarget(s) or
|
||||
s is None and not inherit_unique_symroot):
|
||||
return False
|
||||
return True if symroots else inherit_unique_symroot
|
||||
|
||||
def _DefinedSymroots(self, target):
|
||||
# Returns all values for the 'SYMROOT' attribute defined in all
|
||||
# configurations for this target. If any configuration doesn't define the
|
||||
# 'SYMROOT' attribute, None is added to the returned set. If all
|
||||
# configurations don't define the 'SYMROOT' attribute, an empty set is
|
||||
# returned.
|
||||
config_list = target.GetProperty('buildConfigurationList')
|
||||
symroots = set()
|
||||
for config in config_list.GetProperty('buildConfigurations'):
|
||||
setting = config.GetProperty('buildSettings')
|
||||
if 'SYMROOT' in setting:
|
||||
symroots.add(setting['SYMROOT'])
|
||||
else:
|
||||
symroots.add(None)
|
||||
if len(symroots) == 1 and None in symroots:
|
||||
return set()
|
||||
return symroots
|
||||
|
||||
def _IsUniqueSymrootForTarget(self, symroot):
|
||||
# This method returns True if all configurations in target contain a
|
||||
# 'SYMROOT' attribute that is unique for the given target. A value is
|
||||
# unique, if the Xcode macro '$SRCROOT' appears in it in any form.
|
||||
uniquifier = ['$SRCROOT', '$(SRCROOT)']
|
||||
if any(x in symroot for x in uniquifier):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _SetUpProductReferences(self, other_pbxproject, product_group,
|
||||
project_ref):
|
||||
# TODO(mark): This only adds references to products in other_pbxproject
|
||||
@@ -2803,7 +2862,7 @@ class PBXProject(XCContainerPortal):
|
||||
product_group = ref_dict['ProductGroup']
|
||||
product_group._properties['children'] = sorted(
|
||||
product_group._properties['children'],
|
||||
cmp=lambda x, y: CompareProducts(x, y, remote_products))
|
||||
cmp=lambda x, y, rp=remote_products: CompareProducts(x, y, rp))
|
||||
|
||||
|
||||
class XCProjectFile(XCObject):
|
||||
@@ -2811,27 +2870,10 @@ class XCProjectFile(XCObject):
|
||||
_schema.update({
|
||||
'archiveVersion': [0, int, 0, 1, 1],
|
||||
'classes': [0, dict, 0, 1, {}],
|
||||
'objectVersion': [0, int, 0, 1, 45],
|
||||
'objectVersion': [0, int, 0, 1, 46],
|
||||
'rootObject': [0, PBXProject, 1, 1],
|
||||
})
|
||||
|
||||
def SetXcodeVersion(self, version):
|
||||
version_to_object_version = {
|
||||
'2.4': 45,
|
||||
'3.0': 45,
|
||||
'3.1': 45,
|
||||
'3.2': 46,
|
||||
}
|
||||
if not version in version_to_object_version:
|
||||
supported_str = ', '.join(sorted(version_to_object_version.keys()))
|
||||
raise Exception(
|
||||
'Unsupported Xcode version %s (supported: %s)' %
|
||||
( version, supported_str ) )
|
||||
compatibility_version = 'Xcode %s' % version
|
||||
self._properties['rootObject'].SetProperty('compatibilityVersion',
|
||||
compatibility_version)
|
||||
self.SetProperty('objectVersion', version_to_object_version[version]);
|
||||
|
||||
def ComputeIDs(self, recursive=True, overwrite=True, hash=None):
|
||||
# Although XCProjectFile is implemented here as an XCObject, it's not a
|
||||
# proper object in the Xcode sense, and it certainly doesn't have its own
|
||||
|
||||
Reference in New Issue
Block a user