cocoapods 1.9.1 → 1.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +292 -5
  3. data/README.md +2 -1
  4. data/lib/cocoapods/command/lib/lint.rb +12 -3
  5. data/lib/cocoapods/command/repo/push.rb +1 -1
  6. data/lib/cocoapods/command/repo/update.rb +11 -0
  7. data/lib/cocoapods/command/spec/lint.rb +12 -3
  8. data/lib/cocoapods/command.rb +12 -2
  9. data/lib/cocoapods/config.rb +17 -0
  10. data/lib/cocoapods/downloader/cache.rb +2 -2
  11. data/lib/cocoapods/gem_version.rb +1 -1
  12. data/lib/cocoapods/generator/app_target_helper.rb +10 -2
  13. data/lib/cocoapods/generator/copy_dsyms_script.rb +56 -0
  14. data/lib/cocoapods/generator/copy_resources_script.rb +2 -14
  15. data/lib/cocoapods/generator/copy_xcframework_script.rb +245 -0
  16. data/lib/cocoapods/generator/embed_frameworks_script.rb +125 -212
  17. data/lib/cocoapods/generator/script_phase_constants.rb +99 -0
  18. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +1 -1
  19. data/lib/cocoapods/installer/analyzer.rb +17 -8
  20. data/lib/cocoapods/installer/base_install_hooks_context.rb +135 -0
  21. data/lib/cocoapods/installer/installation_options.rb +5 -0
  22. data/lib/cocoapods/installer/pod_source_installer.rb +2 -1
  23. data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -127
  24. data/lib/cocoapods/installer/post_integrate_hooks_context.rb +9 -0
  25. data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +4 -0
  26. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +2 -1
  27. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +132 -111
  28. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +13 -27
  29. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +5 -1
  30. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +2 -1
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +8 -6
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +187 -61
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +61 -30
  34. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -2
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +5 -7
  36. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +45 -6
  37. data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +19 -0
  38. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  39. data/lib/cocoapods/installer.rb +70 -3
  40. data/lib/cocoapods/sandbox/file_accessor.rb +10 -1
  41. data/lib/cocoapods/sources_manager.rb +2 -1
  42. data/lib/cocoapods/target/aggregate_target.rb +35 -0
  43. data/lib/cocoapods/target/build_settings.rb +94 -18
  44. data/lib/cocoapods/target/pod_target.rb +85 -11
  45. data/lib/cocoapods/target.rb +44 -2
  46. data/lib/cocoapods/user_interface/error_report.rb +1 -1
  47. data/lib/cocoapods/user_interface/inspector_reporter.rb +3 -10
  48. data/lib/cocoapods/validator.rb +38 -12
  49. data/lib/cocoapods/xcode/framework_paths.rb +1 -1
  50. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +91 -4
  51. data/lib/cocoapods/xcode/xcframework.rb +17 -4
  52. data/lib/cocoapods.rb +3 -1
  53. metadata +31 -53
  54. data/lib/cocoapods/generator/prepare_artifacts_script.rb +0 -257
@@ -79,13 +79,14 @@ module Pod
79
79
  #
80
80
  # @param [PBXProject] project The project to configure schemes for.
81
81
  # @param [Array<PodTarget>] pod_targets The pod targets within that project to configure their schemes.
82
+ # @param [PodsProjectGeneratorResult] generator_result the result of the project generation
82
83
  #
83
84
  # @return [void]
84
85
  #
85
- def configure_schemes(project, pod_targets)
86
+ def configure_schemes(project, pod_targets, generator_result)
86
87
  pod_targets.each do |pod_target|
87
88
  share_scheme = pod_target.should_build? && share_scheme_for_development_pod?(pod_target.pod_name) && sandbox.local?(pod_target.pod_name)
88
- configure_schemes_for_pod_target(project, pod_target, share_scheme)
89
+ configure_schemes_for_pod_target(project, pod_target, share_scheme, generator_result)
89
90
  end
90
91
  end
91
92
 
@@ -143,8 +144,10 @@ module Pod
143
144
  pod_installations_to_integrate = pod_target_installation_results.values.select do |pod_target_installation_result|
144
145
  pod_target = pod_target_installation_result.target
145
146
  !pod_target_installation_result.test_native_targets.empty? ||
146
- !pod_target_installation_result.app_native_targets.empty? ||
147
- pod_target.contains_script_phases?
147
+ !pod_target_installation_result.app_native_targets.empty? ||
148
+ pod_target.contains_script_phases? ||
149
+ pod_target.framework_paths.values.flatten.any? { |paths| !paths.dsym_path.nil? } ||
150
+ pod_target.xcframeworks.values.any? { |xcframeworks| !xcframeworks.empty? }
148
151
  end
149
152
  return if pod_installations_to_integrate.empty?
150
153
 
@@ -218,14 +221,35 @@ module Pod
218
221
  end
219
222
  end
220
223
 
221
- def configure_schemes_for_pod_target(project, pod_target, share_scheme)
224
+ # @param [Project] project
225
+ # the project of the pod target
226
+ #
227
+ # @param [Pod::PodTarget] pod_target
228
+ # the pod target for which to configure schemes
229
+ #
230
+ # @param [Boolean] share_scheme
231
+ # whether the created schemes should be shared
232
+ #
233
+ # @param [PodsProjectGeneratorResult] generator_result
234
+ # the project generation result
235
+ #
236
+ def configure_schemes_for_pod_target(project, pod_target, share_scheme, generator_result)
222
237
  # Ignore subspecs because they do not provide a scheme configuration due to the fact that they are always
223
238
  # merged with the root spec scheme.
224
239
  specs = [pod_target.root_spec] + pod_target.test_specs + pod_target.app_specs
240
+ hosted_test_specs_by_host = Hash.new do |hash, key|
241
+ hash[key] = []
242
+ end
243
+ pod_target.test_app_hosts_by_spec.each do |spec, (host_spec, host_target)|
244
+ if host_target == pod_target
245
+ hosted_test_specs_by_host[host_spec] << spec
246
+ end
247
+ end
248
+ is_custom_host = !hosted_test_specs_by_host.empty?
225
249
  specs.each do |spec|
226
250
  scheme_name = spec.spec_type == :library ? pod_target.label : pod_target.non_library_spec_label(spec)
227
251
  scheme_configuration = pod_target.scheme_for_spec(spec)
228
- unless scheme_configuration.empty?
252
+ if !scheme_configuration.empty? || is_custom_host
229
253
  scheme_path = Xcodeproj::XCScheme.user_data_dir(project.path) + "#{scheme_name}.xcscheme"
230
254
  scheme = Xcodeproj::XCScheme.new(scheme_path)
231
255
  command_line_arguments = scheme.launch_action.command_line_arguments
@@ -241,6 +265,21 @@ module Pod
241
265
  if scheme_configuration.key?(:code_coverage)
242
266
  scheme.test_action.code_coverage_enabled = scheme_configuration[:code_coverage]
243
267
  end
268
+
269
+ hosted_test_specs_by_host[spec].each do |hosted_spec|
270
+ # We are an app spec which hosts this test spec.
271
+ # Include the test specs's test bundle within our scheme's test action
272
+ native_target = generator_result.native_target_for_spec(hosted_spec)
273
+ testable = Xcodeproj::XCScheme::TestAction::TestableReference.new(native_target)
274
+ scheme.test_action.add_testable(testable)
275
+ end
276
+
277
+ if spec.test_specification?
278
+ # Default to using the test bundle to expand variables
279
+ native_target_for_expansion = generator_result.native_target_for_spec(spec)
280
+ macro_expansion = Xcodeproj::XCScheme::MacroExpansion.new(native_target_for_expansion)
281
+ scheme.launch_action.add_macro_expansion(macro_expansion)
282
+ end
244
283
  scheme.save!
245
284
  end
246
285
  Xcodeproj::XCScheme.share_scheme(project.path, scheme_name) if share_scheme
@@ -28,6 +28,25 @@ module Pod
28
28
  @projects_by_pod_targets = projects_by_pod_targets
29
29
  @target_installation_results = target_installation_results
30
30
  end
31
+
32
+ # @param [Pod::Specification] spec
33
+ # A spec which was included in the generated project
34
+ #
35
+ # @return [Xcodeproj::PBXNativeTarget] the native target for the spec
36
+ #
37
+ def native_target_for_spec(spec)
38
+ installation_results_by_spec[spec.root].native_target_for_spec(spec)
39
+ end
40
+
41
+ private
42
+
43
+ def installation_results_by_spec
44
+ @target_installation_results_by_spec ||= begin
45
+ target_installation_results.pod_target_installation_results.values.each_with_object({}) do |installation_results, hash|
46
+ hash[installation_results.target.root_spec] = installation_results
47
+ end
48
+ end
49
+ end
31
50
  end
32
51
  end
33
52
  end
@@ -115,7 +115,7 @@ module Pod
115
115
  target_errors = swift_target_definitions.map(&error_message_for_target_definition).to_sentence
116
116
  "- `#{swift_pod_target.name}` is integrated by multiple targets that use a different Swift version: #{target_errors}."
117
117
  end
118
- elsif swift_pod_target.swift_version.empty?
118
+ elsif !swift_pod_target.swift_version.nil? && swift_pod_target.swift_version.empty?
119
119
  "- `#{swift_pod_target.name}` does not specify a Swift version (#{swift_pod_target.spec_swift_versions.map { |v| "`#{v}`" }.to_sentence}) " \
120
120
  "that is satisfied by any of targets (#{swift_pod_target.target_definitions.map { |td| "`#{td.name}`" }.to_sentence}) integrating it."
121
121
  end
@@ -34,6 +34,8 @@ module Pod
34
34
  autoload :InstallationOptions, 'cocoapods/installer/installation_options'
35
35
  autoload :PostInstallHooksContext, 'cocoapods/installer/post_install_hooks_context'
36
36
  autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context'
37
+ autoload :BaseInstallHooksContext, 'cocoapods/installer/base_install_hooks_context'
38
+ autoload :PostIntegrateHooksContext, 'cocoapods/installer/post_integrate_hooks_context'
37
39
  autoload :SourceProviderHooksContext, 'cocoapods/installer/source_provider_hooks_context'
38
40
  autoload :PodfileValidator, 'cocoapods/installer/podfile_validator'
39
41
  autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
@@ -47,6 +49,8 @@ module Pod
47
49
 
48
50
  include Config::Mixin
49
51
 
52
+ MASTER_SPECS_REPO_GIT_URL = 'https://github.com/CocoaPods/Specs.git'.freeze
53
+
50
54
  # @return [Sandbox] The sandbox where the Pods should be installed.
51
55
  #
52
56
  attr_reader :sandbox
@@ -331,7 +335,7 @@ module Pod
331
335
  all_projects_by_pod_targets.merge!(pods_project_by_targets) if pods_project_by_targets
332
336
  all_projects_by_pod_targets.merge!(projects_by_pod_targets) if projects_by_pod_targets
333
337
  all_projects_by_pod_targets.each do |project, pod_targets|
334
- generator.configure_schemes(project, pod_targets)
338
+ generator.configure_schemes(project, pod_targets, pod_project_generation_result)
335
339
  end
336
340
  end
337
341
  end
@@ -494,7 +498,7 @@ module Pod
494
498
  previous_version = sandbox.manifest.version(spec.name)
495
499
  has_changed_version = current_version != previous_version
496
500
  current_repo = analysis_result.specs_by_source.detect { |key, values| break key if values.map(&:name).include?(spec.name) }
497
- current_repo &&= current_repo.url || current_repo.name
501
+ current_repo &&= (Pod::TrunkSource::TRUNK_REPO_NAME if current_repo.name == Pod::TrunkSource::TRUNK_REPO_NAME) || current_repo.url || current_repo.name
498
502
  previous_spec_repo = sandbox.manifest.spec_repo(spec.name)
499
503
  has_changed_repo = !previous_spec_repo.nil? && current_repo && !current_repo.casecmp(previous_spec_repo).zero?
500
504
  title = "Installing #{spec.name} #{spec.version}"
@@ -563,6 +567,7 @@ module Pod
563
567
  #
564
568
  def clean_pod_sources
565
569
  return unless installation_options.clean?
570
+ return if installed_specs.empty?
566
571
  pod_installers.each(&:clean!)
567
572
  end
568
573
 
@@ -607,6 +612,7 @@ module Pod
607
612
  run_plugins_post_install_hooks
608
613
  warn_for_deprecations
609
614
  warn_for_installed_script_phases
615
+ warn_for_removing_git_master_specs_repo
610
616
  print_post_install_message
611
617
  end
612
618
 
@@ -635,12 +641,27 @@ module Pod
635
641
  lock_pod_sources
636
642
  end
637
643
 
644
+ # Runs the registered callbacks for the plugins post integrate hooks.
645
+ #
646
+ def run_plugins_post_integrate_hooks
647
+ if any_plugin_post_integrate_hooks?
648
+ context = PostIntegrateHooksContext.generate(sandbox, pods_project, aggregate_targets)
649
+ HooksManager.run(:post_integrate, context, plugins)
650
+ end
651
+ end
652
+
638
653
  # @return [Boolean] whether there are any plugin post-install hooks to run
639
654
  #
640
655
  def any_plugin_post_install_hooks?
641
656
  HooksManager.hooks_to_run(:post_install, plugins).any?
642
657
  end
643
658
 
659
+ # @return [Boolean] whether there are any plugin post-integrate hooks to run
660
+ #
661
+ def any_plugin_post_integrate_hooks?
662
+ HooksManager.hooks_to_run(:post_integrate, plugins).any?
663
+ end
664
+
644
665
  # Runs the registered callbacks for the source provider plugin hooks.
645
666
  #
646
667
  # @return [Array<Pod::Source>] the plugin sources
@@ -686,7 +707,7 @@ module Pod
686
707
  end
687
708
  end
688
709
 
689
- DEFAULT_PLUGINS = { 'cocoapods-stats' => {} }
710
+ DEFAULT_PLUGINS = {}
690
711
 
691
712
  # Returns the plugins that should be run, as indicated by the default
692
713
  # plugins and the podfile's plugins
@@ -736,6 +757,24 @@ module Pod
736
757
  end
737
758
  end
738
759
 
760
+ # Prints a warning if the project is not explicitly using the git based master specs repo.
761
+ #
762
+ # Helps users to delete the git based master specs repo from the repos directory which reduces `--repo-update`
763
+ # speed and hopefully reduces Github workload.
764
+ #
765
+ # @return [void]
766
+ #
767
+ def warn_for_removing_git_master_specs_repo
768
+ return unless installation_options.warn_for_unused_master_specs_repo?
769
+ podfile_master_source = podfile.sources.find { |source| source == MASTER_SPECS_REPO_GIT_URL }
770
+ master_repo = config.sources_manager.all.find { |s| s.url == MASTER_SPECS_REPO_GIT_URL }
771
+ if podfile_master_source.nil? && !master_repo.nil?
772
+ UI.warn 'Your project does not explicitly specify the CocoaPods master specs repo. Since CDN is now used as the' \
773
+ ' default, you may safely remove it from your repos directory via `pod repo remove master`. To suppress this warning' \
774
+ ' please add `warn_for_unused_master_specs_repo => false` to your Podfile.'
775
+ end
776
+ end
777
+
739
778
  # @return [Lockfile] The lockfile to write to disk.
740
779
  #
741
780
  def generate_lockfile
@@ -799,6 +838,7 @@ module Pod
799
838
  integrator = UserProjectIntegrator.new(podfile, sandbox, installation_root, aggregate_targets, generated_aggregate_targets,
800
839
  :use_input_output_paths => !installation_options.disable_input_output_paths?)
801
840
  integrator.integrate!
841
+ run_podfile_post_integrate_hooks
802
842
  end
803
843
  end
804
844
 
@@ -861,6 +901,33 @@ module Pod
861
901
  "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
862
902
  end
863
903
 
904
+ # Runs the post integrate hooks of the installed specs and of the Podfile.
905
+ #
906
+ # @note Post integrate hooks run _after_ saving of project, so that they
907
+ # can alter it after it is written to the disk.
908
+ #
909
+ # @return [void]
910
+ #
911
+ def run_podfile_post_integrate_hooks
912
+ UI.message '- Running post integrate hooks' do
913
+ executed = run_podfile_post_integrate_hook
914
+ UI.message '- Podfile' if executed
915
+ end
916
+ end
917
+
918
+ # Runs the post integrate hook of the Podfile.
919
+ #
920
+ # @raise Raises an informative if the hooks raises.
921
+ #
922
+ # @return [Boolean] Whether the hook was run.
923
+ #
924
+ def run_podfile_post_integrate_hook
925
+ podfile.post_integrate!(self)
926
+ rescue => e
927
+ raise Informative, 'An error occurred while processing the post-integrate ' \
928
+ 'hook of the Podfile.' \
929
+ "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
930
+ end
864
931
  #-------------------------------------------------------------------------#
865
932
 
866
933
  public
@@ -172,6 +172,15 @@ module Pod
172
172
  end
173
173
  end
174
174
 
175
+ # @return [Array<Pathname>] The paths of the dynamic xcframework bundles
176
+ # that come shipped with the Pod.
177
+ #
178
+ def vendored_static_xcframeworks
179
+ vendored_xcframeworks.select do |path|
180
+ Xcode::XCFramework.new(path).build_type == BuildType.static_framework
181
+ end
182
+ end
183
+
175
184
  # @return [Array<Pathname>] The paths of the static (fake) framework
176
185
  # bundles that come shipped with the Pod.
177
186
  #
@@ -289,7 +298,7 @@ module Pod
289
298
  # that come shipped with the Pod.
290
299
  #
291
300
  def vendored_static_artifacts
292
- vendored_static_libraries + vendored_static_frameworks
301
+ vendored_static_libraries + vendored_static_frameworks + vendored_static_xcframeworks
293
302
  end
294
303
 
295
304
  # @return [Hash{String => Array<Pathname>}] A hash that describes the
@@ -2,7 +2,6 @@ require 'cocoapods-core/source'
2
2
  require 'netrc'
3
3
  require 'set'
4
4
  require 'rest'
5
- require 'typhoeus'
6
5
  require 'yaml'
7
6
 
8
7
  module Pod
@@ -72,6 +71,8 @@ module Pod
72
71
  #
73
72
  def cdn_url?(url)
74
73
  if url =~ %r{^https?:\/\/}
74
+ require 'typhoeus'
75
+
75
76
  response = Typhoeus.get(url + '/CocoaPods-version.yml', :netrc_file => Netrc.default_path, :netrc => :optional)
76
77
  response.code == 200 && begin
77
78
  response_hash = YAML.load(response.body) # rubocop:disable Security/YAMLLoad
@@ -98,6 +98,7 @@ module Pod
98
98
  target_definition, client_root, user_project, user_target_uuids, merged).tap do |aggregate_target|
99
99
  aggregate_target.search_paths_aggregate_targets.concat(search_paths_aggregate_targets).freeze
100
100
  aggregate_target.mark_application_extension_api_only if application_extension_api_only
101
+ aggregate_target.mark_build_library_for_distribution if build_library_for_distribution
101
102
  end
102
103
  end
103
104
 
@@ -284,6 +285,20 @@ module Pod
284
285
  resources_by_config[config] = targets.flat_map do |pod_target|
285
286
  library_specs = pod_target.library_specs.map(&:name)
286
287
  resource_paths = pod_target.resource_paths.values_at(*library_specs).flatten
288
+
289
+ if pod_target.build_as_static_framework?
290
+ built_product_dir = Pathname.new(pod_target.build_product_path('${BUILT_PRODUCTS_DIR}'))
291
+ resource_paths = resource_paths.map do |resource_path|
292
+ extname = File.extname(resource_path)
293
+ if self.class.resource_extension_compilable?(extname)
294
+ output_extname = self.class.output_extension_for_resource(extname)
295
+ built_product_dir.join(File.basename(resource_path)).sub_ext(output_extname).to_s
296
+ else
297
+ resource_path
298
+ end
299
+ end
300
+ end
301
+
287
302
  resource_paths << bridge_support_file
288
303
  resource_paths.compact.uniq
289
304
  end
@@ -359,6 +374,10 @@ module Pod
359
374
  #
360
375
  # @return [Pathname] The absolute path of the prepare artifacts script input file list.
361
376
  #
377
+ # @deprecated
378
+ #
379
+ # @todo Remove in 2.0
380
+ #
362
381
  def prepare_artifacts_script_input_files_path(configuration)
363
382
  support_files_dir + "#{label}-artifacts-#{configuration}-input-files.xcfilelist"
364
383
  end
@@ -367,6 +386,10 @@ module Pod
367
386
  #
368
387
  # @return [Pathname] The absolute path of the prepare artifacts script output file list.
369
388
  #
389
+ # @deprecated
390
+ #
391
+ # @todo Remove in 2.0
392
+ #
370
393
  def prepare_artifacts_script_output_files_path(configuration)
371
394
  support_files_dir + "#{label}-artifacts-#{configuration}-output-files.xcfilelist"
372
395
  end
@@ -453,6 +476,10 @@ module Pod
453
476
  # @return [String] The path of the prepare artifacts script relative to the
454
477
  # root of the Pods project.
455
478
  #
479
+ # @deprecated
480
+ #
481
+ # @todo Remove in 2.0
482
+ #
456
483
  def prepare_artifacts_script_relative_path
457
484
  "${PODS_ROOT}/#{relative_to_pods_root(prepare_artifacts_script_path)}"
458
485
  end
@@ -460,6 +487,10 @@ module Pod
460
487
  # @return [String] The path of the prepare artifacts script input file list
461
488
  # relative to the root of the Pods project.
462
489
  #
490
+ # @deprecated
491
+ #
492
+ # @todo Remove in 2.0
493
+ #
463
494
  def prepare_artifacts_script_input_files_relative_path
464
495
  "${PODS_ROOT}/#{relative_to_pods_root(prepare_artifacts_script_input_files_path('${CONFIGURATION}'))}"
465
496
  end
@@ -467,6 +498,10 @@ module Pod
467
498
  # @return [String] The path of the prepare artifacts script output file list
468
499
  # relative to the root of the Pods project.
469
500
  #
501
+ # @deprecated
502
+ #
503
+ # @todo Remove in 2.0
504
+ #
470
505
  def prepare_artifacts_script_output_files_relative_path
471
506
  "${PODS_ROOT}/#{relative_to_pods_root(prepare_artifacts_script_output_files_path('${CONFIGURATION}'))}"
472
507
  end
@@ -43,7 +43,13 @@ module Pod
43
43
  # @return [String]
44
44
  # The variable for the configuration build directory used when building pod targets.
45
45
  #
46
- CONFIGURATION_BUILD_DIR_VARIABLE = '${PODS_CONFIGURATION_BUILD_DIR}'.freeze
46
+ CONFIGURATION_BUILD_DIR_VARIABLE = '${PODS_CONFIGURATION_BUILD_DIR}'
47
+
48
+ # @return [String]
49
+ # The variable for the configuration intermediate frameworks directory used for building pod targets
50
+ # that contain vendored xcframeworks.
51
+ #
52
+ XCFRAMEWORKS_BUILD_DIR_VARIABLE = '${PODS_XCFRAMEWORKS_BUILD_DIR}'
47
53
 
48
54
  #-------------------------------------------------------------------------#
49
55
 
@@ -95,7 +101,7 @@ module Pod
95
101
  from_search_paths_aggregate_targets: false, from_pod_targets_to_link: false,
96
102
  &implementation)
97
103
 
98
- memoized_key = "#{self}##{method_name}".freeze
104
+ memoized_key = "#{self}##{method_name}"
99
105
 
100
106
  (@build_settings_names ||= Set.new) << method_name.to_s.upcase if build_setting
101
107
 
@@ -134,6 +140,14 @@ module Pod
134
140
  end
135
141
  private_class_method :define_build_settings_method
136
142
 
143
+ # @param [XCFramework] xcframework the xcframework thats slice will be copied to the intermediates dir
144
+ #
145
+ # @return [String] the path to the directory containing the xcframework slice
146
+ #
147
+ def self.xcframework_intermediate_dir(xcframework)
148
+ "#{XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcframework.name}"
149
+ end
150
+
137
151
  class << self
138
152
  #-------------------------------------------------------------------------#
139
153
 
@@ -204,6 +218,10 @@ module Pod
204
218
  '${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
205
219
  end
206
220
 
221
+ define_build_settings_method :pods_xcframeworks_build_dir, :build_setting => true do
222
+ '$(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates'
223
+ end
224
+
207
225
  # @return [String]
208
226
  define_build_settings_method :use_recursive_script_inputs_in_script_phases, :build_setting => true do
209
227
  'YES'
@@ -314,6 +332,13 @@ module Pod
314
332
  false
315
333
  end
316
334
 
335
+ # Xcode 12 turns on this warning by default which is problematic for CocoaPods-generated
336
+ # imports which use double-quoted paths.
337
+ # @return [Boolean]
338
+ define_build_settings_method :clang_warn_quoted_include_in_framework_header, :build_setting => true do
339
+ 'NO'
340
+ end
341
+
317
342
  # @return [Array<String>]
318
343
  # the `LD_RUNPATH_SEARCH_PATHS` needed for dynamically linking the {#target}
319
344
  #
@@ -475,6 +500,14 @@ module Pod
475
500
  pod_targets - subset_targets
476
501
  end
477
502
 
503
+ # @param [Pathname,String] path the path to the xcframework bundle
504
+ #
505
+ # @return [Xcode::XCFramework] the xcframework at the given path
506
+ #
507
+ def load_xcframework(path)
508
+ Xcode::XCFramework.new(path)
509
+ end
510
+
478
511
  # A subclass that generates build settings for a {PodTarget}
479
512
  class PodTargetSettings < BuildSettings
480
513
  #-------------------------------------------------------------------------#
@@ -576,10 +609,13 @@ module Pod
576
609
  frameworks.concat consumer_frameworks
577
610
  if library_xcconfig?
578
611
  # We know that this library target is being built dynamically based
579
- # on the guard above, so include any vendored static frameworks.
612
+ # on the guard above, so include any vendored static frameworks and vendored xcframeworks.
580
613
  if target.should_build?
581
614
  frameworks.concat vendored_static_frameworks.map { |l| File.basename(l, '.framework') }
582
- frameworks.concat vendored_xcframeworks.map(&:name)
615
+ frameworks.concat vendored_xcframeworks.
616
+ select { |xcf| xcf.build_type.static_framework? }.
617
+ map(&:name).
618
+ uniq
583
619
  end
584
620
  # Also include any vendored dynamic frameworks of dependencies.
585
621
  frameworks.concat dependent_targets.reject(&:should_build?).flat_map { |pt| pt.build_settings[@configuration].dynamic_frameworks_to_import }
@@ -596,7 +632,7 @@ module Pod
596
632
  static_frameworks_to_import.concat vendored_static_frameworks.map { |f| File.basename(f, '.framework') } unless target.should_build? && target.build_as_dynamic?
597
633
  unless target.should_build? && target.build_as_dynamic?
598
634
  static_frameworks_to_import.concat vendored_xcframeworks.
599
- select(&:includes_static_slices?).
635
+ select { |xcf| xcf.build_type.static_framework? }.
600
636
  map(&:name).
601
637
  uniq
602
638
  end
@@ -608,7 +644,7 @@ module Pod
608
644
  define_build_settings_method :dynamic_frameworks_to_import, :memoized => true do
609
645
  dynamic_frameworks_to_import = vendored_dynamic_frameworks.map { |f| File.basename(f, '.framework') }
610
646
  dynamic_frameworks_to_import.concat vendored_xcframeworks.
611
- select(&:includes_dynamic_slices?).
647
+ select { |xcf| xcf.build_type.dynamic_framework? }.
612
648
  map(&:name).
613
649
  uniq
614
650
  dynamic_frameworks_to_import << target.product_basename if target.should_build? && target.build_as_dynamic_framework?
@@ -656,12 +692,11 @@ module Pod
656
692
  search_paths.concat file_accessors.
657
693
  flat_map(&:vendored_frameworks).
658
694
  map { |f| File.join '${PODS_ROOT}', f.dirname.relative_path_from(target.sandbox.root) }
659
- # Include each slice in the framework search paths.
660
- # Xcode will not search inside an .xcframework for headers within each slice
661
- search_paths.concat vendored_xcframeworks.
662
- flat_map(&:slices).
663
- select { |slice| slice.platform.symbolic_name == target.platform.symbolic_name }.
664
- flat_map { |slice| File.join '${PODS_ROOT}', slice.path.dirname.relative_path_from(target.sandbox.root) }
695
+ xcframework_intermediates = vendored_xcframeworks.
696
+ select { |xcf| xcf.build_type.framework? }.
697
+ map { |xcf| BuildSettings.xcframework_intermediate_dir(xcf) }.
698
+ uniq
699
+ search_paths.concat xcframework_intermediates
665
700
  search_paths
666
701
  end
667
702
 
@@ -686,7 +721,7 @@ module Pod
686
721
 
687
722
  # @return [Array<Xcode::XCFramework>]
688
723
  define_build_settings_method :vendored_xcframeworks, :memoized => true do
689
- file_accessors.flat_map(&:vendored_xcframeworks).map { |path| Xcode::XCFramework.new(path) }
724
+ file_accessors.flat_map(&:vendored_xcframeworks).map { |path| load_xcframework(path) }
690
725
  end
691
726
 
692
727
  # @return [Array<String>]
@@ -707,7 +742,7 @@ module Pod
707
742
  # @return [Array<String>]
708
743
  #
709
744
  def linker_names_from_libraries(libraries)
710
- libraries.map { |l| File.basename(l, l.extname).sub(/\Alib/, '') }
745
+ libraries.map { |l| File.basename(l, File.extname(l)).sub(/\Alib/, '') }
711
746
  end
712
747
 
713
748
  # @return [Array<String>]
@@ -718,6 +753,11 @@ module Pod
718
753
  if non_library_xcconfig? || target.build_as_dynamic?
719
754
  libraries.concat linker_names_from_libraries(vendored_static_libraries)
720
755
  libraries.concat libraries_to_import
756
+ xcframework_libraries = vendored_xcframeworks.
757
+ select { |xcf| xcf.build_type.static_library? }.
758
+ flat_map { |xcf| linker_names_from_libraries([xcf.slices.first.binary_path]) }.
759
+ uniq
760
+ libraries.concat xcframework_libraries
721
761
  end
722
762
  if non_library_xcconfig?
723
763
  libraries.concat dependent_targets.flat_map { |pt| pt.build_settings[@configuration].dynamic_libraries_to_import }
@@ -729,7 +769,14 @@ module Pod
729
769
  # @return [Array<String>]
730
770
  define_build_settings_method :static_libraries_to_import, :memoized => true do
731
771
  static_libraries_to_import = []
732
- static_libraries_to_import.concat linker_names_from_libraries(vendored_static_libraries) unless target.should_build? && target.build_as_dynamic?
772
+ unless target.should_build? && target.build_as_dynamic?
773
+ static_libraries_to_import.concat linker_names_from_libraries(vendored_static_libraries)
774
+ xcframework_libraries = vendored_xcframeworks.
775
+ select { |xcf| xcf.build_type.static_library? }.
776
+ flat_map { |xcf| linker_names_from_libraries([xcf.slices.first.binary_path]) }.
777
+ uniq
778
+ static_libraries_to_import.concat linker_names_from_libraries(xcframework_libraries)
779
+ end
733
780
  static_libraries_to_import << target.product_basename if target.should_build? && target.build_as_static_library?
734
781
  static_libraries_to_import
735
782
  end
@@ -775,12 +822,20 @@ module Pod
775
822
 
776
823
  # @return [Array<String>]
777
824
  define_build_settings_method :vendored_static_library_search_paths, :memoized => true do
778
- vendored_static_libraries.map { |f| File.join '${PODS_ROOT}', f.dirname.relative_path_from(target.sandbox.root) }
825
+ paths = vendored_static_libraries.map { |f| File.join '${PODS_ROOT}', f.dirname.relative_path_from(target.sandbox.root) }
826
+ paths.concat vendored_xcframeworks.
827
+ select { |xcf| xcf.build_type.static_library? }.
828
+ map { |xcf| BuildSettings.xcframework_intermediate_dir(xcf) }
829
+ paths
779
830
  end
780
831
 
781
832
  # @return [Array<String>]
782
833
  define_build_settings_method :vendored_dynamic_library_search_paths, :memoized => true do
783
- vendored_dynamic_libraries.map { |f| File.join '${PODS_ROOT}', f.dirname.relative_path_from(target.sandbox.root) }
834
+ paths = vendored_dynamic_libraries.map { |f| File.join '${PODS_ROOT}', f.dirname.relative_path_from(target.sandbox.root) }
835
+ paths.concat vendored_xcframeworks.
836
+ select { |xcf| xcf.build_type.dynamic_library? }.
837
+ map { |xcf| BuildSettings.xcframework_intermediate_dir(xcf) }
838
+ paths
784
839
  end
785
840
 
786
841
  # @return [Array<String>]
@@ -816,7 +871,16 @@ module Pod
816
871
 
817
872
  # @return [Array<String>]
818
873
  define_build_settings_method :header_search_paths, :build_setting => true, :memoized => true, :sorted => true do
819
- target.header_search_paths(:include_dependent_targets_for_test_spec => test_xcconfig? && non_library_spec, :include_dependent_targets_for_app_spec => app_xcconfig? && non_library_spec, :configuration => @configuration)
874
+ paths = target.header_search_paths(:include_dependent_targets_for_test_spec => test_xcconfig? && non_library_spec, :include_dependent_targets_for_app_spec => app_xcconfig? && non_library_spec, :configuration => @configuration)
875
+
876
+ dependent_vendored_xcframeworks = []
877
+ dependent_vendored_xcframeworks.concat vendored_xcframeworks
878
+ dependent_vendored_xcframeworks.concat dependent_targets.flat_map { |pt| pt.build_settings[@configuration].vendored_xcframeworks }
879
+ paths.concat dependent_vendored_xcframeworks.
880
+ select { |xcf| xcf.build_type.static_library? }.
881
+ map { |xcf| "#{BuildSettings.xcframework_intermediate_dir(xcf)}/Headers" }.
882
+ compact
883
+ paths
820
884
  end
821
885
 
822
886
  # @return [Array<String>]
@@ -912,6 +976,11 @@ module Pod
912
976
  target.application_extension_api_only ? 'YES' : nil
913
977
  end
914
978
 
979
+ # @return [String]
980
+ define_build_settings_method :build_library_for_distribution, :build_setting => true, :memoized => true do
981
+ target.build_library_for_distribution ? 'YES' : nil
982
+ end
983
+
915
984
  #-------------------------------------------------------------------------#
916
985
 
917
986
  # @!group Target Properties
@@ -1098,6 +1167,13 @@ module Pod
1098
1167
  select { |pt| pt.build_as_framework? && pt.should_build? }.
1099
1168
  map { |pt| pt.build_settings[@configuration].framework_header_search_path }
1100
1169
 
1170
+ xcframework_library_headers = pod_targets.flat_map { |pt| pt.build_settings[@configuration].vendored_xcframeworks }.
1171
+ select { |xcf| xcf.build_type.static_library? }.
1172
+ map { |xcf| "#{BuildSettings.xcframework_intermediate_dir(xcf)}/Headers" }.
1173
+ compact
1174
+
1175
+ paths.concat xcframework_library_headers
1176
+
1101
1177
  paths.concat target.search_paths_aggregate_targets.flat_map { |at| at.build_settings(configuration_name).header_search_paths }
1102
1178
 
1103
1179
  paths