cocoapods 1.10.0 → 1.11.0.beta.2

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +237 -5
  3. data/README.md +11 -11
  4. data/lib/cocoapods/command/outdated.rb +12 -1
  5. data/lib/cocoapods/command/repo/push.rb +17 -0
  6. data/lib/cocoapods/command/spec.rb +18 -9
  7. data/lib/cocoapods/command/spec/cat.rb +3 -1
  8. data/lib/cocoapods/command/spec/lint.rb +1 -1
  9. data/lib/cocoapods/command/spec/which.rb +3 -1
  10. data/lib/cocoapods/config.rb +1 -1
  11. data/lib/cocoapods/downloader.rb +4 -2
  12. data/lib/cocoapods/downloader/cache.rb +95 -6
  13. data/lib/cocoapods/external_sources/podspec_source.rb +1 -1
  14. data/lib/cocoapods/gem_version.rb +1 -1
  15. data/lib/cocoapods/generator/acknowledgements.rb +1 -1
  16. data/lib/cocoapods/generator/app_target_helper.rb +7 -3
  17. data/lib/cocoapods/generator/copy_dsyms_script.rb +4 -4
  18. data/lib/cocoapods/generator/copy_xcframework_script.rb +2 -18
  19. data/lib/cocoapods/generator/embed_frameworks_script.rb +2 -1
  20. data/lib/cocoapods/generator/script_phase_constants.rb +1 -0
  21. data/lib/cocoapods/installer.rb +52 -4
  22. data/lib/cocoapods/installer/analyzer.rb +12 -8
  23. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +31 -4
  24. data/lib/cocoapods/installer/podfile_validator.rb +2 -2
  25. data/lib/cocoapods/installer/pre_integrate_hooks_context.rb +9 -0
  26. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +9 -2
  27. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +15 -2
  28. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +7 -4
  29. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +149 -9
  30. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +1 -1
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +10 -3
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +25 -6
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +6 -19
  34. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +70 -58
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +48 -6
  36. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +2 -2
  37. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +2 -5
  38. data/lib/cocoapods/resolver.rb +4 -4
  39. data/lib/cocoapods/sandbox/file_accessor.rb +57 -10
  40. data/lib/cocoapods/sandbox/headers_store.rb +3 -1
  41. data/lib/cocoapods/sandbox/path_list.rb +1 -1
  42. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +1 -1
  43. data/lib/cocoapods/sources_manager.rb +14 -8
  44. data/lib/cocoapods/target.rb +1 -1
  45. data/lib/cocoapods/target/aggregate_target.rb +23 -1
  46. data/lib/cocoapods/target/build_settings.rb +45 -20
  47. data/lib/cocoapods/target/pod_target.rb +47 -22
  48. data/lib/cocoapods/user_interface.rb +4 -0
  49. data/lib/cocoapods/validator.rb +25 -5
  50. data/lib/cocoapods/version_metadata.rb +1 -1
  51. data/lib/cocoapods/xcode/xcframework.rb +8 -3
  52. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +10 -1
  53. metadata +28 -21
@@ -34,6 +34,7 @@ module Pod
34
34
  target_installation_result.non_library_specs_by_native_target.each do |native_target, spec|
35
35
  add_embed_frameworks_script_phase(native_target, spec)
36
36
  add_copy_resources_script_phase(native_target, spec)
37
+ add_on_demand_resources(native_target, spec) if spec.app_specification?
37
38
  UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(spec), native_target)
38
39
  end
39
40
  add_copy_dsyms_script_phase(target_installation_result.native_target)
@@ -134,20 +135,26 @@ module Pod
134
135
  spec_paths_to_include << spec.name if dependent_target == target
135
136
  dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact
136
137
  end.uniq
138
+ xcframework_paths = dependent_targets.flat_map do |dependent_target|
139
+ spec_paths_to_include = dependent_target.library_specs.map(&:name)
140
+ spec_paths_to_include -= host_target_spec_names
141
+ spec_paths_to_include << spec.name if dependent_target == target
142
+ dependent_target.xcframeworks.values_at(*spec_paths_to_include).flatten.compact
143
+ end.uniq
137
144
 
138
- if use_input_output_paths? && !framework_paths.empty?
145
+ if use_input_output_paths? && !framework_paths.empty? || !xcframework_paths.empty?
139
146
  input_file_list_path = target.embed_frameworks_script_input_files_path_for_spec(spec)
140
147
  input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
141
148
  input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
142
- input_paths_by_config[input_paths_key] = [script_path] + UserProjectIntegrator::TargetIntegrator.embed_frameworks_input_paths(framework_paths, [])
149
+ input_paths_by_config[input_paths_key] = [script_path] + UserProjectIntegrator::TargetIntegrator.embed_frameworks_input_paths(framework_paths, xcframework_paths)
143
150
 
144
151
  output_file_list_path = target.embed_frameworks_script_output_files_path_for_spec(spec)
145
152
  output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
146
153
  output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
147
- output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.embed_frameworks_output_paths(framework_paths, [])
154
+ output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.embed_frameworks_output_paths(framework_paths, xcframework_paths)
148
155
  end
149
156
 
150
- if framework_paths.empty?
157
+ if framework_paths.empty? && xcframework_paths.empty?
151
158
  UserProjectIntegrator::TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
152
159
  else
153
160
  UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(
@@ -183,7 +190,7 @@ module Pod
183
190
  output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
184
191
  output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
185
192
  output_paths_by_config[output_paths_key] = xcframeworks.map do |xcf|
186
- "#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcf.name}"
193
+ "#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcf.target_name}/#{xcf.name}.framework"
187
194
  end
188
195
  end
189
196
 
@@ -199,7 +206,7 @@ module Pod
199
206
  # vendored dSYMs.
200
207
  #
201
208
  # @param [PBXNativeTarget] native_target
202
- # the native target for which to add the the copy dSYM files build phase.
209
+ # the native target for which to add the copy dSYM files build phase.
203
210
  #
204
211
  # @return [void]
205
212
  #
@@ -242,6 +249,41 @@ module Pod
242
249
  UserProjectIntegrator::TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
243
250
  end
244
251
 
252
+ # Adds the ODRs that are related to this app spec. This includes the app spec dependencies as well as the ODRs
253
+ # coming from the app spec itself.
254
+ #
255
+ # @param [Xcodeproj::PBXNativeTarget] native_target
256
+ # the native target for which to add the ODR file references into.
257
+ #
258
+ # @param [Specification] app_spec
259
+ # the app spec to integrate ODRs for.
260
+ #
261
+ # @return [void]
262
+ #
263
+ def add_on_demand_resources(native_target, app_spec)
264
+ dependent_targets = target.dependent_targets_for_app_spec(app_spec)
265
+ parent_odr_group = native_target.project.group_for_spec(app_spec.name)
266
+
267
+ # Add ODRs of the app spec dependencies first.
268
+ dependent_targets.each do |pod_target|
269
+ file_accessors = pod_target.file_accessors.select do |fa|
270
+ fa.spec.library_specification? ||
271
+ fa.spec.test_specification? && pod_target.test_app_hosts_by_spec[fa.spec]&.first == app_spec
272
+ end
273
+ target_odr_group_name = "#{pod_target.label}-OnDemandResources"
274
+ UserProjectIntegrator::TargetIntegrator.update_on_demand_resources(target.sandbox, native_target.project,
275
+ native_target, file_accessors,
276
+ parent_odr_group, target_odr_group_name)
277
+ end
278
+
279
+ # Now add the ODRs of our own app spec declaration.
280
+ file_accessor = target.file_accessors.find { |fa| fa.spec == app_spec }
281
+ target_odr_group_name = "#{target.subspec_label(app_spec)}-OnDemandResources"
282
+ UserProjectIntegrator::TargetIntegrator.update_on_demand_resources(target.sandbox, native_target.project,
283
+ native_target, file_accessor,
284
+ parent_odr_group, target_odr_group_name)
285
+ end
286
+
245
287
  # @return [String] the message that should be displayed for the target
246
288
  # integration.
247
289
  #
@@ -79,12 +79,12 @@ module Pod
79
79
  # @param [Specification] spec
80
80
  # The specification to base from in order to find the native target.
81
81
  #
82
- # @return [PBXNativeTarget] the native target to use or `nil` if none is found.
82
+ # @return [PBXNativeTarget, Nil] the native target to use or `nil` if none is found.
83
83
  #
84
84
  def native_target_for_spec(spec)
85
85
  return native_target if spec.library_specification?
86
86
  return test_native_target_from_spec(spec) if spec.test_specification?
87
- return app_native_target_from_spec(spec) if spec.app_specification?
87
+ app_native_target_from_spec(spec) if spec.app_specification?
88
88
  end
89
89
 
90
90
  # @return [Hash{PBXNativeTarget => Specification}] a hash where the keys are the test native targets and the value
@@ -56,11 +56,8 @@ module Pod
56
56
  name = target.label
57
57
  platform = target.platform.name
58
58
  language = target.uses_swift? ? :swift : :objc
59
- native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
60
-
61
- product_name = target.product_name
62
- product = native_target.product_reference
63
- product.name = product_name
59
+ native_target = project.new_target(product_type, name, platform, deployment_target, nil, language, target.product_basename)
60
+ native_target.product_reference.name = name
64
61
 
65
62
  target.user_build_configurations.each do |bc_name, type|
66
63
  native_target.add_build_configuration(bc_name, type)
@@ -162,9 +162,8 @@ module Pod
162
162
  Array(@podfile_requirements_by_root_name[dependency.root_name])
163
163
  end
164
164
 
165
- specifications_for_dependency(dependency, additional_requirements)
165
+ specifications_for_dependency(dependency, additional_requirements).freeze
166
166
  end
167
- @search[dependency].dup
168
167
  end
169
168
 
170
169
  # Returns the dependencies of `specification`.
@@ -175,8 +174,9 @@ module Pod
175
174
  # dependencies are being asked for.
176
175
  #
177
176
  def dependencies_for(specification)
177
+ root_name = Specification.root_name(specification.name)
178
178
  specification.all_dependencies.map do |dependency|
179
- if dependency.root_name == Specification.root_name(specification.name)
179
+ if dependency.root_name == root_name
180
180
  dependency.dup.tap { |d| d.specific_version = specification.version }
181
181
  else
182
182
  dependency
@@ -264,7 +264,7 @@ module Pod
264
264
  # @param [{String => Array<Conflict>}] conflicts the current conflicts.
265
265
  #
266
266
  def sort_dependencies(dependencies, activated, conflicts)
267
- dependencies.sort_by do |dependency|
267
+ dependencies.sort_by! do |dependency|
268
268
  name = name_for(dependency)
269
269
  [
270
270
  activated.vertex_named(name).payload ? 0 : 1,
@@ -128,6 +128,7 @@ module Pod
128
128
  #
129
129
  def public_headers(include_frameworks = false)
130
130
  public_headers = public_header_files
131
+ project_headers = project_header_files
131
132
  private_headers = private_header_files
132
133
  if public_headers.nil? || public_headers.empty?
133
134
  header_files = headers
@@ -135,7 +136,13 @@ module Pod
135
136
  header_files = public_headers
136
137
  end
137
138
  header_files += vendored_frameworks_headers if include_frameworks
138
- header_files - private_headers
139
+ header_files - project_headers - private_headers
140
+ end
141
+
142
+ # @return [Array<Pathname>] The project headers of the specification.
143
+ #
144
+ def project_headers
145
+ project_header_files
139
146
  end
140
147
 
141
148
  # @return [Array<Pathname>] The private headers of the specification.
@@ -172,6 +179,15 @@ module Pod
172
179
  end
173
180
  end
174
181
 
182
+ # @return [Array<Pathname>] The paths of the dynamic xcframework bundles
183
+ # that come shipped with the Pod.
184
+ #
185
+ def vendored_static_xcframeworks
186
+ vendored_xcframeworks.select do |path|
187
+ Xcode::XCFramework.new(spec.name, path).build_type == BuildType.static_framework
188
+ end
189
+ end
190
+
175
191
  # @return [Array<Pathname>] The paths of the static (fake) framework
176
192
  # bundles that come shipped with the Pod.
177
193
  #
@@ -191,7 +207,7 @@ module Pod
191
207
  # @param [Array<FileAccessor>] file_accessors
192
208
  # The list of all file accessors to compute.
193
209
  #
194
- # @return [Array<String>] The list of all file accessors that a target will integrate into the project.
210
+ # @return [Array<Pathname>] The list of all file accessors that a target will integrate into the project.
195
211
  #
196
212
  def self.all_files(file_accessors)
197
213
  files = [
@@ -203,10 +219,11 @@ module Pod
203
219
  file_accessors.map(&:preserve_paths),
204
220
  file_accessors.map(&:readme),
205
221
  file_accessors.map(&:resources),
222
+ file_accessors.map(&:on_demand_resources_files),
206
223
  file_accessors.map(&:source_files),
207
224
  file_accessors.map(&:module_map),
208
225
  ]
209
- files.flatten.compact.map(&:to_s).uniq
226
+ files.flatten.compact.uniq
210
227
  end
211
228
 
212
229
  # @param [Pathname] framework
@@ -229,14 +246,17 @@ module Pod
229
246
  Pathname.glob(headers_dir + '**/' + GLOB_PATTERNS[:public_header_files])
230
247
  end
231
248
 
232
- # @param [Pathname] framework
249
+ # @param [String] target_name
250
+ # The target name this .xcframework belongs to
251
+ #
252
+ # @param [Pathname] framework_path
233
253
  # The path to the .xcframework
234
254
  #
235
255
  # @return [Array<Pathname>] The paths to all the headers included in the
236
256
  # vendored xcframework
237
257
  #
238
- def self.vendored_xcframework_headers(framework)
239
- xcframework = Xcode::XCFramework.new(framework)
258
+ def self.vendored_xcframework_headers(target_name, framework_path)
259
+ xcframework = Xcode::XCFramework.new(target_name, framework_path)
240
260
  xcframework.slices.flat_map do |slice|
241
261
  vendored_frameworks_headers(slice.path)
242
262
  end
@@ -250,7 +270,7 @@ module Pod
250
270
  self.class.vendored_frameworks_headers(framework)
251
271
  end.uniq
252
272
  paths.concat Array.new(vendored_xcframeworks.flat_map do |framework|
253
- self.class.vendored_xcframework_headers(framework)
273
+ self.class.vendored_xcframework_headers(spec.name, framework)
254
274
  end)
255
275
  paths
256
276
  end
@@ -289,7 +309,7 @@ module Pod
289
309
  # that come shipped with the Pod.
290
310
  #
291
311
  def vendored_static_artifacts
292
- vendored_static_libraries + vendored_static_frameworks
312
+ vendored_static_libraries + vendored_static_frameworks + vendored_static_xcframeworks
293
313
  end
294
314
 
295
315
  # @return [Hash{String => Array<Pathname>}] A hash that describes the
@@ -314,6 +334,26 @@ module Pod
314
334
  resource_bundles.values.flatten
315
335
  end
316
336
 
337
+ # @return [Hash{String => Hash] The expanded paths of the on demand resources specified
338
+ # keyed by their tag including their category.
339
+ #
340
+ def on_demand_resources
341
+ result = {}
342
+ spec_consumer.on_demand_resources.each do |tag_name, file_patterns|
343
+ paths = expanded_paths(file_patterns[:paths],
344
+ :exclude_patterns => spec_consumer.exclude_files,
345
+ :include_dirs => true)
346
+ result[tag_name] = { :paths => paths, :category => file_patterns[:category] }
347
+ end
348
+ result
349
+ end
350
+
351
+ # @return [Array<Pathname>] The expanded paths of the on demand resources.
352
+ #
353
+ def on_demand_resources_files
354
+ on_demand_resources.values.flat_map { |v| v[:paths] }
355
+ end
356
+
317
357
  # @return [Pathname] The of the prefix header file of the specification.
318
358
  #
319
359
  def prefix_header
@@ -322,7 +362,7 @@ module Pod
322
362
  end
323
363
  end
324
364
 
325
- # @return [Pathname] The path of the auto-detected README file.
365
+ # @return [Pathname, nil] The path of the auto-detected README file.
326
366
  #
327
367
  def readme
328
368
  path_list.glob([GLOB_PATTERNS[:readme]]).first
@@ -404,7 +444,14 @@ module Pod
404
444
  paths_for_attribute(:public_header_files)
405
445
  end
406
446
 
407
- # @return [Array<Pathname>] The paths of the user-specified public header
447
+ # @return [Array<Pathname>] The paths of the user-specified project header
448
+ # files.
449
+ #
450
+ def project_header_files
451
+ paths_for_attribute(:project_header_files)
452
+ end
453
+
454
+ # @return [Array<Pathname>] The paths of the user-specified private header
408
455
  # files.
409
456
  #
410
457
  def private_header_files
@@ -51,7 +51,9 @@ module Pod
51
51
  #
52
52
  def search_paths(platform, target_name = nil, use_modular_headers = false)
53
53
  key = SEARCH_PATHS_KEY.new(platform.name, target_name, use_modular_headers)
54
- return @search_paths_cache[key] if @search_paths_cache.key?(key)
54
+ if (cached = @search_paths_cache[key])
55
+ return cached
56
+ end
55
57
  search_paths = @search_paths.select do |entry|
56
58
  matches_platform = entry[:platform] == platform.name
57
59
  matches_target = target_name.nil? || (File.basename(entry[:path]) == target_name)
@@ -23,7 +23,7 @@ module Pod
23
23
  # @param [Pathname] root @see #root
24
24
  #
25
25
  def initialize(root)
26
- root_dir = ActiveSupport::Multibyte::Unicode.normalize(root.to_s)
26
+ root_dir = root.to_s.unicode_normalize(:nfkc)
27
27
  @root = Pathname.new(root_dir)
28
28
  @glob_cache = {}
29
29
  end
@@ -64,7 +64,7 @@ module Pod
64
64
  # specifications (according to their platform) of this Pod.
65
65
  #
66
66
  def used_files
67
- FileAccessor.all_files(file_accessors)
67
+ FileAccessor.all_files(file_accessors).map(&:to_s)
68
68
  end
69
69
  end
70
70
  end
@@ -1,4 +1,5 @@
1
1
  require 'cocoapods-core/source'
2
+ require 'cocoapods/open-uri'
2
3
  require 'netrc'
3
4
  require 'set'
4
5
  require 'rest'
@@ -70,15 +71,20 @@ module Pod
70
71
  # The URL of the source.
71
72
  #
72
73
  def cdn_url?(url)
73
- if url =~ %r{^https?:\/\/}
74
- require 'typhoeus'
74
+ return unless url =~ %r{^https?:\/\/}
75
75
 
76
- response = Typhoeus.get(url + '/CocoaPods-version.yml', :netrc_file => Netrc.default_path, :netrc => :optional)
77
- response.code == 200 && begin
78
- response_hash = YAML.load(response.body) # rubocop:disable Security/YAMLLoad
79
- response_hash.is_a?(Hash) && !Source::Metadata.new(response_hash).latest_cocoapods_version.nil?
80
- end
81
- end
76
+ uri_options = {}
77
+
78
+ netrc_info = Netrc.read
79
+ netrc_host = URI.parse(url).host
80
+ credentials = netrc_info[netrc_host]
81
+ uri_options[:http_basic_authentication] = credentials if credentials
82
+
83
+ response = OpenURI.open_uri(url.chomp('/') + '/CocoaPods-version.yml', uri_options)
84
+ response_hash = YAML.load(response.read) # rubocop:disable Security/YAMLLoad
85
+ response_hash.is_a?(Hash) && !Source::Metadata.new(response_hash).latest_cocoapods_version.nil?
86
+ rescue ::OpenURI::HTTPError, SocketError
87
+ return false
82
88
  rescue => e
83
89
  raise Informative, "Couldn't determine repo type for URL: `#{url}`: #{e}"
84
90
  end
@@ -350,7 +350,7 @@ module Pod
350
350
  end
351
351
 
352
352
  def self.resource_extension_compilable?(input_extension)
353
- output_extension_for_resource(input_extension) != input_extension
353
+ output_extension_for_resource(input_extension) != input_extension && input_extension != '.xcassets'
354
354
  end
355
355
 
356
356
  #-------------------------------------------------------------------------#
@@ -225,6 +225,12 @@ module Pod
225
225
  !resource_paths_by_config.each_value.all?(&:empty?)
226
226
  end
227
227
 
228
+ # @return [Boolean] Whether the target contains any on demand resources
229
+ #
230
+ def includes_on_demand_resources?
231
+ !on_demand_resources.empty?
232
+ end
233
+
228
234
  # @return [Boolean] Whether the target contains frameworks to be embedded into
229
235
  # the user target
230
236
  #
@@ -273,6 +279,20 @@ module Pod
273
279
  end
274
280
  end
275
281
 
282
+ # @return [Array<Pathname>] Uniqued On Demand Resources for this target.
283
+ #
284
+ # @note On Demand Resources are not separated by config as they are integrated directly into the users target via
285
+ # the resources build phase.
286
+ #
287
+ def on_demand_resources
288
+ @on_demand_resources ||= begin
289
+ pod_targets.flat_map do |pod_target|
290
+ library_file_accessors = pod_target.file_accessors.select { |fa| fa.spec.library_specification? }
291
+ library_file_accessors.flat_map(&:on_demand_resources_files)
292
+ end.uniq
293
+ end
294
+ end
295
+
276
296
  # @return [Hash{String => Array<String>}] Uniqued Resources grouped by config
277
297
  #
278
298
  def resource_paths_by_config
@@ -292,7 +312,9 @@ module Pod
292
312
  extname = File.extname(resource_path)
293
313
  if self.class.resource_extension_compilable?(extname)
294
314
  output_extname = self.class.output_extension_for_resource(extname)
295
- built_product_dir.join(File.basename(resource_path, extname)).sub_ext(output_extname).to_s
315
+ output_path_components = Pathname(resource_path).each_filename.select { |component| File.extname(component) == '.lproj' }
316
+ output_path_components << File.basename(resource_path)
317
+ built_product_dir.join(*output_path_components).sub_ext(output_extname).to_s
296
318
  else
297
319
  resource_path
298
320
  end
@@ -140,12 +140,12 @@ module Pod
140
140
  end
141
141
  private_class_method :define_build_settings_method
142
142
 
143
- # @param [XCFramework] xcframework the xcframework thats slice will be copied to the intermediates dir
143
+ # @param [XCFramework] xcframework the xcframework slice that will be copied to the intermediates dir
144
144
  #
145
145
  # @return [String] the path to the directory containing the xcframework slice
146
146
  #
147
147
  def self.xcframework_intermediate_dir(xcframework)
148
- "#{XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcframework.name}"
148
+ "#{XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcframework.target_name}"
149
149
  end
150
150
 
151
151
  class << self
@@ -346,18 +346,26 @@ module Pod
346
346
  #
347
347
  # @param [Boolean] test_bundle
348
348
  #
349
- def _ld_runpath_search_paths(requires_host_target: false, test_bundle: false)
349
+ def _ld_runpath_search_paths(requires_host_target: false, test_bundle: false, uses_swift: false)
350
+ paths = []
351
+ if uses_swift
352
+ paths << '/usr/lib/swift'
353
+ paths << '$(PLATFORM_DIR)/Developer/Library/Frameworks' if test_bundle
354
+ end
350
355
  if target.platform.symbolic_name == :osx
351
- ["'@executable_path/../Frameworks'",
352
- test_bundle ? "'@loader_path/../Frameworks'" : "'@loader_path/Frameworks'"]
356
+ paths << "'@executable_path/../Frameworks'"
357
+ paths << if test_bundle
358
+ "'@loader_path/../Frameworks'"
359
+ else
360
+ "'@loader_path/Frameworks'"
361
+ end
362
+ paths << '${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}' if uses_swift
353
363
  else
354
- paths = [
355
- "'@executable_path/Frameworks'",
356
- "'@loader_path/Frameworks'",
357
- ]
364
+ paths << "'@executable_path/Frameworks'"
365
+ paths << "'@loader_path/Frameworks'"
358
366
  paths << "'@executable_path/../../Frameworks'" if requires_host_target
359
- paths
360
367
  end
368
+ paths
361
369
  end
362
370
  private :_ld_runpath_search_paths
363
371
 
@@ -500,12 +508,14 @@ module Pod
500
508
  pod_targets - subset_targets
501
509
  end
502
510
 
511
+ # @param [String] target_name the name of the target this xcframework belongs to
512
+ #
503
513
  # @param [Pathname,String] path the path to the xcframework bundle
504
514
  #
505
515
  # @return [Xcode::XCFramework] the xcframework at the given path
506
516
  #
507
- def load_xcframework(path)
508
- Xcode::XCFramework.new(path)
517
+ def load_xcframework(target_name, path)
518
+ Xcode::XCFramework.new(target_name, path)
509
519
  end
510
520
 
511
521
  # A subclass that generates build settings for a {PodTarget}
@@ -616,9 +626,15 @@ module Pod
616
626
  select { |xcf| xcf.build_type.static_framework? }.
617
627
  map(&:name).
618
628
  uniq
629
+
630
+ # Include direct dynamic dependencies to the linker flags. We used to add those in the 'Link Binary With Libraries'
631
+ # phase but we no longer do since we cannot differentiate between debug or release configurations within
632
+ # that phase.
633
+ frameworks.concat target.dependent_targets_by_config[@configuration].flat_map { |pt| pt.build_settings[@configuration].dynamic_frameworks_to_import }
634
+ else
635
+ # Also include any vendored dynamic frameworks of dependencies.
636
+ frameworks.concat dependent_targets.reject(&:should_build?).flat_map { |pt| pt.build_settings[@configuration].dynamic_frameworks_to_import }
619
637
  end
620
- # Also include any vendored dynamic frameworks of dependencies.
621
- frameworks.concat dependent_targets.reject(&:should_build?).flat_map { |pt| pt.build_settings[@configuration].dynamic_frameworks_to_import }
622
638
  else
623
639
  frameworks.concat dependent_targets_to_link.flat_map { |pt| pt.build_settings[@configuration].frameworks_to_import }
624
640
  end
@@ -721,7 +737,9 @@ module Pod
721
737
 
722
738
  # @return [Array<Xcode::XCFramework>]
723
739
  define_build_settings_method :vendored_xcframeworks, :memoized => true do
724
- file_accessors.flat_map(&:vendored_xcframeworks).map { |path| load_xcframework(path) }
740
+ file_accessors.flat_map do |file_accessor|
741
+ file_accessor.vendored_xcframeworks.map { |path| load_xcframework(file_accessor.spec.name, path) }
742
+ end
725
743
  end
726
744
 
727
745
  # @return [Array<String>]
@@ -840,10 +858,15 @@ module Pod
840
858
 
841
859
  # @return [Array<String>]
842
860
  define_build_settings_method :library_search_paths_to_import, :memoized => true do
843
- vendored_library_search_paths = vendored_static_library_search_paths + vendored_dynamic_library_search_paths
844
- return vendored_library_search_paths if target.build_as_framework? || !target.should_build?
861
+ search_paths = vendored_static_library_search_paths + vendored_dynamic_library_search_paths
862
+ if target.uses_swift? || other_swift_flags_without_swift?
863
+ search_paths << '/usr/lib/swift'
864
+ search_paths << '${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}'
865
+ search_paths << '$(PLATFORM_DIR)/Developer/Library/Frameworks' if test_xcconfig?
866
+ end
867
+ return search_paths if target.build_as_framework? || !target.should_build?
845
868
 
846
- vendored_library_search_paths << target.configuration_build_dir(CONFIGURATION_BUILD_DIR_VARIABLE)
869
+ search_paths << target.configuration_build_dir(CONFIGURATION_BUILD_DIR_VARIABLE)
847
870
  end
848
871
 
849
872
  #-------------------------------------------------------------------------#
@@ -948,7 +971,8 @@ module Pod
948
971
  # @return [Array<String>]
949
972
  define_build_settings_method :ld_runpath_search_paths, :build_setting => true, :memoized => true do
950
973
  return if library_xcconfig?
951
- _ld_runpath_search_paths(:test_bundle => test_xcconfig?)
974
+ _ld_runpath_search_paths(:test_bundle => test_xcconfig?,
975
+ :uses_swift => other_swift_flags_without_swift? || dependent_targets.any?(&:uses_swift?))
952
976
  end
953
977
 
954
978
  #-------------------------------------------------------------------------#
@@ -1251,7 +1275,8 @@ module Pod
1251
1275
  return unless pod_targets.any?(&:build_as_dynamic?) || any_vendored_dynamic_artifacts?
1252
1276
  symbol_type = target.user_targets.map(&:symbol_type).uniq.first
1253
1277
  test_bundle = symbol_type == :octest_bundle || symbol_type == :unit_test_bundle || symbol_type == :ui_test_bundle
1254
- _ld_runpath_search_paths(:requires_host_target => target.requires_host_target?, :test_bundle => test_bundle)
1278
+ _ld_runpath_search_paths(:requires_host_target => target.requires_host_target?, :test_bundle => test_bundle,
1279
+ :uses_swift => pod_targets.any?(&:uses_swift?))
1255
1280
  end
1256
1281
 
1257
1282
  # @return [Boolean]