Class: Pod::PodTarget

Inherits:
Target
  • Object
show all
Defined in:
lib/cocoapods/target/pod_target.rb

Overview

Stores the information relative to the target used to compile a single Pod. A pod can have one or more activated spec, subspecs and test specs.

Constant Summary

Constants inherited from Target

Target::DEFAULT_BUILD_CONFIGURATIONS, Target::DEFAULT_NAME, Target::DEFAULT_VERSION

Instance Attribute Summary collapse

Attributes inherited from Target

#application_extension_api_only, #archs, #build_library_for_distribution, #build_settings, #platform, #sandbox, #user_build_configurations

Instance Method Summary collapse

Methods inherited from Target

#bridge_support_path, #build_as_dynamic?, #build_as_dynamic_framework?, #build_as_dynamic_library?, #build_as_framework?, #build_as_library?, #build_as_static?, #build_as_static_framework?, #build_as_static_library?, #dummy_source_path, #framework_name, #info_plist_path, #inspect, #mark_application_extension_api_only, #mark_build_library_for_distribution, #module_map_path_to_write, #name, output_extension_for_resource, #prepare_artifacts_script_path, #product_basename, #product_name, #product_type, #requires_frameworks?, resource_extension_compilable?, #static_framework?, #static_library_name, #support_files_dir, #umbrella_header_path, #umbrella_header_path_to_write, #xcconfig_path

Constructor Details

#initialize(sandbox, build_type, user_build_configurations, archs, platform, specs, target_definitions, file_accessors = [], scope_suffix = nil, swift_version = nil) ⇒ PodTarget

Initialize a new instance



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/cocoapods/target/pod_target.rb', line 137

def initialize(sandbox, build_type, user_build_configurations, archs, platform, specs, target_definitions,
               file_accessors = [], scope_suffix = nil, swift_version = nil)
  super(sandbox, build_type, user_build_configurations, archs, platform)
  raise "Can't initialize a PodTarget without specs!" if specs.nil? || specs.empty?
  raise "Can't initialize a PodTarget without TargetDefinition!" if target_definitions.nil? || target_definitions.empty?
  raise "Can't initialize a PodTarget with an empty string scope suffix!" if scope_suffix == ''
  @specs = specs.dup.freeze
  @target_definitions = target_definitions
  @file_accessors = file_accessors
  @scope_suffix = scope_suffix
  @swift_version = swift_version
  all_specs_by_type = @specs.group_by(&:spec_type)
  @library_specs = all_specs_by_type[:library] || []
  @test_specs = all_specs_by_type[:test] || []
  @app_specs = all_specs_by_type[:app] || []
  @build_headers = Sandbox::HeadersStore.new(sandbox, 'Private', :private)
  self.dependent_targets = []
  self.test_dependent_targets_by_spec_name = Hash[test_specs.map { |ts| [ts.name, []] }]
  self.app_dependent_targets_by_spec_name = Hash[app_specs.map { |as| [as.name, []] }]
  @test_app_hosts_by_spec = {}
  @build_config_cache = {}
  @test_spec_build_settings_by_config = create_test_build_settings_by_config
  @app_spec_build_settings_by_config = create_app_build_settings_by_config
end

Instance Attribute Details

#app_dependent_targets_by_spec_nameHash{String=>Array<PodTarget>}



88
89
90
# File 'lib/cocoapods/target/pod_target.rb', line 88

def app_dependent_targets_by_spec_name
  @app_dependent_targets_by_spec_name
end

#app_dependent_targets_by_spec_name_by_configObject

Returns the value of attribute app_dependent_targets_by_spec_name_by_config.



89
90
91
# File 'lib/cocoapods/target/pod_target.rb', line 89

def app_dependent_targets_by_spec_name_by_config
  @app_dependent_targets_by_spec_name_by_config
end

#app_spec_build_settingsHash{String => BuildSettings} (readonly)



117
118
119
# File 'lib/cocoapods/target/pod_target.rb', line 117

def app_spec_build_settings
  @app_spec_build_settings
end

#app_spec_build_settings_by_configObject (readonly)

Returns the value of attribute app_spec_build_settings_by_config.



118
119
120
# File 'lib/cocoapods/target/pod_target.rb', line 118

def app_spec_build_settings_by_config
  @app_spec_build_settings_by_config
end

#app_specsArray<Specification> (readonly)



26
27
28
# File 'lib/cocoapods/target/pod_target.rb', line 26

def app_specs
  @app_specs
end

#build_headersHeadersStore (readonly)



47
48
49
# File 'lib/cocoapods/target/pod_target.rb', line 47

def build_headers
  @build_headers
end

#dependent_targetsArray<PodTarget>



52
53
54
# File 'lib/cocoapods/target/pod_target.rb', line 52

def dependent_targets
  @dependent_targets
end

#dependent_targets_by_configObject

Returns the value of attribute dependent_targets_by_config.



53
54
55
# File 'lib/cocoapods/target/pod_target.rb', line 53

def dependent_targets_by_config
  @dependent_targets_by_config
end

#file_accessorsArray<Sandbox::FileAccessor> (readonly)



36
37
38
# File 'lib/cocoapods/target/pod_target.rb', line 36

def file_accessors
  @file_accessors
end

#library_specsArray<Specification> (readonly)



21
22
23
# File 'lib/cocoapods/target/pod_target.rb', line 21

def library_specs
  @library_specs
end

#scope_suffixString (readonly)

Note:

This affects the value returned by #configuration_build_dir and accessors relying on this as #build_product_path.

Returns the suffix used for this target when deduplicated. May be ‘nil`.



43
44
45
# File 'lib/cocoapods/target/pod_target.rb', line 43

def scope_suffix
  @scope_suffix
end

#specsArray<Specification> (readonly)



11
12
13
# File 'lib/cocoapods/target/pod_target.rb', line 11

def specs
  @specs
end

#swift_versionString (readonly)



122
123
124
# File 'lib/cocoapods/target/pod_target.rb', line 122

def swift_version
  @swift_version
end

#target_definitionsArray<TargetDefinition> (readonly)



31
32
33
# File 'lib/cocoapods/target/pod_target.rb', line 31

def target_definitions
  @target_definitions
end

#test_app_hosts_by_specHash{Specification => (Specification,PodTarget)}



108
109
110
# File 'lib/cocoapods/target/pod_target.rb', line 108

def test_app_hosts_by_spec
  @test_app_hosts_by_spec
end

#test_dependent_targets_by_spec_nameHash{String=>Array<PodTarget>}



68
69
70
# File 'lib/cocoapods/target/pod_target.rb', line 68

def test_dependent_targets_by_spec_name
  @test_dependent_targets_by_spec_name
end

#test_dependent_targets_by_spec_name_by_configObject

Returns the value of attribute test_dependent_targets_by_spec_name_by_config.



69
70
71
# File 'lib/cocoapods/target/pod_target.rb', line 69

def test_dependent_targets_by_spec_name_by_config
  @test_dependent_targets_by_spec_name_by_config
end

#test_spec_build_settingsHash{String => BuildSettings} (readonly)



112
113
114
# File 'lib/cocoapods/target/pod_target.rb', line 112

def test_spec_build_settings
  @test_spec_build_settings
end

#test_spec_build_settings_by_configObject (readonly)

Returns the value of attribute test_spec_build_settings_by_config.



113
114
115
# File 'lib/cocoapods/target/pod_target.rb', line 113

def test_spec_build_settings_by_config
  @test_spec_build_settings_by_config
end

#test_specsArray<Specification> (readonly)



16
17
18
# File 'lib/cocoapods/target/pod_target.rb', line 16

def test_specs
  @test_specs
end

Instance Method Details

#all_filesArray<Pathname>



208
209
210
# File 'lib/cocoapods/target/pod_target.rb', line 208

def all_files
  Sandbox::FileAccessor.all_files(file_accessors)
end

#app_host_dependent_targets_for_spec(spec, configuration: nil) ⇒ Array<PodTarget>



632
633
634
635
636
637
638
639
640
641
# File 'lib/cocoapods/target/pod_target.rb', line 632

def app_host_dependent_targets_for_spec(spec, configuration: nil)
  return [] unless spec.test_specification? && spec.consumer(platform).test_type == :unit
  app_host_info = test_app_hosts_by_spec[spec]
  if app_host_info.nil?
    []
  else
    app_spec, app_target = *app_host_info
    app_target.dependent_targets_for_app_spec(app_spec, :configuration => configuration)
  end
end

#app_host_target_label(test_spec) ⇒ (String,String)



614
615
616
617
618
619
620
621
622
# File 'lib/cocoapods/target/pod_target.rb', line 614

def app_host_target_label(test_spec)
  app_spec, app_target = test_app_hosts_by_spec[test_spec]

  if app_spec
    [app_target.name, app_target.app_target_label(app_spec)]
  elsif test_spec.consumer(platform).requires_app_host?
    [name, "AppHost-#{label}-#{label_for_test_type(test_spec.test_type)}-Tests"]
  end
end

#app_spec_consumersArray<Specification::Consumer>



317
318
319
# File 'lib/cocoapods/target/pod_target.rb', line 317

def app_spec_consumers
  app_specs.map { |app_spec| app_spec.consumer(platform) }
end

#app_target_label(app_spec) ⇒ String



604
605
606
# File 'lib/cocoapods/target/pod_target.rb', line 604

def app_target_label(app_spec)
  "#{label}-#{subspec_label(app_spec)}"
end

#build_product_path(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE) ⇒ String



990
991
992
# File 'lib/cocoapods/target/pod_target.rb', line 990

def build_product_path(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE)
  "#{configuration_build_dir(dir)}/#{product_name}"
end

#build_settings_by_config_for_spec(spec) ⇒ Object



1052
1053
1054
1055
1056
1057
1058
# File 'lib/cocoapods/target/pod_target.rb', line 1052

def build_settings_by_config_for_spec(spec)
  case spec.spec_type
  when :test then test_spec_build_settings_by_config[spec.name]
  when :app  then app_spec_build_settings_by_config[spec.name]
  else            build_settings
  end || raise(ArgumentError, "No build settings for #{spec}")
end

#build_settings_for_spec(spec, configuration: nil) ⇒ BuildSettings::PodTargetSettings

Returns The build settings for the given spec.

Raises:

  • (ArgumentError)


1046
1047
1048
1049
1050
# File 'lib/cocoapods/target/pod_target.rb', line 1046

def build_settings_for_spec(spec, configuration: nil)
  raise ArgumentError, 'Must give configuration' unless configuration
  configuration = user_build_configurations[configuration] if user_build_configurations.key?(configuration)
  build_settings_by_config_for_spec(spec)[configuration] || raise(ArgumentError, "No build settings for #{spec} (configuration #{configuration.inspect}) (known configurations #{config_variants})")
end

#configuration_build_dir(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE) ⇒ String



981
982
983
# File 'lib/cocoapods/target/pod_target.rb', line 981

def configuration_build_dir(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE)
  "#{dir}/#{label}"
end

#contains_app_specifications?Boolean



399
400
401
# File 'lib/cocoapods/target/pod_target.rb', line 399

def contains_app_specifications?
  !app_specs.empty?
end

#contains_script_phases?Boolean



387
388
389
# File 'lib/cocoapods/target/pod_target.rb', line 387

def contains_script_phases?
  !script_phases.empty?
end

#contains_test_specifications?Boolean



393
394
395
# File 'lib/cocoapods/target/pod_target.rb', line 393

def contains_test_specifications?
  !test_specs.empty?
end

#copy_dsyms_script_input_files_pathPathname



785
786
787
# File 'lib/cocoapods/target/pod_target.rb', line 785

def copy_dsyms_script_input_files_path
  support_files_dir + "#{label}-copy-dsyms-input-files.xcfilelist"
end

#copy_dsyms_script_output_files_pathPathname



791
792
793
# File 'lib/cocoapods/target/pod_target.rb', line 791

def copy_dsyms_script_output_files_path
  support_files_dir + "#{label}-copy-dsyms-output-files.xcfilelist"
end

#copy_dsyms_script_pathPathname



779
780
781
# File 'lib/cocoapods/target/pod_target.rb', line 779

def copy_dsyms_script_path
  support_files_dir + "#{label}-copy-dsyms.sh"
end

#copy_resources_script_input_files_path_for_spec(spec) ⇒ Pathname



680
681
682
# File 'lib/cocoapods/target/pod_target.rb', line 680

def copy_resources_script_input_files_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-resources-input-files.xcfilelist"
end

#copy_resources_script_output_files_path_for_spec(spec) ⇒ Pathname



689
690
691
# File 'lib/cocoapods/target/pod_target.rb', line 689

def copy_resources_script_output_files_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-resources-output-files.xcfilelist"
end

#copy_resources_script_path_for_spec(spec) ⇒ Pathname



671
672
673
# File 'lib/cocoapods/target/pod_target.rb', line 671

def copy_resources_script_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-resources.sh"
end

#copy_xcframeworks_script_input_files_pathString



728
729
730
# File 'lib/cocoapods/target/pod_target.rb', line 728

def copy_xcframeworks_script_input_files_path
  support_files_dir + "#{label}-xcframeworks-input-files.xcfilelist"
end

#copy_xcframeworks_script_output_files_pathString



734
735
736
# File 'lib/cocoapods/target/pod_target.rb', line 734

def copy_xcframeworks_script_output_files_path
  support_files_dir + "#{label}-xcframeworks-output-files.xcfilelist"
end

#copy_xcframeworks_script_pathPathname



722
723
724
# File 'lib/cocoapods/target/pod_target.rb', line 722

def copy_xcframeworks_script_path
  support_files_dir + "#{label}-xcframeworks.sh"
end

#defines_module?Boolean

Note:

Static library targets can temporarily opt in to this behavior by setting ‘DEFINES_MODULE = YES` in their specification’s ‘pod_target_xcconfig`.

Returns Whether the target defines a “module” (and thus will need a module map and umbrella header).



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/cocoapods/target/pod_target.rb', line 359

def defines_module?
  return @defines_module if defined?(@defines_module)
  return @defines_module = true if uses_swift? || build_as_framework?

  explicit_target_definitions = target_definitions.select { |td| td.dependencies.any? { |d| d.root_name == pod_name } }
  tds_by_answer = explicit_target_definitions.group_by { |td| td.build_pod_as_module?(pod_name) }

  if tds_by_answer.size > 1
    UI.warn "Unable to determine whether to build `#{label}` as a module due to a conflict " \
      "between the following target definitions:\n\t- #{tds_by_answer.map do |a, td|
                                                          "`#{td.to_sentence}` #{a ? "requires `#{label}` as a module" : "does not require `#{label}` as a module"}"
                                                        end.join("\n\t- ")}\n\n" \
      "Defaulting to skip building `#{label}` as a module."
  elsif tds_by_answer.keys.first == true || target_definitions.all? { |td| td.build_pod_as_module?(pod_name) }
    return @defines_module = true
  end

  @defines_module = library_specs.any? { |s| s.consumer(platform).pod_target_xcconfig['DEFINES_MODULE'] == 'YES' }
end

#dependenciesArray<String>



816
817
818
819
820
# File 'lib/cocoapods/target/pod_target.rb', line 816

def dependencies
  spec_consumers.flat_map do |consumer|
    consumer.dependencies.map { |dep| Specification.root_name(dep.name) }
  end.uniq
end

#dependent_targets_for_app_spec(app_spec, configuration: nil) ⇒ Array<PodTarget>



944
945
946
# File 'lib/cocoapods/target/pod_target.rb', line 944

def dependent_targets_for_app_spec(app_spec, configuration: nil)
  [self, *recursive_dependent_targets(:configuration => configuration), *recursive_app_dependent_targets(app_spec, :configuration => configuration)].uniq
end

#dependent_targets_for_test_spec(test_spec, configuration: nil) ⇒ Array<PodTarget>



897
898
899
# File 'lib/cocoapods/target/pod_target.rb', line 897

def dependent_targets_for_test_spec(test_spec, configuration: nil)
  [self, *recursive_dependent_targets(:configuration => configuration), *recursive_test_dependent_targets(test_spec, :configuration => configuration)].uniq
end

#deployment_target_for_non_library_spec(spec) ⇒ String

Returns The deployment target to use for the non library spec. If the non library spec explicitly specifies one then this is the one used otherwise the one that was determined by the analyzer is used.

Raises:

  • (ArgumentError)


489
490
491
492
# File 'lib/cocoapods/target/pod_target.rb', line 489

def deployment_target_for_non_library_spec(spec)
  raise ArgumentError, 'Must be a non library spec.' unless spec.non_library_specification?
  spec.deployment_target(platform.name.to_s) || platform.deployment_target.to_s
end

#embed_frameworks_script_input_files_path_for_spec(spec) ⇒ Pathname



707
708
709
# File 'lib/cocoapods/target/pod_target.rb', line 707

def embed_frameworks_script_input_files_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-frameworks-input-files.xcfilelist"
end

#embed_frameworks_script_output_files_path_for_spec(spec) ⇒ Pathname



716
717
718
# File 'lib/cocoapods/target/pod_target.rb', line 716

def embed_frameworks_script_output_files_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-frameworks-output-files.xcfilelist"
end

#embed_frameworks_script_path_for_spec(spec) ⇒ Pathname



698
699
700
# File 'lib/cocoapods/target/pod_target.rb', line 698

def embed_frameworks_script_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-frameworks.sh"
end

#framework_pathsHash{String=>Array<Xcode::FrameworkPaths>}



407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/cocoapods/target/pod_target.rb', line 407

def framework_paths
  @framework_paths ||= begin
    file_accessors.each_with_object({}) do |file_accessor, hash|
      frameworks = file_accessor.vendored_dynamic_artifacts.map do |framework_path|
        relative_path_to_sandbox = framework_path.relative_path_from(sandbox.root)
        framework_source = "${PODS_ROOT}/#{relative_path_to_sandbox}"
        # Until this can be configured, assume the dSYM file uses the file name as the framework.
        # See https://github.com/CocoaPods/CocoaPods/issues/1698
        dsym_name = "#{framework_path.basename}.dSYM"
        dsym_path = Pathname.new("#{framework_path.dirname}/#{dsym_name}")
        dsym_source = if dsym_path.exist?
                        "${PODS_ROOT}/#{relative_path_to_sandbox}.dSYM"
                      end
        dirname = framework_path.dirname
        bcsymbolmap_paths = if dirname.exist?
                              Dir.chdir(dirname) do
                                Dir.glob('*.bcsymbolmap').map do |bcsymbolmap_file_name|
                                  bcsymbolmap_path = dirname + bcsymbolmap_file_name
                                  "${PODS_ROOT}/#{bcsymbolmap_path.relative_path_from(sandbox.root)}"
                                end
                              end
                            end
        Xcode::FrameworkPaths.new(framework_source, dsym_source, bcsymbolmap_paths)
      end
      if file_accessor.spec.library_specification? && should_build? && build_as_dynamic_framework?
        frameworks << Xcode::FrameworkPaths.new(build_product_path('${BUILT_PRODUCTS_DIR}'))
      end
      hash[file_accessor.spec.name] = frameworks
    end
  end
end

#header_mappings_by_file_accessorHash{FileAccessor => Hash}



220
221
222
223
224
225
226
227
# File 'lib/cocoapods/target/pod_target.rb', line 220

def header_mappings_by_file_accessor
  valid_accessors = file_accessors.reject { |fa| fa.spec.non_library_specification? }
  Hash[valid_accessors.map do |file_accessor|
    # Private headers will always end up in Pods/Headers/Private/PodA/*.h
    # This will allow for `""` imports to work.
    [file_accessor, header_mappings(file_accessor, file_accessor.headers)]
  end]
end

#header_search_paths(include_dependent_targets_for_test_spec: nil, include_dependent_targets_for_app_spec: nil, include_private_headers: true, configuration: nil) ⇒ Array<String>



1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
# File 'lib/cocoapods/target/pod_target.rb', line 1022

def header_search_paths(include_dependent_targets_for_test_spec: nil, include_dependent_targets_for_app_spec: nil,
                        include_private_headers: true, configuration: nil)
  header_search_paths = []
  header_search_paths.concat(build_headers.search_paths(platform, nil, false)) if include_private_headers
  header_search_paths.concat(sandbox.public_headers.search_paths(platform, pod_name, uses_modular_headers?))
  dependent_targets = recursive_dependent_targets(:configuration => configuration)
  if include_dependent_targets_for_test_spec
    dependent_targets += recursive_test_dependent_targets(include_dependent_targets_for_test_spec, :configuration => configuration)
  end
  if include_dependent_targets_for_app_spec
    dependent_targets += recursive_app_dependent_targets(include_dependent_targets_for_app_spec, :configuration => configuration)
  end
  dependent_targets.uniq.each do |dependent_target|
    header_search_paths.concat(sandbox.public_headers.search_paths(platform, dependent_target.pod_name, defines_module? && dependent_target.uses_modular_headers?(false)))
  end
  header_search_paths.uniq
end

#headers_sandboxPathname



214
215
216
# File 'lib/cocoapods/target/pod_target.rb', line 214

def headers_sandbox
  Pathname.new(pod_name)
end

#info_plist_entriesHash



567
568
569
# File 'lib/cocoapods/target/pod_target.rb', line 567

def info_plist_entries
  root_spec.info_plist
end

#info_plist_path_for_spec(spec) ⇒ Pathname



800
801
802
# File 'lib/cocoapods/target/pod_target.rb', line 800

def info_plist_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-Info.plist"
end

#inhibit_warnings?Boolean

Checks if warnings should be inhibited for this pod.



952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
# File 'lib/cocoapods/target/pod_target.rb', line 952

def inhibit_warnings?
  return @inhibit_warnings if defined? @inhibit_warnings
  whitelists = target_definitions.map do |target_definition|
    target_definition.inhibits_warnings_for_pod?(root_spec.name)
  end.uniq

  if whitelists.empty?
    @inhibit_warnings = false
    false
  elsif whitelists.count == 1
    @inhibit_warnings = whitelists.first
    whitelists.first
  else
    UI.warn "The pod `#{pod_name}` is linked to different targets " \
      "(#{target_definitions.map { |td| "`#{td.name}`" }.to_sentence}), which contain different " \
      'settings to inhibit warnings. CocoaPods does not currently ' \
      'support different settings and will fall back to your preference ' \
      'set in the root target definition.'
    @inhibit_warnings = podfile.root_target_definitions.first.inhibits_warnings_for_pod?(root_spec.name)
  end
end

#labelString



198
199
200
201
202
203
204
# File 'lib/cocoapods/target/pod_target.rb', line 198

def label
  if scope_suffix.nil? || scope_suffix[0] == '.'
    "#{root_spec.name}#{scope_suffix}"
  else
    "#{root_spec.name}-#{scope_suffix}"
  end
end

#label_for_test_type(test_type) ⇒ String

Returns the label to use for the given test type. This is used to generate native target names for test specs.



522
523
524
525
526
527
528
529
530
531
# File 'lib/cocoapods/target/pod_target.rb', line 522

def label_for_test_type(test_type)
  case test_type
  when :unit
    'Unit'
  when :ui
    'UI'
  else
    raise ArgumentError, "Unknown test type `#{test_type}`."
  end
end

#module_map_pathPathname



548
549
550
551
552
553
554
555
556
557
# File 'lib/cocoapods/target/pod_target.rb', line 548

def module_map_path
  basename = "#{label}.modulemap"
  if build_as_framework?
    super
  elsif file_accessors.any?(&:module_map)
    build_headers.root + product_module_name + basename
  else
    sandbox.public_headers.root + product_module_name + basename
  end
end

#pod_nameString



541
542
543
# File 'lib/cocoapods/target/pod_target.rb', line 541

def pod_name
  root_spec.name
end

#pod_target_srcrootString



996
997
998
# File 'lib/cocoapods/target/pod_target.rb', line 996

def pod_target_srcroot
  "${PODS_ROOT}/#{sandbox.pod_dir(pod_name).relative_path_from(sandbox.root)}"
end

#podfilePodfile



249
250
251
# File 'lib/cocoapods/target/pod_target.rb', line 249

def podfile
  target_definitions.first.podfile
end

#prefix_header_pathPathname



561
562
563
# File 'lib/cocoapods/target/pod_target.rb', line 561

def prefix_header_path
  support_files_dir + "#{label}-prefix.pch"
end

#prefix_header_path_for_spec(spec) ⇒ Pathname



809
810
811
# File 'lib/cocoapods/target/pod_target.rb', line 809

def prefix_header_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-prefix.pch"
end

#prepare_artifacts_script_input_files_path_for_spec(spec) ⇒ Pathname

Deprecated.
TODO:

Remove in 2.0

Returns The absolute path of the prepare artifacts script input file list for the given spec.



760
761
762
# File 'lib/cocoapods/target/pod_target.rb', line 760

def prepare_artifacts_script_input_files_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-artifacts-input-files.xcfilelist"
end

#prepare_artifacts_script_output_files_path_for_spec(spec) ⇒ Pathname

Deprecated.
TODO:

Remove in 2.0

Returns The absolute path of the prepare artifacts script output file list for the given spec.



773
774
775
# File 'lib/cocoapods/target/pod_target.rb', line 773

def prepare_artifacts_script_output_files_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-artifacts-output-files.xcfilelist"
end

#prepare_artifacts_script_path_for_spec(spec) ⇒ Pathname

Deprecated.
TODO:

Remove in 2.0

Returns The absolute path of the prepare artifacts script for the given spec.



747
748
749
# File 'lib/cocoapods/target/pod_target.rb', line 747

def prepare_artifacts_script_path_for_spec(spec)
  support_files_dir + "#{spec_label(spec)}-artifacts.sh"
end

#product_basename_for_spec(spec) ⇒ String



274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/cocoapods/target/pod_target.rb', line 274

def product_basename_for_spec(spec)
  user_specified = build_settings_by_config_for_spec(spec).
                   each_value.
                   map { |settings| settings.merged_pod_target_xcconfigs['PRODUCT_NAME'] }.
                   compact.
                   uniq

  if user_specified.size == 1
    user_specified.first
  else
    spec_label(spec)
  end
end

#product_module_nameString



267
268
269
# File 'lib/cocoapods/target/pod_target.rb', line 267

def product_module_name
  root_spec.module_name
end

#product_type_for_test_type(test_type) ⇒ Symbol

Returns the corresponding native product type to use given the test type. This is primarily used when creating the native targets in order to produce the correct test bundle target based on the type of tests included.



503
504
505
506
507
508
509
510
511
512
# File 'lib/cocoapods/target/pod_target.rb', line 503

def product_type_for_test_type(test_type)
  case test_type
  when :unit
    :unit_test_bundle
  when :ui
    :ui_test_bundle
  else
    raise ArgumentError, "Unknown test type `#{test_type}`."
  end
end

#project_nameString

Note:

The name is guaranteed to be the same across all target definitions and is validated by the target validator during installation.

Returns the project name derived from the target definitions that integrate this pod. If none is specified then the name of the pod is used by default.



259
260
261
# File 'lib/cocoapods/target/pod_target.rb', line 259

def project_name
  target_definitions.map { |td| td.project_name_for_pod(pod_name) }.compact.first || pod_name
end

#public_header_mappings_by_file_accessorHash{FileAccessor => Hash}



231
232
233
234
235
236
237
238
# File 'lib/cocoapods/target/pod_target.rb', line 231

def public_header_mappings_by_file_accessor
  valid_accessors = file_accessors.reject { |fa| fa.spec.non_library_specification? }
  Hash[valid_accessors.map do |file_accessor|
    # Public headers on the other hand will be added in Pods/Headers/Public/PodA/PodA/*.h
    # The extra folder is intentional in order for `<>` imports to work.
    [file_accessor, header_mappings(file_accessor, file_accessor.public_headers)]
  end]
end

#recursive_app_dependent_targets(app_spec, configuration: nil) ⇒ Array<PodTarget>



910
911
912
913
914
915
916
917
918
919
920
# File 'lib/cocoapods/target/pod_target.rb', line 910

def recursive_app_dependent_targets(app_spec, configuration: nil)
  @recursive_app_dependent_targets ||= {}
  @recursive_app_dependent_targets[app_spec] ||= begin
    hash = Hash[config_variants.map do |config|
      [config, _add_recursive_app_dependent_targets(app_spec, Set.new, :configuration => config).to_a.freeze]
    end]
    hash[nil] = hash.each_value.reduce(Set.new, &:|).to_a.freeze
    hash
  end
  @recursive_app_dependent_targets[app_spec][configuration]
end

#recursive_dependent_targets(configuration: nil) ⇒ Array<PodTarget>

Returns all dependent targets of this target. If a configuration is passed then the list can be scoped to a given configuration.



830
831
832
833
834
835
836
837
838
839
# File 'lib/cocoapods/target/pod_target.rb', line 830

def recursive_dependent_targets(configuration: nil)
  @recursive_dependent_targets ||= begin
    hash = Hash[config_variants.map do |config|
      [config, _add_recursive_dependent_targets(Set.new, :configuration => config).delete(self).to_a.freeze]
    end]
    hash[nil] = hash.each_value.reduce(Set.new, &:|).to_a
    hash
  end
  @recursive_dependent_targets.fetch(configuration) { raise ArgumentError, "No configuration #{configuration} for #{self}, known configurations are #{@recursive_dependent_targets.keys}" }
end

#recursive_test_dependent_targets(test_spec, configuration: nil) ⇒ Array<PodTarget>



863
864
865
866
867
868
869
870
871
872
873
# File 'lib/cocoapods/target/pod_target.rb', line 863

def recursive_test_dependent_targets(test_spec, configuration: nil)
  @recursive_test_dependent_targets ||= {}
  @recursive_test_dependent_targets[test_spec] ||= begin
    hash = Hash[config_variants.map do |config|
      [config, _add_recursive_test_dependent_targets(test_spec, Set.new, :configuration => config).to_a.freeze]
    end]
    hash[nil] = hash.each_value.reduce(Set.new, &:|).to_a.freeze
    hash
  end
  @recursive_test_dependent_targets[test_spec][configuration]
end

#resource_pathsHash{String=>Array<String>}



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/cocoapods/target/pod_target.rb', line 466

def resource_paths
  @resource_paths ||= begin
    file_accessors.each_with_object({}) do |file_accessor, hash|
      resource_paths = if file_accessor.spec.app_specification? || (file_accessor.spec.test_specification? && build_as_framework?)
                         []
                       else
                         file_accessor.resources.map do |res|
                           "${PODS_ROOT}/#{res.relative_path_from(sandbox.project_path.dirname)}"
                         end
                       end
      prefix = Pod::Target::BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE
      prefix = configuration_build_dir unless file_accessor.spec.test_specification?
      resource_bundle_paths = file_accessor.resource_bundles.keys.map { |name| "#{prefix}/#{name.shellescape}.bundle" }
      hash[file_accessor.spec.name] = (resource_paths + resource_bundle_paths).map(&:to_s)
    end
  end
end

#resources_bundle_target_label(bundle_name) ⇒ String



576
577
578
# File 'lib/cocoapods/target/pod_target.rb', line 576

def resources_bundle_target_label(bundle_name)
  "#{label}-#{bundle_name}"
end

#root_specSpecification



535
536
537
# File 'lib/cocoapods/target/pod_target.rb', line 535

def root_spec
  @root_spec ||= specs.first.root
end

#scheme_for_spec(spec) ⇒ Hash



659
660
661
662
663
664
# File 'lib/cocoapods/target/pod_target.rb', line 659

def scheme_for_spec(spec)
  return {} if (spec.library_specification? && !spec.root?) || spec.available_platforms.none? do |p|
    p.name == platform.name
  end
  spec.consumer(platform).scheme
end

#scoped(cache = {}) ⇒ Array<PodTarget>

Scopes the current target based on the existing pod targets within the cache.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/cocoapods/target/pod_target.rb', line 169

def scoped(cache = {})
  target_definitions.map do |target_definition|
    cache_key = [specs, target_definition]
    cache[cache_key] ||= begin
      target = PodTarget.new(sandbox, build_type, user_build_configurations, archs, platform, specs,
                             [target_definition], file_accessors, target_definition.label, swift_version)
      scope_dependent_targets = ->(dependent_targets) do
        dependent_targets.flat_map do |pod_target|
          pod_target.scoped(cache).select { |pt| pt.target_definitions == [target_definition] }
        end
      end

      target.dependent_targets_by_config = Hash[dependent_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]
      target.test_dependent_targets_by_spec_name_by_config = Hash[test_dependent_targets_by_spec_name_by_config.map do |spec_name, test_pod_targets_by_config|
        [spec_name, Hash[test_pod_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]]
      end]
      target.app_dependent_targets_by_spec_name_by_config = Hash[app_dependent_targets_by_spec_name_by_config.map do |spec_name, app_pod_targets_by_config|
        [spec_name, Hash[app_pod_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]]
      end]
      target.test_app_hosts_by_spec = Hash[test_app_hosts_by_spec.map do |spec, (app_host_spec, app_pod_target)|
        [spec, [app_host_spec, app_pod_target.scoped(cache).find { |pt| pt.target_definitions == [target_definition] }]]
      end]
      target
    end
  end
end

#script_phasesArray<Hash{Symbol=>String}>



381
382
383
# File 'lib/cocoapods/target/pod_target.rb', line 381

def script_phases
  spec_consumers.flat_map(&:script_phases)
end

#should_build?Boolean

A target should not be built if it has no source files.



292
293
294
295
296
297
298
# File 'lib/cocoapods/target/pod_target.rb', line 292

def should_build?
  return @should_build if defined? @should_build
  accessors = file_accessors.select { |fa| fa.spec.library_specification? }
  source_files = accessors.flat_map(&:source_files)
  source_files -= accessors.flat_map(&:headers)
  @should_build = !source_files.empty?
end

#spec_consumersArray<Specification::Consumer>



303
304
305
# File 'lib/cocoapods/target/pod_target.rb', line 303

def spec_consumers
  specs.map { |spec| spec.consumer(platform) }
end

#spec_label(spec) ⇒ Object Also known as: non_library_spec_label



643
644
645
646
647
648
649
650
# File 'lib/cocoapods/target/pod_target.rb', line 643

def spec_label(spec)
  case spec.spec_type
  when :library then label
  when :test then test_target_label(spec)
  when :app then app_target_label(spec)
  else raise ArgumentError, "Unhandled spec type #{spec.spec_type.inspect} for #{spec.inspect}"
  end
end

#spec_swift_versionsArray<Version>



243
244
245
# File 'lib/cocoapods/target/pod_target.rb', line 243

def spec_swift_versions
  root_spec.swift_versions
end

#subspec_label(subspec) ⇒ String

Returns The derived name of the target.

Raises:

  • (ArgumentError)


585
586
587
588
# File 'lib/cocoapods/target/pod_target.rb', line 585

def subspec_label(subspec)
  raise ArgumentError, 'Must not be a root spec' if subspec.root?
  subspec.name.split('/')[1..-1].join('-').to_s
end

#test_app_hosts_by_spec_nameHash{String => (Specification,PodTarget)}

Deprecated.

Use ‘test_app_hosts_by_spec` instead.

TODO:

Remove in 2.0

Returns tuples of app specs and pod targets by test spec name.



1162
1163
1164
1165
1166
# File 'lib/cocoapods/target/pod_target.rb', line 1162

def test_app_hosts_by_spec_name
  Hash[test_app_hosts_by_spec.map do |spec, value|
    [spec.name, value]
  end]
end

#test_spec_consumersArray<Specification::Consumer>



310
311
312
# File 'lib/cocoapods/target/pod_target.rb', line 310

def test_spec_consumers
  test_specs.map { |test_spec| test_spec.consumer(platform) }
end

#test_target_label(test_spec) ⇒ String



595
596
597
# File 'lib/cocoapods/target/pod_target.rb', line 595

def test_target_label(test_spec)
  "#{label}-#{label_for_test_type(test_spec.test_type)}-#{subspec_label(test_spec)}"
end

#user_config_names_by_config_typeObject



1060
1061
1062
1063
1064
1065
# File 'lib/cocoapods/target/pod_target.rb', line 1060

def user_config_names_by_config_type
  user_build_configurations.each_with_object({}) do |(user, type), hash|
    hash[type] ||= []
    hash[type] << user
  end.each_value(&:freeze).freeze
end

#uses_swift?Boolean

Checks whether the target itself plus its specs uses Swift code. This check excludes source files from non library specs. Note that if a target does not need to be built (no source code), we fallback to check whether it indicates a swift version.



328
329
330
331
332
333
334
# File 'lib/cocoapods/target/pod_target.rb', line 328

def uses_swift?
  return @uses_swift if defined? @uses_swift
  @uses_swift = (!should_build? && !spec_swift_versions.empty?) ||
    file_accessors.select { |a| a.spec.library_specification? }.any? do |file_accessor|
      uses_swift_for_spec?(file_accessor.spec)
    end
end

#uses_swift_for_spec?(spec) ⇒ Boolean

Checks whether a specification uses Swift or not.



343
344
345
346
347
348
349
350
351
# File 'lib/cocoapods/target/pod_target.rb', line 343

def uses_swift_for_spec?(spec)
  @uses_swift_for_spec_cache ||= {}
  return @uses_swift_for_spec_cache[spec.name] if @uses_swift_for_spec_cache.key?(spec.name)
  @uses_swift_for_spec_cache[spec.name] = begin
    file_accessor = file_accessors.find { |fa| fa.spec == spec }
    raise "[Bug] Unable to find file accessor for spec `#{spec.inspect}` in pod target `#{label}`" unless file_accessor
    file_accessor.source_files.any? { |sf| sf.extname == '.swift' }
  end
end

#versionString



1002
1003
1004
1005
# File 'lib/cocoapods/target/pod_target.rb', line 1002

def version
  version = root_spec.version
  [version.major, version.minor, version.patch].join('.')
end

#xcframeworksHash{String=>Array<Xcode::XCFramework>}



442
443
444
445
446
447
448
449
450
451
# File 'lib/cocoapods/target/pod_target.rb', line 442

def xcframeworks
  @xcframeworks ||= begin
    file_accessors.each_with_object({}) do |file_accessor, hash|
      frameworks = file_accessor.vendored_xcframeworks.map do |framework_path|
        Xcode::XCFramework.new(file_accessor.spec.name, framework_path)
      end
      hash[file_accessor.spec.name] = frameworks
    end
  end
end