cocoapods 1.8.4 → 1.9.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +69 -1
- data/lib/cocoapods.rb +1 -0
- data/lib/cocoapods/command/setup.rb +1 -0
- data/lib/cocoapods/executable.rb +1 -1
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/embed_frameworks_script.rb +36 -6
- data/lib/cocoapods/generator/prepare_artifacts_script.rb +244 -0
- data/lib/cocoapods/installer.rb +6 -5
- data/lib/cocoapods/installer/analyzer.rb +137 -59
- data/lib/cocoapods/installer/analyzer/pod_variant.rb +27 -12
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +11 -2
- data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +10 -2
- data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +15 -2
- data/lib/cocoapods/installer/project_cache/target_cache_key.rb +7 -5
- data/lib/cocoapods/installer/user_project_integrator.rb +1 -10
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +100 -19
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +3 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +29 -4
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +7 -2
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +106 -45
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +68 -1
- data/lib/cocoapods/installer/xcode/pods_project_generator/pods_project_writer.rb +29 -14
- data/lib/cocoapods/sandbox/file_accessor.rb +32 -21
- data/lib/cocoapods/sources_manager.rb +9 -2
- data/lib/cocoapods/target.rb +11 -14
- data/lib/cocoapods/target/aggregate_target.rb +78 -18
- data/lib/cocoapods/target/build_settings.rb +64 -31
- data/lib/cocoapods/target/pod_target.rb +236 -87
- data/lib/cocoapods/user_interface/error_report.rb +14 -4
- data/lib/cocoapods/validator.rb +2 -0
- data/lib/cocoapods/xcode.rb +7 -0
- data/lib/cocoapods/{target → xcode}/framework_paths.rb +14 -1
- data/lib/cocoapods/xcode/linkage_analyzer.rb +22 -0
- data/lib/cocoapods/xcode/xcframework.rb +81 -0
- data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +51 -0
- metadata +12 -8
- data/lib/cocoapods/target/build_type.rb +0 -139
@@ -22,6 +22,10 @@ module Pod
|
|
22
22
|
#
|
23
23
|
attr_reader :project_object_version
|
24
24
|
|
25
|
+
# @return [Hash<String, Hash>] The podfile plugins to be run for the installation.
|
26
|
+
#
|
27
|
+
attr_reader :podfile_plugins
|
28
|
+
|
25
29
|
# @return [Array<PodTarget>] The list of pod targets.
|
26
30
|
#
|
27
31
|
attr_reader :pod_targets
|
@@ -40,15 +44,17 @@ module Pod
|
|
40
44
|
# @param [ProjectInstallationCache] cache @see #cache
|
41
45
|
# @param [Hash{String => Symbol}] build_configurations @see #build_configurations
|
42
46
|
# @param [Integer] project_object_version @see #project_object_version
|
47
|
+
# @param [Hash<String, Hash>] podfile_plugins @see #podfile_plugins
|
43
48
|
# @param [Array<PodTarget>] pod_targets @see #pod_targets
|
44
49
|
# @param [Array<AggregateTarget>] aggregate_targets @see #aggregate_targets
|
45
50
|
# @param [Bool] clean_install @see #clean_install
|
46
51
|
#
|
47
|
-
def initialize(sandbox, cache, build_configurations, project_object_version, pod_targets, aggregate_targets,
|
52
|
+
def initialize(sandbox, cache, build_configurations, project_object_version, podfile_plugins, pod_targets, aggregate_targets,
|
48
53
|
clean_install: false)
|
49
54
|
@sandbox = sandbox
|
50
55
|
@cache = cache
|
51
56
|
@build_configurations = build_configurations
|
57
|
+
@podfile_plugins = podfile_plugins
|
52
58
|
@pod_targets = pod_targets
|
53
59
|
@aggregate_targets = aggregate_targets
|
54
60
|
@project_object_version = project_object_version
|
@@ -70,7 +76,9 @@ module Pod
|
|
70
76
|
end
|
71
77
|
|
72
78
|
# Bail out early since these properties affect all targets and their associate projects.
|
73
|
-
if cache.build_configurations != build_configurations ||
|
79
|
+
if cache.build_configurations != build_configurations ||
|
80
|
+
cache.project_object_version != project_object_version ||
|
81
|
+
YAMLHelper.convert(cache.podfile_plugins) != YAMLHelper.convert(podfile_plugins)
|
74
82
|
UI.message 'Ignoring project cache due to project configuration changes.'
|
75
83
|
return full_install_results
|
76
84
|
end
|
@@ -21,16 +21,23 @@ module Pod
|
|
21
21
|
#
|
22
22
|
attr_reader :project_object_version
|
23
23
|
|
24
|
+
# @return [Hash<String, Hash>]
|
25
|
+
# Podfile plugins used with a particular install.
|
26
|
+
#
|
27
|
+
attr_reader :podfile_plugins
|
28
|
+
|
24
29
|
# Initializes a new instance.
|
25
30
|
#
|
26
31
|
# @param [Hash{String => TargetCacheKey}] cache_key_by_target_label @see #cache_key_by_target_label
|
27
32
|
# @param [Hash{String => Symbol}] build_configurations @see #build_configurations
|
28
33
|
# @param [Integer] project_object_version @see #project_object_version
|
34
|
+
# @param [Hash<String, Hash>] podfile_plugins @see #podfile_plugins
|
29
35
|
#
|
30
|
-
def initialize(cache_key_by_target_label = {}, build_configurations = nil, project_object_version = nil)
|
36
|
+
def initialize(cache_key_by_target_label = {}, build_configurations = nil, project_object_version = nil, podfile_plugins = {})
|
31
37
|
@cache_key_by_target_label = cache_key_by_target_label
|
32
38
|
@build_configurations = build_configurations
|
33
39
|
@project_object_version = project_object_version
|
40
|
+
@podfile_plugins = podfile_plugins
|
34
41
|
end
|
35
42
|
|
36
43
|
def update_cache_key_by_target_label!(cache_key_by_target_label)
|
@@ -45,6 +52,10 @@ module Pod
|
|
45
52
|
@project_object_version = project_object_version
|
46
53
|
end
|
47
54
|
|
55
|
+
def update_podfile_plugins!(podfile_plugins)
|
56
|
+
@podfile_plugins = podfile_plugins
|
57
|
+
end
|
58
|
+
|
48
59
|
def save_as(path)
|
49
60
|
Pathname(path).dirname.mkpath
|
50
61
|
Sandbox.update_changed_file(path, YAMLHelper.convert(to_hash))
|
@@ -59,7 +70,8 @@ module Pod
|
|
59
70
|
end]
|
60
71
|
project_object_version = contents['OBJECT_VERSION']
|
61
72
|
build_configurations = contents['BUILD_CONFIGURATIONS']
|
62
|
-
|
73
|
+
podfile_plugins = contents['PLUGINS']
|
74
|
+
ProjectInstallationCache.new(cache_key_by_target_label, build_configurations, project_object_version, podfile_plugins)
|
63
75
|
end
|
64
76
|
|
65
77
|
def to_hash
|
@@ -69,6 +81,7 @@ module Pod
|
|
69
81
|
contents = { 'CACHE_KEYS' => cache_key_contents }
|
70
82
|
contents['BUILD_CONFIGURATIONS'] = build_configurations if build_configurations
|
71
83
|
contents['OBJECT_VERSION'] = project_object_version if project_object_version
|
84
|
+
contents['PLUGINS'] = podfile_plugins if podfile_plugins
|
72
85
|
contents
|
73
86
|
end
|
74
87
|
end
|
@@ -116,12 +116,14 @@ module Pod
|
|
116
116
|
#
|
117
117
|
def self.from_pod_target(sandbox, pod_target, is_local_pod: false, checkout_options: nil)
|
118
118
|
build_settings = {}
|
119
|
-
build_settings[pod_target.label.to_s] =
|
120
|
-
|
121
|
-
|
119
|
+
build_settings[pod_target.label.to_s] = Hash[pod_target.build_settings.map do |k, v|
|
120
|
+
[k, Digest::MD5.hexdigest(v.xcconfig.to_s)]
|
121
|
+
end]
|
122
|
+
pod_target.test_spec_build_settings_by_config.each do |name, settings_by_config|
|
123
|
+
build_settings[name] = Hash[settings_by_config.map { |k, v| [k, Digest::MD5.hexdigest(v.xcconfig.to_s)] }]
|
122
124
|
end
|
123
|
-
pod_target.
|
124
|
-
build_settings[name] = Digest::MD5.hexdigest(
|
125
|
+
pod_target.app_spec_build_settings_by_config.each do |name, settings_by_config|
|
126
|
+
build_settings[name] = Hash[settings_by_config.map { |k, v| [k, Digest::MD5.hexdigest(v.xcconfig.to_s)] }]
|
125
127
|
end
|
126
128
|
|
127
129
|
contents = {
|
@@ -92,7 +92,7 @@ module Pod
|
|
92
92
|
# @return [void]
|
93
93
|
#
|
94
94
|
def create_workspace
|
95
|
-
all_projects =
|
95
|
+
all_projects = user_project_paths.sort.push(sandbox.project_path).uniq
|
96
96
|
file_references = all_projects.map do |path|
|
97
97
|
relative_path = path.relative_path_from(workspace_path.dirname).to_s
|
98
98
|
Xcodeproj::Workspace::FileReference.new(relative_path, 'group')
|
@@ -221,15 +221,6 @@ module Pod
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
|
224
|
-
# @return [Array<Pathname>] the paths of all the user projects referenced
|
225
|
-
# by the targets that require integration.
|
226
|
-
#
|
227
|
-
# @note Empty target definitions are ignored.
|
228
|
-
#
|
229
|
-
def user_project_paths_to_integrate
|
230
|
-
targets_to_integrate.map(&:user_project_path).compact.uniq
|
231
|
-
end
|
232
|
-
|
233
224
|
# @return [Array<Xcodeproj::Project>] the projects of all the targets that require integration.
|
234
225
|
#
|
235
226
|
# @note Empty target definitions are ignored.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/string/inflections'
|
2
|
-
require 'cocoapods/
|
2
|
+
require 'cocoapods/xcode/framework_paths'
|
3
3
|
|
4
4
|
module Pod
|
5
5
|
class Installer
|
@@ -37,6 +37,10 @@ module Pod
|
|
37
37
|
#
|
38
38
|
EMBED_FRAMEWORK_PHASE_NAME = 'Embed Pods Frameworks'.freeze
|
39
39
|
|
40
|
+
# @return [String] the name of the embed frameworks phase
|
41
|
+
#
|
42
|
+
PREPARE_ARTIFACTS_PHASE_NAME = 'Prepare Artifacts'.freeze
|
43
|
+
|
40
44
|
# @return [String] the name of the copy resources phase
|
41
45
|
#
|
42
46
|
COPY_PODS_RESOURCES_PHASE_NAME = 'Copy Pods Resources'.freeze
|
@@ -45,6 +49,10 @@ module Pod
|
|
45
49
|
#
|
46
50
|
MAX_INPUT_OUTPUT_PATHS = 1000
|
47
51
|
|
52
|
+
# @return [String] the path to the artifact lists file used in the prepare & embed scripts
|
53
|
+
#
|
54
|
+
ARTIFACT_LIST_FILE = '${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt'.freeze
|
55
|
+
|
48
56
|
# @return [AggregateTarget] the target that should be integrated.
|
49
57
|
#
|
50
58
|
attr_reader :target
|
@@ -135,15 +143,52 @@ module Pod
|
|
135
143
|
TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
|
136
144
|
end
|
137
145
|
|
146
|
+
# Adds a shell script build phase responsible to copy xcframeworks slices
|
147
|
+
# generated by the TargetDefinition to the build directory.
|
148
|
+
#
|
149
|
+
# @param [PBXNativeTarget] native_target
|
150
|
+
# The native target to add the script phase into.
|
151
|
+
#
|
152
|
+
# @param [String] script_path
|
153
|
+
# The script path to execute as part of this script phase.
|
154
|
+
#
|
155
|
+
# @param [Hash<Array, String>] input_paths_by_config
|
156
|
+
# The input paths (if any) to include for this script phase.
|
157
|
+
#
|
158
|
+
# @param [Hash<Array, String>] output_paths_by_config
|
159
|
+
# The output paths (if any) to include for this script phase.
|
160
|
+
#
|
161
|
+
# @return [void]
|
162
|
+
#
|
163
|
+
def create_or_update_prepare_artifacts_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {})
|
164
|
+
phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + PREPARE_ARTIFACTS_PHASE_NAME)
|
165
|
+
phase.shell_script = %("#{script_path}"\n)
|
166
|
+
reorder_script_phase(native_target, phase, :before_compile)
|
167
|
+
TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
|
168
|
+
end
|
169
|
+
|
138
170
|
# Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present
|
139
171
|
#
|
140
172
|
# @param [PBXNativeTarget] native_target
|
141
173
|
# The native target to remove the script phase from.
|
142
174
|
#
|
143
175
|
def remove_embed_frameworks_script_phase_from_target(native_target)
|
144
|
-
|
145
|
-
|
146
|
-
|
176
|
+
remove_script_phase_from_target(native_target, EMBED_FRAMEWORK_PHASE_NAME)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present
|
180
|
+
#
|
181
|
+
# @param [PBXNativeTarget] native_target
|
182
|
+
# The native target to remove the script phase from.
|
183
|
+
#
|
184
|
+
def remove_prepare_artifacts_script_phase_from_target(native_target)
|
185
|
+
remove_script_phase_from_target(native_target, PREPARE_ARTIFACTS_PHASE_NAME)
|
186
|
+
end
|
187
|
+
|
188
|
+
def remove_script_phase_from_target(native_target, phase_name)
|
189
|
+
build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(phase_name) }
|
190
|
+
return unless build_phase.present?
|
191
|
+
native_target.build_phases.delete(build_phase)
|
147
192
|
end
|
148
193
|
|
149
194
|
# Adds a shell script build phase responsible to copy the resources
|
@@ -235,6 +280,7 @@ module Pod
|
|
235
280
|
phase.output_paths = script_phase[:output_files]
|
236
281
|
phase.input_file_list_paths = script_phase[:input_file_lists]
|
237
282
|
phase.output_file_list_paths = script_phase[:output_file_lists]
|
283
|
+
phase.dependency_file = script_phase[:dependency_file]
|
238
284
|
# At least with Xcode 10 `showEnvVarsInLog` is *NOT* set to any value even if it's checked and it only
|
239
285
|
# gets set to '0' if the user has explicitly disabled this.
|
240
286
|
if (show_env_vars_in_log = script_phase.fetch(:show_env_vars_in_log, '1')) == '0'
|
@@ -242,19 +288,22 @@ module Pod
|
|
242
288
|
end
|
243
289
|
|
244
290
|
execution_position = script_phase[:execution_position]
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
291
|
+
reorder_script_phase(native_target, phase, execution_position)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def reorder_script_phase(native_target, script_phase, execution_position)
|
296
|
+
return if execution_position == :any
|
297
|
+
compile_build_phase_index = native_target.build_phases.index do |bp|
|
298
|
+
bp.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase)
|
299
|
+
end
|
300
|
+
unless compile_build_phase_index.nil?
|
301
|
+
script_phase_index = native_target.build_phases.index do |bp|
|
302
|
+
bp.is_a?(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) && !bp.name.nil? && bp.name == script_phase.name
|
303
|
+
end
|
304
|
+
if (execution_position == :before_compile && script_phase_index > compile_build_phase_index) ||
|
305
|
+
(execution_position == :after_compile && script_phase_index < compile_build_phase_index)
|
306
|
+
native_target.build_phases.move_from(script_phase_index, compile_build_phase_index)
|
258
307
|
end
|
259
308
|
end
|
260
309
|
end
|
@@ -318,7 +367,7 @@ module Pod
|
|
318
367
|
|
319
368
|
# Returns the framework output paths for the given input paths
|
320
369
|
#
|
321
|
-
# @param [Array<
|
370
|
+
# @param [Array<Xcode::FrameworkPaths>] framework_input_paths
|
322
371
|
# The framework input paths to map to output paths.
|
323
372
|
#
|
324
373
|
# @return [Array<String>] The framework output paths
|
@@ -351,6 +400,7 @@ module Pod
|
|
351
400
|
|
352
401
|
add_pods_library
|
353
402
|
add_embed_frameworks_script_phase
|
403
|
+
add_prepare_artifacts_script_phase
|
354
404
|
remove_embed_frameworks_script_phase_from_embedded_targets
|
355
405
|
add_copy_resources_script_phase
|
356
406
|
add_check_manifest_lock_script_phase
|
@@ -454,7 +504,7 @@ module Pod
|
|
454
504
|
# @return [void]
|
455
505
|
#
|
456
506
|
def add_embed_frameworks_script_phase
|
457
|
-
unless target.includes_frameworks?
|
507
|
+
unless target.includes_frameworks? || target.includes_xcframeworks?
|
458
508
|
native_targets_to_embed_in.each do |native_target|
|
459
509
|
TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
|
460
510
|
end
|
@@ -468,6 +518,7 @@ module Pod
|
|
468
518
|
target.framework_paths_by_config.each do |config, framework_paths|
|
469
519
|
input_paths_key = XCFileListConfigKey.new(target.embed_frameworks_script_input_files_path(config), target.embed_frameworks_script_input_files_relative_path)
|
470
520
|
input_paths = input_paths_by_config[input_paths_key] = [script_path]
|
521
|
+
input_paths << ARTIFACT_LIST_FILE if target.includes_xcframeworks?
|
471
522
|
framework_paths.each do |path|
|
472
523
|
input_paths.concat(path.all_paths)
|
473
524
|
end
|
@@ -482,6 +533,36 @@ module Pod
|
|
482
533
|
end
|
483
534
|
end
|
484
535
|
|
536
|
+
# Find or create a 'Prepare Artifacts' Copy Files Build Phase
|
537
|
+
#
|
538
|
+
# @return [void]
|
539
|
+
#
|
540
|
+
def add_prepare_artifacts_script_phase
|
541
|
+
unless target.includes_xcframeworks?
|
542
|
+
native_targets_to_embed_in.each do |native_target|
|
543
|
+
TargetIntegrator.remove_prepare_artifacts_script_phase_from_target(native_target)
|
544
|
+
end
|
545
|
+
return
|
546
|
+
end
|
547
|
+
|
548
|
+
script_path = target.prepare_artifacts_script_relative_path
|
549
|
+
input_paths_by_config = {}
|
550
|
+
output_paths_by_config = {}
|
551
|
+
if use_input_output_paths?
|
552
|
+
target.xcframeworks_by_config.each do |config, xcframeworks|
|
553
|
+
input_paths_key = XCFileListConfigKey.new(target.prepare_artifacts_script_input_files_path(config), target.prepare_artifacts_script_input_files_relative_path)
|
554
|
+
input_paths = input_paths_by_config[input_paths_key] = [script_path]
|
555
|
+
input_paths.concat(xcframeworks.map { |xcf| "${PODS_ROOT}/#{xcf.path.relative_path_from(target.sandbox.root)}" })
|
556
|
+
|
557
|
+
output_paths_key = XCFileListConfigKey.new(target.prepare_artifacts_script_output_files_path(config), target.prepare_artifacts_script_output_files_relative_path)
|
558
|
+
output_paths_by_config[output_paths_key] = [ARTIFACT_LIST_FILE]
|
559
|
+
end
|
560
|
+
end
|
561
|
+
native_targets_to_embed_in.each do |native_target|
|
562
|
+
TargetIntegrator.create_or_update_prepare_artifacts_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config)
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
485
566
|
# Updates all target script phases for the current target, including creating or updating, deleting
|
486
567
|
# and re-ordering.
|
487
568
|
#
|
@@ -238,6 +238,9 @@ module Pod
|
|
238
238
|
environment_variables.assign_variable(:key => k, :value => v)
|
239
239
|
end
|
240
240
|
scheme.launch_action.environment_variables = environment_variables
|
241
|
+
if scheme_configuration.key?(:code_coverage)
|
242
|
+
scheme.test_action.code_coverage_enabled = scheme_configuration[:code_coverage]
|
243
|
+
end
|
241
244
|
scheme.save!
|
242
245
|
end
|
243
246
|
Xcodeproj::XCScheme.share_scheme(project.path, scheme_name) if share_scheme
|
@@ -16,7 +16,7 @@ module Pod
|
|
16
16
|
create_support_files_dir
|
17
17
|
create_support_files_group
|
18
18
|
create_xcconfig_file(native_target)
|
19
|
-
if target.
|
19
|
+
if target.build_as_framework?
|
20
20
|
create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
|
21
21
|
create_module_map(native_target)
|
22
22
|
create_umbrella_header(native_target)
|
@@ -30,7 +30,8 @@ module Pod
|
|
30
30
|
# cause an App Store rejection because frameworks cannot be
|
31
31
|
# embedded in embedded targets.
|
32
32
|
#
|
33
|
-
create_embed_frameworks_script if target.includes_frameworks? && !target.requires_host_target?
|
33
|
+
create_embed_frameworks_script if (target.includes_frameworks? || target.includes_xcframeworks?) && !target.requires_host_target?
|
34
|
+
create_prepare_artifacts_script if target.includes_xcframeworks? && !target.requires_host_target?
|
34
35
|
create_bridge_support_file(native_target)
|
35
36
|
create_copy_resources_script if target.includes_resources?
|
36
37
|
create_acknowledgements
|
@@ -145,8 +146,8 @@ module Pod
|
|
145
146
|
# Creates a script that embeds the frameworks to the bundle of the client
|
146
147
|
# target.
|
147
148
|
#
|
148
|
-
# @note We can't use Xcode default
|
149
|
-
# we need to ensure that we only copy the
|
149
|
+
# @note We can't use Xcode default link libraries phase, because
|
150
|
+
# we need to ensure that we only copy the frameworks which are
|
150
151
|
# relevant for the current build configuration.
|
151
152
|
#
|
152
153
|
# @return [void]
|
@@ -158,6 +159,30 @@ module Pod
|
|
158
159
|
add_file_to_support_group(path)
|
159
160
|
end
|
160
161
|
|
162
|
+
# Creates a script that prepares artifacts for embedding into a host target.
|
163
|
+
#
|
164
|
+
# @note We can't use Xcode default link libraries phase, because
|
165
|
+
# we need to ensure that we only copy the frameworks which are
|
166
|
+
# relevant for the current build configuration.
|
167
|
+
#
|
168
|
+
# @return [void]
|
169
|
+
#
|
170
|
+
def create_prepare_artifacts_script
|
171
|
+
path = target.prepare_artifacts_script_path
|
172
|
+
generator = Generator::PrepareArtifactsScript.new(target.xcframeworks_by_config, sandbox.root, target.platform)
|
173
|
+
update_changed_file(generator, path)
|
174
|
+
add_file_to_support_group(path)
|
175
|
+
|
176
|
+
target.user_build_configurations.each_key do |config|
|
177
|
+
if (input_file_list = target.prepare_artifacts_script_input_files_path(config))
|
178
|
+
add_file_to_support_group(input_file_list)
|
179
|
+
end
|
180
|
+
if (output_file_list = target.prepare_artifacts_script_output_files_path(config))
|
181
|
+
add_file_to_support_group(output_file_list)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
161
186
|
# Generates the acknowledgement files (markdown and plist) for the target.
|
162
187
|
#
|
163
188
|
# @return [void]
|
@@ -37,6 +37,10 @@ module Pod
|
|
37
37
|
#
|
38
38
|
attr_reader :add_main
|
39
39
|
|
40
|
+
# @return [Boolean] whether the app host installer should add a launch screen storyboard
|
41
|
+
#
|
42
|
+
attr_reader :add_launchscreen_storyboard
|
43
|
+
|
40
44
|
# @return [Hash] Info.plist entries for the app host
|
41
45
|
#
|
42
46
|
attr_reader :info_plist_entries
|
@@ -52,7 +56,7 @@ module Pod
|
|
52
56
|
# @param [Boolean] add_main see #add_main
|
53
57
|
# @param [Hash] info_plist_entries see #info_plist_entries
|
54
58
|
#
|
55
|
-
def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true, info_plist_entries: {})
|
59
|
+
def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true, add_launchscreen_storyboard: platform == :ios, info_plist_entries: {})
|
56
60
|
@sandbox = sandbox
|
57
61
|
@project = project
|
58
62
|
@platform = platform
|
@@ -60,6 +64,7 @@ module Pod
|
|
60
64
|
@group_name = group_name
|
61
65
|
@app_target_label = app_target_label
|
62
66
|
@add_main = add_main
|
67
|
+
@add_launchscreen_storyboard = add_launchscreen_storyboard
|
63
68
|
@info_plist_entries = info_plist_entries
|
64
69
|
target_group = project.pod_group(group_name)
|
65
70
|
@group = target_group[subgroup_name] || target_group.new_group(subgroup_name)
|
@@ -79,7 +84,7 @@ module Pod
|
|
79
84
|
end
|
80
85
|
|
81
86
|
Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, @group, app_target_label) if add_main
|
82
|
-
Pod::Generator::AppTargetHelper.add_launchscreen_storyboard(project, app_host_target, @group, deployment_target, app_target_label) if
|
87
|
+
Pod::Generator::AppTargetHelper.add_launchscreen_storyboard(project, app_host_target, @group, deployment_target, app_target_label) if add_launchscreen_storyboard
|
83
88
|
create_info_plist_file_with_sandbox(sandbox, app_host_info_plist_path, app_host_target, '1.0.0', platform,
|
84
89
|
:appl, :additional_entries => additional_info_plist_entries)
|
85
90
|
@group.new_file(app_host_info_plist_path)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'cocoapods/xcode'
|
2
|
+
|
1
3
|
module Pod
|
2
4
|
class Installer
|
3
5
|
class Xcode
|
@@ -56,6 +58,7 @@ module Pod
|
|
56
58
|
|
57
59
|
add_files_to_build_phases(native_target, test_native_targets, app_native_targets)
|
58
60
|
validate_targets_contain_sources(test_native_targets + app_native_targets + [native_target])
|
61
|
+
validate_xcframeworks_no_mixed_linkage
|
59
62
|
|
60
63
|
create_xcconfig_file(native_target, resource_bundle_targets)
|
61
64
|
create_test_xcconfig_files(test_native_targets, test_resource_bundle_targets)
|
@@ -69,7 +72,7 @@ module Pod
|
|
69
72
|
generator.imports += library_file_accessors.flat_map do |file_accessor|
|
70
73
|
header_dir = if !target.build_as_framework? && dir = file_accessor.spec_consumer.header_dir
|
71
74
|
Pathname.new(dir)
|
72
|
-
|
75
|
+
end
|
73
76
|
|
74
77
|
file_accessor.public_headers.map do |public_header|
|
75
78
|
public_header = if header_mappings_dir(file_accessor)
|
@@ -148,14 +151,18 @@ module Pod
|
|
148
151
|
# Removes overrides of the `pod_target_xcconfig` settings from the target's
|
149
152
|
# build configurations.
|
150
153
|
#
|
151
|
-
# @
|
152
|
-
#
|
153
|
-
# @param [Target::BuildSettings] build_settings
|
154
|
+
# @param [Hash{Symbol => Pod::Target::BuildSettings}] build_settings_by_config the build settings by config
|
155
|
+
# of the target.
|
154
156
|
#
|
155
157
|
# @param [PBXNativeTarget] native_target
|
158
|
+
# the native target to remove pod target xcconfig overrides from.
|
159
|
+
#
|
160
|
+
# @return [Void]
|
156
161
|
#
|
157
|
-
|
162
|
+
#
|
163
|
+
def remove_pod_target_xcconfig_overrides_from_target(build_settings_by_config, native_target)
|
158
164
|
native_target.build_configurations.each do |configuration|
|
165
|
+
build_settings = build_settings_by_config[target.user_build_configurations[configuration.name]]
|
159
166
|
build_settings.merged_pod_target_xcconfigs.each_key do |setting|
|
160
167
|
configuration.build_settings.delete(setting)
|
161
168
|
end
|
@@ -365,9 +372,10 @@ module Pod
|
|
365
372
|
configuration.build_settings['CODE_SIGN_IDENTITY'] = '' if target.platform == :osx
|
366
373
|
end
|
367
374
|
|
368
|
-
remove_pod_target_xcconfig_overrides_from_target(target.
|
375
|
+
remove_pod_target_xcconfig_overrides_from_target(target.test_spec_build_settings_by_config[test_spec.name], test_native_target)
|
369
376
|
|
370
377
|
# Test native targets also need frameworks and resources to be copied over to their xctest bundle.
|
378
|
+
create_test_target_prepare_artifacts_script(test_spec)
|
371
379
|
create_test_target_embed_frameworks_script(test_spec)
|
372
380
|
create_test_target_copy_resources_script(test_spec)
|
373
381
|
|
@@ -411,8 +419,11 @@ module Pod
|
|
411
419
|
app_target_label = target.app_target_label(app_spec)
|
412
420
|
platform = Platform.new(target.platform.symbolic_name, target.deployment_target_for_non_library_spec(app_spec))
|
413
421
|
info_plist_entries = spec_consumer.info_plist
|
422
|
+
resources = target.file_accessors.find { |fa| fa.spec == app_spec }.resources
|
423
|
+
add_launchscreen_storyboard = resources.none? { |resource| resource.basename.to_s == 'LaunchScreen.storyboard' } && platform.name == :ios
|
414
424
|
app_native_target = AppHostInstaller.new(sandbox, project, platform, subspec_name, spec_name,
|
415
425
|
app_target_label, :add_main => false,
|
426
|
+
:add_launchscreen_storyboard => add_launchscreen_storyboard,
|
416
427
|
:info_plist_entries => info_plist_entries).install!
|
417
428
|
|
418
429
|
app_native_target.product_reference.name = app_target_label
|
@@ -454,11 +465,11 @@ module Pod
|
|
454
465
|
end
|
455
466
|
end
|
456
467
|
|
457
|
-
remove_pod_target_xcconfig_overrides_from_target(target.
|
468
|
+
remove_pod_target_xcconfig_overrides_from_target(target.app_spec_build_settings_by_config[app_spec.name], app_native_target)
|
458
469
|
|
459
470
|
create_app_target_embed_frameworks_script(app_spec)
|
460
471
|
create_app_target_copy_resources_script(app_spec)
|
461
|
-
add_resources_to_target(
|
472
|
+
add_resources_to_target(resources, app_native_target)
|
462
473
|
|
463
474
|
app_native_target
|
464
475
|
end
|
@@ -489,7 +500,7 @@ module Pod
|
|
489
500
|
# @param [Array<Sandbox::FileAccessor>] file_accessors
|
490
501
|
# the file accessors list to generate resource bundles for.
|
491
502
|
#
|
492
|
-
# @return [Array<PBXNativeTarget>] the resource bundle native targets created.
|
503
|
+
# @return [Hash{String=>Array<PBXNativeTarget>}] the resource bundle native targets created.
|
493
504
|
#
|
494
505
|
def add_resources_bundle_targets(file_accessors)
|
495
506
|
file_accessors.each_with_object({}) do |file_accessor, hash|
|
@@ -548,7 +559,7 @@ module Pod
|
|
548
559
|
end
|
549
560
|
end
|
550
561
|
|
551
|
-
remove_pod_target_xcconfig_overrides_from_target(target.
|
562
|
+
remove_pod_target_xcconfig_overrides_from_target(target.build_settings_by_config_for_spec(file_accessor.spec), resource_bundle_target)
|
552
563
|
|
553
564
|
resource_bundle_target
|
554
565
|
end
|
@@ -566,12 +577,14 @@ module Pod
|
|
566
577
|
# @return [void]
|
567
578
|
#
|
568
579
|
def create_xcconfig_file(native_target, resource_bundle_targets)
|
569
|
-
|
570
|
-
|
571
|
-
|
580
|
+
target.user_config_names_by_config_type.each do |config, names|
|
581
|
+
path = target.xcconfig_path(config)
|
582
|
+
update_changed_file(target.build_settings[config], path)
|
583
|
+
xcconfig_file_ref = add_file_to_support_group(path)
|
572
584
|
|
573
|
-
|
574
|
-
|
585
|
+
# also apply the private config to resource bundle targets.
|
586
|
+
apply_xcconfig_file_ref_to_targets([native_target] + resource_bundle_targets, xcconfig_file_ref, names)
|
587
|
+
end
|
575
588
|
end
|
576
589
|
|
577
590
|
# Generates the contents of the xcconfig file used for each test target type and saves it to disk.
|
@@ -588,19 +601,22 @@ module Pod
|
|
588
601
|
target.test_specs.each do |test_spec|
|
589
602
|
spec_consumer = test_spec.consumer(target.platform)
|
590
603
|
test_type = spec_consumer.test_type
|
591
|
-
path = target.xcconfig_path("#{test_type.capitalize}-#{target.subspec_label(test_spec)}")
|
592
|
-
test_spec_build_settings = target.build_settings_for_spec(test_spec)
|
593
|
-
update_changed_file(test_spec_build_settings, path)
|
594
|
-
test_xcconfig_file_ref = add_file_to_support_group(path)
|
595
|
-
|
596
604
|
test_native_target = test_native_target_from_spec(spec_consumer.spec, test_native_targets)
|
605
|
+
|
606
|
+
target.user_config_names_by_config_type.each do |config, names|
|
607
|
+
path = target.xcconfig_path("#{test_type.capitalize}-#{target.subspec_label(test_spec)}.#{config}")
|
608
|
+
test_spec_build_settings = target.build_settings_for_spec(test_spec, :configuration => config)
|
609
|
+
update_changed_file(test_spec_build_settings, path)
|
610
|
+
test_xcconfig_file_ref = add_file_to_support_group(path)
|
611
|
+
|
612
|
+
# also apply the private config to resource bundle test targets related to this test spec.
|
613
|
+
scoped_test_resource_bundle_targets = test_resource_bundle_targets[test_spec.name]
|
614
|
+
apply_xcconfig_file_ref_to_targets([test_native_target] + scoped_test_resource_bundle_targets, test_xcconfig_file_ref, names)
|
615
|
+
end
|
616
|
+
|
597
617
|
test_native_target.build_configurations.each do |test_native_target_bc|
|
598
618
|
test_target_swift_debug_hack(test_spec, test_native_target_bc)
|
599
619
|
end
|
600
|
-
|
601
|
-
# also apply the private config to resource bundle test targets related to this test spec.
|
602
|
-
scoped_test_resource_bundle_targets = test_resource_bundle_targets[test_spec.name]
|
603
|
-
apply_xcconfig_file_ref_to_targets([test_native_target] + scoped_test_resource_bundle_targets, test_xcconfig_file_ref)
|
604
620
|
end
|
605
621
|
end
|
606
622
|
|
@@ -613,12 +629,11 @@ module Pod
|
|
613
629
|
#
|
614
630
|
def create_test_target_copy_resources_script(test_spec)
|
615
631
|
path = target.copy_resources_script_path_for_spec(test_spec)
|
616
|
-
pod_targets = target.dependent_targets_for_test_spec(test_spec)
|
617
632
|
host_target_spec_names = target.app_host_dependent_targets_for_spec(test_spec).flat_map do |pt|
|
618
633
|
pt.specs.map(&:name)
|
619
634
|
end.uniq
|
620
|
-
resource_paths_by_config = target.user_build_configurations.
|
621
|
-
resources_by_config[
|
635
|
+
resource_paths_by_config = target.user_build_configurations.each_with_object({}) do |(config_name, config), resources_by_config|
|
636
|
+
resources_by_config[config_name] = target.dependent_targets_for_test_spec(test_spec, :configuration => config).flat_map do |pod_target|
|
622
637
|
spec_paths_to_include = pod_target.library_specs.map(&:name)
|
623
638
|
spec_paths_to_include -= host_target_spec_names
|
624
639
|
spec_paths_to_include << test_spec.name if pod_target == target
|
@@ -632,6 +647,33 @@ module Pod
|
|
632
647
|
end
|
633
648
|
end
|
634
649
|
|
650
|
+
# Creates a script that prepares artifacts for the test target.
|
651
|
+
#
|
652
|
+
# @param [Specification] test_spec
|
653
|
+
# The test spec to create the script for.
|
654
|
+
#
|
655
|
+
# @return [void]
|
656
|
+
#
|
657
|
+
def create_test_target_prepare_artifacts_script(test_spec)
|
658
|
+
path = target.prepare_artifacts_script_path_for_spec(test_spec)
|
659
|
+
host_target_spec_names = target.app_host_dependent_targets_for_spec(test_spec).flat_map do |pt|
|
660
|
+
pt.specs.map(&:name)
|
661
|
+
end.uniq
|
662
|
+
frameworks_by_config = target.user_build_configurations.each_with_object({}) do |(config_name, config), paths_by_config|
|
663
|
+
paths_by_config[config_name] = target.dependent_targets_for_test_spec(test_spec, :configuration => config).flat_map do |pod_target|
|
664
|
+
spec_paths_to_include = pod_target.library_specs.map(&:name)
|
665
|
+
spec_paths_to_include -= host_target_spec_names
|
666
|
+
spec_paths_to_include << test_spec.name if pod_target == target
|
667
|
+
pod_target.xcframeworks.values_at(*spec_paths_to_include).flatten.compact.uniq
|
668
|
+
end
|
669
|
+
end
|
670
|
+
unless frameworks_by_config.each_value.all?(&:empty?)
|
671
|
+
generator = Generator::PrepareArtifactsScript.new(frameworks_by_config, target.sandbox.root, target.platform)
|
672
|
+
update_changed_file(generator, path)
|
673
|
+
add_file_to_support_group(path)
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
635
677
|
# Creates a script that embeds the frameworks to the bundle of the test target.
|
636
678
|
#
|
637
679
|
# @param [Specification] test_spec
|
@@ -641,12 +683,11 @@ module Pod
|
|
641
683
|
#
|
642
684
|
def create_test_target_embed_frameworks_script(test_spec)
|
643
685
|
path = target.embed_frameworks_script_path_for_spec(test_spec)
|
644
|
-
pod_targets = target.dependent_targets_for_test_spec(test_spec)
|
645
686
|
host_target_spec_names = target.app_host_dependent_targets_for_spec(test_spec).flat_map do |pt|
|
646
687
|
pt.specs.map(&:name)
|
647
688
|
end.uniq
|
648
|
-
framework_paths_by_config = target.user_build_configurations.
|
649
|
-
paths_by_config[
|
689
|
+
framework_paths_by_config = target.user_build_configurations.each_with_object({}) do |(config_name, config), paths_by_config|
|
690
|
+
paths_by_config[config_name] = target.dependent_targets_for_test_spec(test_spec, :configuration => config).flat_map do |pod_target|
|
650
691
|
spec_paths_to_include = pod_target.library_specs.map(&:name)
|
651
692
|
spec_paths_to_include -= host_target_spec_names
|
652
693
|
spec_paths_to_include << test_spec.name if pod_target == target
|
@@ -673,15 +714,18 @@ module Pod
|
|
673
714
|
def create_app_xcconfig_files(app_native_targets, app_resource_bundle_targets)
|
674
715
|
target.app_specs.each do |app_spec|
|
675
716
|
spec_consumer = app_spec.consumer(target.platform)
|
676
|
-
path = target.xcconfig_path(target.subspec_label(app_spec))
|
677
|
-
update_changed_file(target.build_settings_for_spec(app_spec), path)
|
678
|
-
app_xcconfig_file_ref = add_file_to_support_group(path)
|
679
|
-
|
680
717
|
app_native_target = app_native_target_from_spec(spec_consumer.spec, app_native_targets)
|
681
718
|
|
682
|
-
|
683
|
-
|
684
|
-
|
719
|
+
target.user_config_names_by_config_type.each do |config, names|
|
720
|
+
path = target.xcconfig_path("#{target.subspec_label(app_spec)}.#{config}")
|
721
|
+
app_spec_build_settings = target.build_settings_for_spec(app_spec, :configuration => config)
|
722
|
+
update_changed_file(app_spec_build_settings, path)
|
723
|
+
app_xcconfig_file_ref = add_file_to_support_group(path)
|
724
|
+
|
725
|
+
# also apply the private config to resource bundle app targets related to this app spec.
|
726
|
+
scoped_app_resource_bundle_targets = app_resource_bundle_targets[app_spec.name]
|
727
|
+
apply_xcconfig_file_ref_to_targets([app_native_target] + scoped_app_resource_bundle_targets, app_xcconfig_file_ref, names)
|
728
|
+
end
|
685
729
|
end
|
686
730
|
end
|
687
731
|
|
@@ -694,9 +738,9 @@ module Pod
|
|
694
738
|
#
|
695
739
|
def create_app_target_copy_resources_script(app_spec)
|
696
740
|
path = target.copy_resources_script_path_for_spec(app_spec)
|
697
|
-
|
698
|
-
|
699
|
-
resources_by_config[
|
741
|
+
resource_paths_by_config = target.user_build_configurations.each_with_object({}) do |(config_name, config), resources_by_config|
|
742
|
+
pod_targets = target.dependent_targets_for_app_spec(app_spec, :configuration => config)
|
743
|
+
resources_by_config[config_name] = pod_targets.flat_map do |pod_target|
|
700
744
|
spec_paths_to_include = pod_target.library_specs.map(&:name)
|
701
745
|
spec_paths_to_include << app_spec.name if pod_target == target
|
702
746
|
pod_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
|
@@ -718,9 +762,9 @@ module Pod
|
|
718
762
|
#
|
719
763
|
def create_app_target_embed_frameworks_script(app_spec)
|
720
764
|
path = target.embed_frameworks_script_path_for_spec(app_spec)
|
721
|
-
|
722
|
-
|
723
|
-
paths_by_config[
|
765
|
+
framework_paths_by_config = target.user_build_configurations.each_with_object({}) do |(config_name, config), paths_by_config|
|
766
|
+
pod_targets = target.dependent_targets_for_app_spec(app_spec, :configuration => config)
|
767
|
+
paths_by_config[config_name] = pod_targets.flat_map do |pod_target|
|
724
768
|
spec_paths_to_include = pod_target.library_specs.map(&:name)
|
725
769
|
spec_paths_to_include << app_spec.name if pod_target == target
|
726
770
|
pod_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
|
@@ -841,9 +885,10 @@ module Pod
|
|
841
885
|
flags * ' '
|
842
886
|
end
|
843
887
|
|
844
|
-
def apply_xcconfig_file_ref_to_targets(targets, xcconfig_file_ref)
|
888
|
+
def apply_xcconfig_file_ref_to_targets(targets, xcconfig_file_ref, configurations)
|
845
889
|
targets.each do |config_target|
|
846
890
|
config_target.build_configurations.each do |configuration|
|
891
|
+
next unless configurations.include?(configuration.name)
|
847
892
|
configuration.base_configuration_reference = xcconfig_file_ref
|
848
893
|
end
|
849
894
|
end
|
@@ -928,16 +973,20 @@ module Pod
|
|
928
973
|
'Project'
|
929
974
|
end
|
930
975
|
|
931
|
-
if target.build_as_framework? &&
|
976
|
+
if target.build_as_framework? && !header_mappings_dir(file_accessor).nil? && acl != 'Project'
|
932
977
|
relative_path = if mapping_dir = header_mappings_dir(file_accessor)
|
933
978
|
file_ref.real_path.relative_path_from(mapping_dir)
|
934
979
|
else
|
935
980
|
file_ref.real_path.relative_path_from(file_accessor.path_list.root)
|
936
981
|
end
|
982
|
+
compile_build_phase_index = native_target.build_phases.index do |bp|
|
983
|
+
bp.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase)
|
984
|
+
end
|
937
985
|
sub_dir = relative_path.dirname
|
938
986
|
copy_phase_name = "Copy #{sub_dir} #{acl} Headers"
|
939
987
|
copy_phase = native_target.copy_files_build_phases.find { |bp| bp.name == copy_phase_name } ||
|
940
988
|
native_target.new_copy_files_build_phase(copy_phase_name)
|
989
|
+
native_target.build_phases.move(copy_phase, compile_build_phase_index - 1) unless compile_build_phase_index.nil?
|
941
990
|
copy_phase.symbol_dst_subfolder_spec = :products_directory
|
942
991
|
copy_phase.dst_path = "$(#{acl.upcase}_HEADERS_FOLDER_PATH)/#{sub_dir}"
|
943
992
|
copy_phase.add_file_reference(file_ref, true)
|
@@ -1035,6 +1084,18 @@ module Pod
|
|
1035
1084
|
end
|
1036
1085
|
end
|
1037
1086
|
|
1087
|
+
# Raises if a vendored xcframework contains frameworks of mixed linkage
|
1088
|
+
#
|
1089
|
+
def validate_xcframeworks_no_mixed_linkage
|
1090
|
+
target.xcframeworks.each_value do |xcframeworks|
|
1091
|
+
xcframeworks.each do |xcframework|
|
1092
|
+
dynamic_slices, static_slices = xcframework.slices.partition { |slice| Pod::Xcode::LinkageAnalyzer.dynamic_binary?(slice.path) }
|
1093
|
+
if !dynamic_slices.empty? && !static_slices.empty?
|
1094
|
+
raise Informative, "Unable to install vendored xcframework `#{xcframework.name}` for Pod `#{target.label}`, because it contains both static and dynamic frameworks."
|
1095
|
+
end
|
1096
|
+
end
|
1097
|
+
end
|
1098
|
+
end
|
1038
1099
|
#-----------------------------------------------------------------------#
|
1039
1100
|
end
|
1040
1101
|
end
|