mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
ios: Correct xcode-hybrid setup for Xcode 14.
Changes copied verbatim from Chromium with one exception to remove Chromium specific gn args. This includes a mini_chromium roll to not codesign within Xcode. Change-Id: I89b35bee08f9bc9e37f902f2b57e02acb2113ae1 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3726509 Reviewed-by: Rohit Rao <rohitrao@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Justin Cohen <justincohen@chromium.org>
This commit is contained in:
parent
80f383327e
commit
bac699ef47
2
DEPS
2
DEPS
@ -44,7 +44,7 @@ deps = {
|
|||||||
'e1e7b0ad8ee99a875b272c8e33e308472e897660',
|
'e1e7b0ad8ee99a875b272c8e33e308472e897660',
|
||||||
'crashpad/third_party/mini_chromium/mini_chromium':
|
'crashpad/third_party/mini_chromium/mini_chromium':
|
||||||
Var('chromium_git') + '/chromium/mini_chromium@' +
|
Var('chromium_git') + '/chromium/mini_chromium@' +
|
||||||
'5654edb4225bcad13901155c819febb5748e502b',
|
'75dcb8dc417af77fdb9ec23c7b51cb1d57dfcee2',
|
||||||
'crashpad/third_party/libfuzzer/src':
|
'crashpad/third_party/libfuzzer/src':
|
||||||
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
|
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
|
||||||
'fda403cf93ecb8792cb1d061564d89a6553ca020',
|
'fda403cf93ecb8792cb1d061564d89a6553ca020',
|
||||||
|
@ -28,6 +28,7 @@ import copy
|
|||||||
import filecmp
|
import filecmp
|
||||||
import functools
|
import functools
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import io
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -65,7 +66,7 @@ class Template(string.Template):
|
|||||||
@functools.lru_cache
|
@functools.lru_cache
|
||||||
def LoadSchemeTemplate(root, name):
|
def LoadSchemeTemplate(root, name):
|
||||||
"""Return a string.Template object for scheme file loaded relative to root."""
|
"""Return a string.Template object for scheme file loaded relative to root."""
|
||||||
path = os.path.join(root, 'build', 'ios', name)
|
path = os.path.join(root, 'build', 'ios', name + '.template')
|
||||||
with open(path) as file:
|
with open(path) as file:
|
||||||
return Template(file.read())
|
return Template(file.read())
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ def CreateIdentifier(str_id):
|
|||||||
return hashlib.sha1(str_id.encode("utf-8")).hexdigest()[:24].upper()
|
return hashlib.sha1(str_id.encode("utf-8")).hexdigest()[:24].upper()
|
||||||
|
|
||||||
|
|
||||||
def GenerateSchemeForTarget(root, project, old_project, name, path, tests):
|
def GenerateSchemeForTarget(root, project, old_project, name, path, is_test):
|
||||||
"""Generates the .xcsheme file for target named |name|.
|
"""Generates the .xcsheme file for target named |name|.
|
||||||
|
|
||||||
The file is generated in the new project schemes directory from a template.
|
The file is generated in the new project schemes directory from a template.
|
||||||
@ -91,9 +92,23 @@ def GenerateSchemeForTarget(root, project, old_project, name, path, tests):
|
|||||||
if not os.path.isdir(os.path.dirname(scheme_path)):
|
if not os.path.isdir(os.path.dirname(scheme_path)):
|
||||||
os.makedirs(os.path.dirname(scheme_path))
|
os.makedirs(os.path.dirname(scheme_path))
|
||||||
|
|
||||||
|
substitutions = {
|
||||||
|
'LLDBINIT_PATH': LLDBINIT_PATH,
|
||||||
|
'BLUEPRINT_IDENTIFIER': identifier,
|
||||||
|
'BUILDABLE_NAME': path,
|
||||||
|
'BLUEPRINT_NAME': name,
|
||||||
|
'PROJECT_NAME': project_name
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_test:
|
||||||
|
template = LoadSchemeTemplate(root, 'xcodescheme-testable')
|
||||||
|
substitutions['PATH'] = os.environ['PATH']
|
||||||
|
|
||||||
|
else:
|
||||||
|
template = LoadSchemeTemplate(root, 'xcodescheme')
|
||||||
|
|
||||||
old_scheme_path = os.path.join(old_project, relative_path)
|
old_scheme_path = os.path.join(old_project, relative_path)
|
||||||
if os.path.exists(old_scheme_path):
|
if os.path.exists(old_scheme_path):
|
||||||
made_changes = False
|
|
||||||
|
|
||||||
tree = xml.etree.ElementTree.parse(old_scheme_path)
|
tree = xml.etree.ElementTree.parse(old_scheme_path)
|
||||||
tree_root = tree.getroot()
|
tree_root = tree.getroot()
|
||||||
@ -105,7 +120,6 @@ def GenerateSchemeForTarget(root, project, old_project, name, path, tests):
|
|||||||
('BlueprintIdentifier', identifier)):
|
('BlueprintIdentifier', identifier)):
|
||||||
if reference.get(attr) != value:
|
if reference.get(attr) != value:
|
||||||
reference.set(attr, value)
|
reference.set(attr, value)
|
||||||
made_changes = True
|
|
||||||
|
|
||||||
for child in tree_root:
|
for child in tree_root:
|
||||||
if child.tag not in ('TestAction', 'LaunchAction'):
|
if child.tag not in ('TestAction', 'LaunchAction'):
|
||||||
@ -113,59 +127,29 @@ def GenerateSchemeForTarget(root, project, old_project, name, path, tests):
|
|||||||
|
|
||||||
if child.get('customLLDBInitFile') != LLDBINIT_PATH:
|
if child.get('customLLDBInitFile') != LLDBINIT_PATH:
|
||||||
child.set('customLLDBInitFile', LLDBINIT_PATH)
|
child.set('customLLDBInitFile', LLDBINIT_PATH)
|
||||||
made_changes = True
|
|
||||||
|
|
||||||
# Override the list of testables.
|
if is_test:
|
||||||
if child.tag == 'TestAction':
|
|
||||||
for subchild in child:
|
|
||||||
if subchild.tag != 'Testables':
|
|
||||||
continue
|
|
||||||
|
|
||||||
for elt in list(subchild):
|
template_tree = xml.etree.ElementTree.parse(
|
||||||
subchild.remove(elt)
|
io.StringIO(template.substitute(**substitutions)))
|
||||||
|
|
||||||
if tests:
|
template_tree_root = template_tree.getroot()
|
||||||
template = LoadSchemeTemplate(root, 'xcodescheme-testable.template')
|
for child in tree_root:
|
||||||
for (key, test_path, test_name) in sorted(tests):
|
if child.tag != 'BuildAction':
|
||||||
testable = ''.join(template.substitute(
|
continue
|
||||||
BLUEPRINT_IDENTIFIER=key,
|
|
||||||
BUILDABLE_NAME=test_path,
|
|
||||||
BLUEPRINT_NAME=test_name,
|
|
||||||
PROJECT_NAME=project_name))
|
|
||||||
|
|
||||||
testable_elt = xml.etree.ElementTree.fromstring(testable)
|
for subchild in list(child):
|
||||||
subchild.append(testable_elt)
|
child.remove(subchild)
|
||||||
|
|
||||||
if made_changes:
|
for post_action in template_tree_root.findall('.//PostActions'):
|
||||||
tree.write(scheme_path, xml_declaration=True, encoding='UTF-8')
|
child.append(post_action)
|
||||||
|
|
||||||
else:
|
tree.write(scheme_path, xml_declaration=True, encoding='UTF-8')
|
||||||
shutil.copyfile(old_scheme_path, scheme_path)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
testables = ''
|
|
||||||
if tests:
|
|
||||||
template = LoadSchemeTemplate(root, 'xcodescheme-testable.template')
|
|
||||||
testables = '\n' + ''.join(
|
|
||||||
template.substitute(
|
|
||||||
BLUEPRINT_IDENTIFIER=key,
|
|
||||||
BUILDABLE_NAME=test_path,
|
|
||||||
BLUEPRINT_NAME=test_name,
|
|
||||||
PROJECT_NAME=project_name)
|
|
||||||
for (key, test_path, test_name) in sorted(tests)).rstrip()
|
|
||||||
|
|
||||||
template = LoadSchemeTemplate(root, 'xcodescheme.template')
|
|
||||||
|
|
||||||
with open(scheme_path, 'w') as scheme_file:
|
with open(scheme_path, 'w') as scheme_file:
|
||||||
scheme_file.write(
|
scheme_file.write(template.substitute(**substitutions))
|
||||||
template.substitute(
|
|
||||||
TESTABLES=testables,
|
|
||||||
LLDBINIT_PATH=LLDBINIT_PATH,
|
|
||||||
BLUEPRINT_IDENTIFIER=identifier,
|
|
||||||
BUILDABLE_NAME=path,
|
|
||||||
BLUEPRINT_NAME=name,
|
|
||||||
PROJECT_NAME=project_name))
|
|
||||||
|
|
||||||
|
|
||||||
class XcodeProject(object):
|
class XcodeProject(object):
|
||||||
@ -225,6 +209,7 @@ class XcodeProject(object):
|
|||||||
# because objects will be added to/removed from the project upon
|
# because objects will be added to/removed from the project upon
|
||||||
# iterating this list and python dictionaries cannot be mutated
|
# iterating this list and python dictionaries cannot be mutated
|
||||||
# during iteration.
|
# during iteration.
|
||||||
|
|
||||||
for key, obj in list(self.IterObjectsByIsa('XCConfigurationList')):
|
for key, obj in list(self.IterObjectsByIsa('XCConfigurationList')):
|
||||||
# Use the first build configuration as template for creating all the
|
# Use the first build configuration as template for creating all the
|
||||||
# new build configurations.
|
# new build configurations.
|
||||||
@ -232,7 +217,6 @@ class XcodeProject(object):
|
|||||||
build_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \
|
build_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \
|
||||||
'$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
|
'$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
|
||||||
|
|
||||||
|
|
||||||
# Remove the existing build configurations from the project before
|
# Remove the existing build configurations from the project before
|
||||||
# creating the new ones.
|
# creating the new ones.
|
||||||
for build_config_id in obj['buildConfigurations']:
|
for build_config_id in obj['buildConfigurations']:
|
||||||
@ -342,48 +326,56 @@ def UpdateXcodeProject(project_dir, old_project_dir, configurations, root_dir):
|
|||||||
product = project.objects[obj['productReference']]
|
product = project.objects[obj['productReference']]
|
||||||
product_path = product['path']
|
product_path = product['path']
|
||||||
|
|
||||||
# For XCTests, the key is the product path, while for XCUITests, the key
|
# Do not generate scheme for the XCTests and XXCUITests target app.
|
||||||
# is the target name. Use a sum of both possible keys (there should not
|
# Instead, a scheme will be generated for each test modules.
|
||||||
# be overlaps since different hosts are used for XCTests and XCUITests
|
|
||||||
# but this make the code simpler).
|
|
||||||
tests = mapping.get(product_path, []) + mapping.get(obj['name'], [])
|
tests = mapping.get(product_path, []) + mapping.get(obj['name'], [])
|
||||||
GenerateSchemeForTarget(
|
if not tests:
|
||||||
root_dir, project_dir, old_project_dir,
|
GenerateSchemeForTarget(
|
||||||
obj['name'], product_path, tests)
|
root_dir, project_dir, old_project_dir,
|
||||||
|
obj['name'], product_path, False)
|
||||||
|
|
||||||
|
else:
|
||||||
|
for (_, test_name, test_path) in tests:
|
||||||
|
GenerateSchemeForTarget(
|
||||||
|
root_dir, project_dir, old_project_dir,
|
||||||
|
test_name, test_path, True)
|
||||||
|
|
||||||
source = GetOrCreateRootGroup(project, json_data['rootObject'], 'Source')
|
root_object = project.objects[json_data['rootObject']]
|
||||||
AddMarkdownToProject(project, root_dir, source)
|
main_group = project.objects[root_object['mainGroup']]
|
||||||
SortFileReferencesByName(project, source)
|
|
||||||
|
sources = None
|
||||||
|
for child_key in main_group['children']:
|
||||||
|
child = project.objects[child_key]
|
||||||
|
if child.get('name') == 'Source' or child.get('name') == 'Sources':
|
||||||
|
sources = child
|
||||||
|
break
|
||||||
|
|
||||||
|
if sources is None:
|
||||||
|
sources = main_group
|
||||||
|
|
||||||
|
AddMarkdownToProject(project, root_dir, sources, sources is main_group)
|
||||||
|
SortFileReferencesByName(project, sources, root_object.get('productRefGroup'))
|
||||||
|
|
||||||
objects = collections.OrderedDict(sorted(project.objects.items()))
|
objects = collections.OrderedDict(sorted(project.objects.items()))
|
||||||
WriteXcodeProject(project_dir, json.dumps(json_data))
|
# WriteXcodeProject(project_dir, json.dumps(json_data))
|
||||||
|
|
||||||
|
|
||||||
def CreateGroup(project, parent_group, group_name, path=None):
|
def CreateGroup(project, parent_group, group_name, use_relative_paths):
|
||||||
group_object = {
|
group_object = {
|
||||||
'children': [],
|
'children': [],
|
||||||
'isa': 'PBXGroup',
|
'isa': 'PBXGroup',
|
||||||
'name': group_name,
|
|
||||||
'sourceTree': '<group>',
|
'sourceTree': '<group>',
|
||||||
}
|
}
|
||||||
if path is not None:
|
if use_relative_paths:
|
||||||
group_object['path'] = path
|
group_object['path'] = group_name
|
||||||
|
else:
|
||||||
|
group_object['name'] = group_name
|
||||||
parent_group_name = parent_group.get('name', '')
|
parent_group_name = parent_group.get('name', '')
|
||||||
group_object_key = project.AddObject(parent_group_name, group_object)
|
group_object_key = project.AddObject(parent_group_name, group_object)
|
||||||
parent_group['children'].append(group_object_key)
|
parent_group['children'].append(group_object_key)
|
||||||
return group_object
|
return group_object
|
||||||
|
|
||||||
|
|
||||||
def GetOrCreateRootGroup(project, root_object, group_name):
|
|
||||||
main_group = project.objects[project.objects[root_object]['mainGroup']]
|
|
||||||
for child_key in main_group['children']:
|
|
||||||
child = project.objects[child_key]
|
|
||||||
if child['name'] == group_name:
|
|
||||||
return child
|
|
||||||
return CreateGroup(project, main_group, group_name, path='../..')
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectKey(object):
|
class ObjectKey(object):
|
||||||
|
|
||||||
"""Wrapper around PBXFileReference and PBXGroup for sorting.
|
"""Wrapper around PBXFileReference and PBXGroup for sorting.
|
||||||
@ -401,19 +393,24 @@ class ObjectKey(object):
|
|||||||
is checked and compared in alphabetic order.
|
is checked and compared in alphabetic order.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj, last):
|
||||||
self.isa = obj['isa']
|
self.isa = obj['isa']
|
||||||
if 'name' in obj:
|
if 'name' in obj:
|
||||||
self.name = obj['name']
|
self.name = obj['name']
|
||||||
else:
|
else:
|
||||||
self.name = obj['path']
|
self.name = obj['path']
|
||||||
|
self.last = last
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
|
if self.last != other.last:
|
||||||
|
return other.last
|
||||||
if self.isa != other.isa:
|
if self.isa != other.isa:
|
||||||
return self.isa > other.isa
|
return self.isa > other.isa
|
||||||
return self.name < other.name
|
return self.name < other.name
|
||||||
|
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
|
if self.last != other.last:
|
||||||
|
return self.last
|
||||||
if self.isa != other.isa:
|
if self.isa != other.isa:
|
||||||
return self.isa < other.isa
|
return self.isa < other.isa
|
||||||
return self.name > other.name
|
return self.name > other.name
|
||||||
@ -422,9 +419,10 @@ class ObjectKey(object):
|
|||||||
return self.isa == other.isa and self.name == other.name
|
return self.isa == other.isa and self.name == other.name
|
||||||
|
|
||||||
|
|
||||||
def SortFileReferencesByName(project, group_object):
|
def SortFileReferencesByName(project, group_object, products_group_ref):
|
||||||
SortFileReferencesByNameWithSortKey(
|
SortFileReferencesByNameWithSortKey(
|
||||||
project, group_object, lambda ref: ObjectKey(project.objects[ref]))
|
project, group_object,
|
||||||
|
lambda ref: ObjectKey(project.objects[ref], ref == products_group_ref))
|
||||||
|
|
||||||
|
|
||||||
def SortFileReferencesByNameWithSortKey(project, group_object, sort_key):
|
def SortFileReferencesByNameWithSortKey(project, group_object, sort_key):
|
||||||
@ -435,7 +433,7 @@ def SortFileReferencesByNameWithSortKey(project, group_object, sort_key):
|
|||||||
SortFileReferencesByNameWithSortKey(project, child, sort_key)
|
SortFileReferencesByNameWithSortKey(project, child, sort_key)
|
||||||
|
|
||||||
|
|
||||||
def AddMarkdownToProject(project, root_dir, group_object):
|
def AddMarkdownToProject(project, root_dir, group_object, use_relative_paths):
|
||||||
list_files_cmd = ['git', '-C', root_dir, 'ls-files', '*.md']
|
list_files_cmd = ['git', '-C', root_dir, 'ls-files', '*.md']
|
||||||
paths = check_output(list_files_cmd).splitlines()
|
paths = check_output(list_files_cmd).splitlines()
|
||||||
ios_internal_dir = os.path.join(root_dir, 'ios_internal')
|
ios_internal_dir = os.path.join(root_dir, 'ios_internal')
|
||||||
@ -448,31 +446,43 @@ def AddMarkdownToProject(project, root_dir, group_object):
|
|||||||
"fileEncoding": "4",
|
"fileEncoding": "4",
|
||||||
"isa": "PBXFileReference",
|
"isa": "PBXFileReference",
|
||||||
"lastKnownFileType": "net.daringfireball.markdown",
|
"lastKnownFileType": "net.daringfireball.markdown",
|
||||||
"name": os.path.basename(path),
|
|
||||||
"path": path,
|
|
||||||
"sourceTree": "<group>"
|
"sourceTree": "<group>"
|
||||||
}
|
}
|
||||||
new_markdown_entry_id = project.AddObject('sources', new_markdown_entry)
|
if use_relative_paths:
|
||||||
folder = GetFolderForPath(project, group_object, os.path.dirname(path))
|
new_markdown_entry['path'] = os.path.basename(path)
|
||||||
|
else:
|
||||||
|
new_markdown_entry['name'] = os.path.basename(path)
|
||||||
|
new_markdown_entry['path'] = path
|
||||||
|
folder = GetFolderForPath(
|
||||||
|
project, group_object, os.path.dirname(path),
|
||||||
|
use_relative_paths)
|
||||||
|
folder_name = folder.get('name', None)
|
||||||
|
if folder_name is None:
|
||||||
|
folder_name = folder.get('path', 'sources')
|
||||||
|
new_markdown_entry_id = project.AddObject(folder_name, new_markdown_entry)
|
||||||
folder['children'].append(new_markdown_entry_id)
|
folder['children'].append(new_markdown_entry_id)
|
||||||
|
|
||||||
|
|
||||||
def GetFolderForPath(project, group_object, path):
|
def GetFolderForPath(project, group_object, path, use_relative_paths):
|
||||||
objects = project.objects
|
objects = project.objects
|
||||||
if not path:
|
if not path:
|
||||||
return group_object
|
return group_object
|
||||||
for folder in path.split('/'):
|
for folder in path.split('/'):
|
||||||
children = group_object['children']
|
children = group_object['children']
|
||||||
new_root = None
|
new_root = None
|
||||||
for child in children:
|
for child_key in children:
|
||||||
if objects[child]['isa'] == 'PBXGroup' and \
|
child = objects[child_key]
|
||||||
objects[child]['name'] == folder:
|
if child['isa'] == 'PBXGroup':
|
||||||
new_root = objects[child]
|
child_name = child.get('name', None)
|
||||||
break
|
if child_name is None:
|
||||||
|
child_name = child.get('path')
|
||||||
|
if child_name == folder:
|
||||||
|
new_root = child
|
||||||
|
break
|
||||||
if not new_root:
|
if not new_root:
|
||||||
# If the folder isn't found we could just cram it into the leaf existing
|
# If the folder isn't found we could just cram it into the leaf existing
|
||||||
# folder, but that leads to folders with tons of README.md inside.
|
# folder, but that leads to folders with tons of README.md inside.
|
||||||
new_root = CreateGroup(project, group_object, folder)
|
new_root = CreateGroup(project, group_object, folder, use_relative_paths)
|
||||||
group_object = new_root
|
group_object = new_root
|
||||||
return group_object
|
return group_object
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class GnGenerator(object):
|
|||||||
self._config = config
|
self._config = config
|
||||||
self._target = target
|
self._target = target
|
||||||
|
|
||||||
def _GetGnArgs(self, extra_args=None):
|
def _GetGnArgs(self):
|
||||||
"""Build the list of arguments to pass to gn.
|
"""Build the list of arguments to pass to gn.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -134,11 +134,6 @@ class GnGenerator(object):
|
|||||||
'target_environment',
|
'target_environment',
|
||||||
self.TARGET_ENVIRONMENT_VALUES[self._target]))
|
self.TARGET_ENVIRONMENT_VALUES[self._target]))
|
||||||
|
|
||||||
# If extra arguments are passed to the function, pass them before the
|
|
||||||
# user overrides (if any).
|
|
||||||
if extra_args is not None:
|
|
||||||
args.extend(extra_args)
|
|
||||||
|
|
||||||
# Add user overrides after the other configurations so that they can
|
# Add user overrides after the other configurations so that they can
|
||||||
# refer to them and override them.
|
# refer to them and override them.
|
||||||
args.extend(self._settings.items('gn_args'))
|
args.extend(self._settings.items('gn_args'))
|
||||||
@ -218,6 +213,10 @@ class GnGenerator(object):
|
|||||||
gn_command.append('--ninja-executable=autoninja')
|
gn_command.append('--ninja-executable=autoninja')
|
||||||
gn_command.append('--xcode-build-system=new')
|
gn_command.append('--xcode-build-system=new')
|
||||||
gn_command.append('--xcode-project=%s' % xcode_project_name)
|
gn_command.append('--xcode-project=%s' % xcode_project_name)
|
||||||
|
gn_command.append('--xcode-additional-files-patterns=*.md')
|
||||||
|
gn_command.append('--xcode-configs=' + ';'.join(SUPPORTED_CONFIGS))
|
||||||
|
gn_command.append('--xcode-config-build-dir='
|
||||||
|
'//out/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}')
|
||||||
if self._settings.has_section('filters'):
|
if self._settings.has_section('filters'):
|
||||||
target_filters = self._settings.values('filters')
|
target_filters = self._settings.values('filters')
|
||||||
if target_filters:
|
if target_filters:
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1220"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<PostActions>
|
||||||
|
<ExecutionAction
|
||||||
|
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
|
||||||
|
<ActionContent
|
||||||
|
title = "Resign test runner"
|
||||||
|
scriptText = "unset -v XCODE_DEVELOPER_DIR_PATH BUILDDIR="${PROJECT_DIR}/../${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}" export PATH="@{PATH}" rm -rf "${BUILDDIR}/@{BLUEPRINT_NAME}-Runner.app" autoninja -C "${BUILDDIR}" "@{BLUEPRINT_NAME}" "
|
||||||
|
shellToInvoke = "/bin/sh">
|
||||||
|
<EnvironmentBuildable>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "@{BLUEPRINT_IDENTIFIER}"
|
||||||
|
BuildableName = "@{BUILDABLE_NAME}"
|
||||||
|
BlueprintName = "@{BLUEPRINT_NAME}"
|
||||||
|
ReferencedContainer = "container:@{PROJECT_NAME}">
|
||||||
|
</BuildableReference>
|
||||||
|
</EnvironmentBuildable>
|
||||||
|
</ActionContent>
|
||||||
|
</ExecutionAction>
|
||||||
|
</PostActions>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
customLLDBInitFile = "@{LLDBINIT_PATH}"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
<TestableReference
|
<TestableReference
|
||||||
skipped = "NO">
|
skipped = "NO">
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
@ -8,3 +42,32 @@
|
|||||||
ReferencedContainer = "container:@{PROJECT_NAME}">
|
ReferencedContainer = "container:@{PROJECT_NAME}">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</TestableReference>
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
customLLDBInitFile = "@{LLDBINIT_PATH}"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Profile"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Official"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
customLLDBInitFile = "@{LLDBINIT_PATH}"
|
customLLDBInitFile = "@{LLDBINIT_PATH}"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>@{TESTABLES}
|
|
||||||
</Testables>
|
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user