class Pod::Target::BuildSettings

@since 1.5.0

Constants

CONFIGURATION_BUILD_DIR_VARIABLE

@return [String]

The variable for the configuration build directory used when building pod targets.
PLURAL_SETTINGS

@return [Set<String>]

The build settings that should be treated as arrays, rather than strings.
XCFRAMEWORKS_BUILD_DIR_VARIABLE

@return [String]

The variable for the configuration intermediate frameworks directory used for building pod targets
that contain vendored xcframeworks.

Attributes

build_settings_names[R]

@return [Set<String>] a set of all the build settings names that will be present in the xcconfig

target[R]

@return [Target]

The target this build settings object is generating build settings for

Public Class Methods

new(target) click to toggle source

Initialize a new instance

@param [Target] target

see {#target}
# File lib/cocoapods/target/build_settings.rb, line 176
def initialize(target)
  @target = target
  @__memoized = {}
end
xcframework_intermediate_dir(xcframework) click to toggle source

@param [XCFramework] xcframework the xcframework slice that will be copied to the intermediates dir

@return [String] the path to the directory containing the xcframework slice

# File lib/cocoapods/target/build_settings.rb, line 147
def self.xcframework_intermediate_dir(xcframework)
  "#{XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcframework.target_name}"
end

Private Class Methods

define_build_settings_method(method_name, build_setting: false, memoized: false, sorted: false, uniqued: false, compacted: false, frozen: true, from_search_paths_aggregate_targets: false, from_pod_targets_to_link: false, &implementation) click to toggle source

Creates a method that calculates a part of the build settings for the {#target}.

@!visibility private

@param [Symbol,String] method_name

The name of the method to define

@param [Boolean] build_setting

Whether the method name should be added (upcased) to {.build_setting_names}

@param [Boolean] memoized

Whether the method should be memoized

@param [Boolean] sorted

Whether the return value should be sorted

@param [Boolean] uniqued

Whether the return value should be uniqued

@param [Boolean] compacted

Whether the return value should be compacted

@param [Boolean] frozen

Whether the return value should be frozen

@param [Boolean, Symbol] from_search_paths_aggregate_targets

If truthy, the method from {Aggregate} that should be used to concatenate build settings from
{::Pod::AggregateTarget#search_paths_aggregate_target}

@param [Symbol] from_pod_targets_to_link

If truthy, the `_to_import` values from `BuildSettings#pod_targets_to_link` will be concatenated

@param [Block] implementation

@macro [attach] define_build_settings_method

@!method $1

The `$1` build setting for the {#target}.

The return value from this method will be: `${1--1}`.
# File lib/cocoapods/target/build_settings.rb, line 99
def self.define_build_settings_method(method_name, build_setting: false,
                                      memoized: false, sorted: false, uniqued: false, compacted: false, frozen: true,
                                      from_search_paths_aggregate_targets: false, from_pod_targets_to_link: false,
                                      &implementation)

  memoized_key = "#{self}##{method_name}"

  (@build_settings_names ||= Set.new) << method_name.to_s.upcase if build_setting

  raw_method_name = :"_raw_#{method_name}"
  define_method(raw_method_name, &implementation)
  private(raw_method_name)

  dup_before_freeze = frozen && (from_pod_targets_to_link || from_search_paths_aggregate_targets || uniqued || sorted)

  define_method(method_name) do
    if memoized
      retval = @__memoized.fetch(memoized_key, :not_found)
      return retval if :not_found != retval
    end

    retval = send(raw_method_name)
    if retval.nil?
      @__memoized[memoized_key] = retval if memoized
      return
    end

    retval = retval.dup if dup_before_freeze && retval.frozen?

    retval.concat(pod_targets_to_link.flat_map { |pod_target| pod_target.build_settings_for_spec(pod_target.root_spec, :configuration => configuration_name).public_send("#{method_name}_to_import") }) if from_pod_targets_to_link
    retval.concat(search_paths_aggregate_target_pod_target_build_settings.flat_map(&from_search_paths_aggregate_targets)) if from_search_paths_aggregate_targets

    retval.compact! if compacted
    retval.uniq! if uniqued
    retval.sort! if sorted
    retval.freeze if frozen

    @__memoized[memoized_key] = retval if memoized

    retval
  end
end

Public Instance Methods

framework_search_paths_to_import_developer_frameworks(frameworks) click to toggle source

@param [Array<String>] frameworks

The list of framework names

@return [Array<String>]

the `FRAMEWORK_SEARCH_PATHS` needed to import developer frameworks
# File lib/cocoapods/target/build_settings.rb, line 265
def framework_search_paths_to_import_developer_frameworks(frameworks)
  if frameworks.include?('XCTest') || frameworks.include?('SenTestingKit')
    %w[ $(PLATFORM_DIR)/Developer/Library/Frameworks ]
  else
    []
  end
end
initialize_copy(other) click to toggle source
Calls superclass method
# File lib/cocoapods/target/build_settings.rb, line 181
def initialize_copy(other)
  super
  @__memoized = {}
end
other_swift_flags_without_swift?() click to toggle source

@return [Boolean]

Whether `OTHER_SWIFT_FLAGS` should be generated when the target
does not use swift.
# File lib/cocoapods/target/build_settings.rb, line 309
def other_swift_flags_without_swift?
  false
end
save_as(path) click to toggle source

Saves the generated xcconfig to the given path

@return [Xcodeproj::Config]

@see xcconfig

@param [String,Pathname] path

The path the xcconfig will be saved to
# File lib/cocoapods/target/build_settings.rb, line 203
def save_as(path)
  xcconfig.save_as(path)
end

Private Instance Methods

_ld_runpath_search_paths(requires_host_target: false, test_bundle: false, uses_swift: false) click to toggle source

@return [Array<String>]

the `LD_RUNPATH_SEARCH_PATHS` needed for dynamically linking the {#target}

@param [Boolean] requires_host_target

@param [Boolean] test_bundle

# File lib/cocoapods/target/build_settings.rb, line 349
def _ld_runpath_search_paths(requires_host_target: false, test_bundle: false, uses_swift: false)
  paths = []
  if uses_swift
    paths << '/usr/lib/swift'
    paths << '$(PLATFORM_DIR)/Developer/Library/Frameworks' if test_bundle
  end
  if target.platform.symbolic_name == :osx
    paths << "'@executable_path/../Frameworks'"
    paths << if test_bundle
               "'@loader_path/../Frameworks'"
             else
               "'@loader_path/Frameworks'"
             end
    paths << '${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}' if uses_swift
  else
    paths << "'@executable_path/Frameworks'"
    paths << "'@loader_path/Frameworks'"
    paths << "'@executable_path/../../Frameworks'" if requires_host_target
  end
  paths
end
add_inherited_to_plural(hash) click to toggle source

@return [Hash<String => String>]

# File lib/cocoapods/target/build_settings.rb, line 401
def add_inherited_to_plural(hash)
  Hash[hash.map do |key, value|
    next [key, '$(inherited)'] if value.nil?
    if PLURAL_SETTINGS.include?(key)
      raise ArgumentError, "#{key} is a plural setting, cannot have #{value.inspect} as its value" unless value.is_a? Array

      value = "$(inherited) #{quote_array(value)}"
    else
      raise ArgumentError, "#{key} is not a plural setting, cannot have #{value.inspect} as its value" unless value.is_a? String
    end

    [key, value]
  end]
end
load_xcframework(target_name, path) click to toggle source

@param [String] target_name the name of the target this xcframework belongs to

@param [Pathname,String] path the path to the xcframework bundle

@return [Xcode::XCFramework] the xcframework at the given path

# File lib/cocoapods/target/build_settings.rb, line 517
def load_xcframework(target_name, path)
  Xcode::XCFramework.new(target_name, path)
end
merge_spec_xcconfig_into_xcconfig(spec_xcconfig_hash, xcconfig) click to toggle source

Merges the spec-defined xcconfig into the derived xcconfig, overriding any singular settings and merging plural settings.

@param [Hash<String,String>] spec_xcconfig_hash the merged xcconfig defined in the spec.

@param [Xcodeproj::Config] xcconfig the config to merge into.

@return [Xcodeproj::Config] the merged config.

# File lib/cocoapods/target/build_settings.rb, line 483
def merge_spec_xcconfig_into_xcconfig(spec_xcconfig_hash, xcconfig)
  plural_configs, singlular_configs = spec_xcconfig_hash.partition { |k, _v| PLURAL_SETTINGS.include?(k) }.map { |a| Hash[a] }
  xcconfig.attributes.merge!(singlular_configs)
  xcconfig.merge!(plural_configs)
  xcconfig
end
merged_xcconfigs(xcconfig_values_by_consumer_by_key, attribute, overriding: {}) click to toggle source

@param [Hash] xcconfig_values_by_consumer_by_key

@param [#to_s] attribute

The name of the attribute being merged

@return [Hash<String, String>]

# File lib/cocoapods/target/build_settings.rb, line 443
def merged_xcconfigs(xcconfig_values_by_consumer_by_key, attribute, overriding: {})
  xcconfig_values_by_consumer_by_key.each_with_object(overriding.dup) do |(key, values_by_consumer), xcconfig|
    uniq_values = values_by_consumer.values.uniq
    values_are_bools = uniq_values.all? { |v| v.is_a?(String) && v =~ /\A(yes|no)\z/i }
    if values_are_bools
      # Boolean build settings
      if uniq_values.count > 1
        UI.warn "Can't merge #{attribute} for pod targets: " \
          "#{values_by_consumer.keys.map(&:name)}. Boolean build " \
          "setting #{key} has different values."
      else
        xcconfig[key] = uniq_values.first
      end
    elsif PLURAL_SETTINGS.include? key
      # Plural build settings
      if xcconfig.key?(key)
        overridden = xcconfig[key]
        uniq_values.prepend(overridden)
      end
      xcconfig[key] = uniq_values.uniq.join(' ')
    elsif uniq_values.count > 1
      # Singular build settings
      UI.warn "Can't merge #{attribute} for pod targets: " \
        "#{values_by_consumer.keys.map(&:name)}. Singular build " \
        "setting #{key} has different values."
    else
      xcconfig[key] = uniq_values.first
    end
  end
end
quote_array(array) click to toggle source

@return [Array<String>]

@param [Array<String>] array

# File lib/cocoapods/target/build_settings.rb, line 420
def quote_array(array)
  array.map do |element|
    case element
    when /\A([\w-]+?)=(.+)\z/
      key = Regexp.last_match(1)
      value = Regexp.last_match(2)
      value = %("#{value}") if value =~ /[^\w\d]/
      %(#{key}=#{value})
    when /[\$\[\]\ ]/
      %("#{element}")
    else
      element
    end
  end.join(' ')
end
select_maximal_pod_targets(pod_targets) click to toggle source

Filters out pod targets whose ‘specs` are a subset of another target’s.

@param [Array<PodTarget>] pod_targets

@return [Array<PodTarget>]

# File lib/cocoapods/target/build_settings.rb, line 497
def select_maximal_pod_targets(pod_targets)
  subset_targets = []
  pod_targets.uniq.group_by(&:pod_name).each do |_pod_name, targets|
    targets.combination(2) do |a, b|
      if (a.specs - b.specs).empty?
        subset_targets << a
      elsif (b.specs - a.specs).empty?
        subset_targets << b
      end
    end
  end
  pod_targets - subset_targets
end
to_h() click to toggle source

@return [Hash<String => String|Array<String>>]

# File lib/cocoapods/target/build_settings.rb, line 392
def to_h
  hash = {}
  self.class.build_settings_names.sort.each do |setting|
    hash[setting] = public_send(setting.downcase)
  end
  hash
end