cocoapods 1.8.4 → 1.9.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|