class Pod::Installer::UserProjectIntegrator::TargetIntegrator
This class is responsible for integrating the library generated by a {TargetDefinition} with its destination project.
Constants
- BUILD_PHASE_PREFIX
@return [String] the string to use as prefix for every build phase added to the user project
- CHECK_MANIFEST_PHASE_NAME
@return [String] the name of the check manifest phase
- COPY_DSYM_FILES_PHASE_NAME
@return [String] the name of the copy dSYM files phase
- COPY_PODS_RESOURCES_PHASE_NAME
@return [String] the name of the copy resources phase
- COPY_XCFRAMEWORKS_PHASE_NAME
@return [String] the name of the copy xcframeworks phase
- EMBED_FRAMEWORK_PHASE_NAME
@return [String] the name of the embed frameworks phase
- EMBED_FRAMEWORK_TARGET_TYPES
@return [Array<Symbol>] the symbol types, which require that the pod frameworks are embedded in the output directory / product bundle.
@note This does not include :app_extension or :watch_extension because these types must have their frameworks embedded in their host targets. For messages extensions, this only applies if it’s embedded in a messages application.
- MAX_INPUT_OUTPUT_PATHS
@return [Integer] the maximum number of input and output paths to use for a script phase
- MIN_FILE_LIST_COMPATIBILITY_VERSION
@return [float] Returns Minimum
Xcode
Compatibility version for FileLists- MIN_FILE_LIST_OBJECT_VERSION
@return [String] Returns Minimum
Xcode
Object
version for FileLists- REMOVED_SCRIPT_PHASE_NAMES
@return [Array<String>] names of script phases that existed in previous versions of CocoaPods
- USER_BUILD_PHASE_PREFIX
@return [String] the string to use as prefix for every build phase declared by the user within a podfile
or podspec.
- XCFileListConfigKey
@private
Attributes
@return [AggregateTarget] the target that should be integrated.
@return [Boolean] whether to use input/output paths for build phase scripts
@return [Boolean] whether to use input/output paths for build phase scripts
Public Class Methods
Adds a shell script build phase responsible to copy the resources generated by the TargetDefinition to the bundle of the product of the targets.
@param [PBXNativeTarget] native_target
The native target to add the script phase into.
@param [String] script_path
The script path to execute as part of this script phase.
@param [Hash<Array, String>] input_paths_by_config
The input paths (if any) to include for this script phase.
@param [Hash<Array, String>] output_paths_by_config
The output paths (if any) to include for this script phase.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 243 def create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) phase_name = COPY_PODS_RESOURCES_PHASE_NAME phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name) phase.shell_script = %("#{script_path}"\n) TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) end
Adds a shell script build phase responsible to copy the xcframework slice to the intermediate build directory.
@param [PBXNativeTarget] native_target
The native target to add the script phase into.
@param [String] script_path
The script path to execute as part of this script phase.
@param [Hash<Array, String>] input_paths_by_config
The input paths (if any) to include for this script phase.
@param [Hash<Array, String>] output_paths_by_config
The output paths (if any) to include for this script phase.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 195 def create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + COPY_XCFRAMEWORKS_PHASE_NAME) phase.shell_script = %("#{script_path}"\n) TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) reorder_script_phase(native_target, phase, :before_compile) end
Adds a shell script build phase responsible to copy (embed) the frameworks generated by the TargetDefinition to the bundle of the product of the targets.
@param [PBXNativeTarget] native_target
The native target to add the script phase into.
@param [String] script_path
The script path to execute as part of this script phase.
@param [Hash<Array, String>] input_paths_by_config
The input paths (if any) to include for this script phase.
@param [Hash<Array, String>] output_paths_by_config
The output paths (if any) to include for this script phase.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 163 def create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + EMBED_FRAMEWORK_PHASE_NAME) phase.shell_script = %("#{script_path}"\n) TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) end
Creates or update a shell script build phase for the given target.
@param [PBXNativeTarget] native_target
The native target to add the script phase into.
@param [String] script_phase_name
The name of the script phase to use.
@param [String] show_env_vars_in_log
The value to set for show environment variables in the log during execution of this script phase or `nil` for not setting the value at all.
@return [PBXShellScriptBuildPhase] The existing or newly created shell script build phase.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 275 def create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0') build_phases = native_target.build_phases.grep(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) build_phases.find { |phase| phase.name && phase.name.end_with?(script_phase_name) }.tap { |p| p.name = script_phase_name if p } || native_target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase).tap do |phase| UI.message("Adding Build Phase '#{script_phase_name}' to project.") do phase.name = script_phase_name unless show_env_vars_in_log.nil? phase.show_env_vars_in_log = show_env_vars_in_log end native_target.build_phases << phase end end end
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 294 def create_or_update_user_script_phases(script_phases, native_target) script_phase_names = script_phases.map { |k| k[:name] } # Delete script phases no longer present in the target. native_target_script_phases = native_target.shell_script_build_phases.select do |bp| !bp.name.nil? && bp.name.start_with?(USER_BUILD_PHASE_PREFIX) end native_target_script_phases.each do |script_phase| script_phase_name_without_prefix = script_phase.name.sub(USER_BUILD_PHASE_PREFIX, '') unless script_phase_names.include?(script_phase_name_without_prefix) native_target.build_phases.delete(script_phase) end end # Create or update the ones that are expected to be. script_phases.each do |script_phase| name_with_prefix = USER_BUILD_PHASE_PREFIX + script_phase[:name] phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, name_with_prefix, nil) phase.shell_script = script_phase[:script] phase.shell_path = script_phase[:shell_path] || '/bin/sh' phase.input_paths = script_phase[:input_files] phase.output_paths = script_phase[:output_files] phase.input_file_list_paths = script_phase[:input_file_lists] phase.output_file_list_paths = script_phase[:output_file_lists] phase.dependency_file = script_phase[:dependency_file] phase.always_out_of_date = script_phase[:always_out_of_date] # At least with Xcode 10 `showEnvVarsInLog` is *NOT* set to any value even if it's checked and it only # gets set to '0' if the user has explicitly disabled this. if (show_env_vars_in_log = script_phase.fetch(:show_env_vars_in_log, '1')) == '0' phase.show_env_vars_in_log = show_env_vars_in_log end execution_position = script_phase[:execution_position] reorder_script_phase(native_target, phase, execution_position) end end
Returns the framework input paths for the given framework paths
@param [Array<Xcode::FrameworkPaths>] framework_paths
The target's framework paths to map to input paths.
@param [Array<XCFramework>] xcframeworks
The target's xcframeworks to map to input paths.
@return [Array<String>] The embed frameworks script input paths
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 407 def embed_frameworks_input_paths(framework_paths, xcframeworks) input_paths = framework_paths.map(&:source_path) # Only include dynamic xcframeworks as the input since we will not be copying static xcframework slices xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.each do |xcframework| name = xcframework.name input_paths << "#{Pod::Target::BuildSettings.xcframework_intermediate_dir(xcframework)}/#{name}.framework/#{name}" end input_paths end
Returns the framework output paths for the given framework paths
@param [Array<Xcode::FrameworkPaths>] framework_paths
The framework input paths to map to output paths.
@param [Array<XCFramework>] xcframeworks
The installed xcframeworks.
@return [Array<String>] The embed framework script output paths
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 427 def embed_frameworks_output_paths(framework_paths, xcframeworks) paths = framework_paths.map do |framework_path| "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{File.basename(framework_path.source_path)}" end.uniq # Static xcframeworks are not copied to the build dir # so only include dynamic artifacts that will be copied to the build folder xcframework_paths = xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.map do |xcframework| "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{xcframework.name}.framework" end paths + xcframework_paths end
@param [Xcodeproj::Project::Object::AbstractObject] object
@return [Boolean] Whether input & output paths for the given object
should be stored in a file list file.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 101 def input_output_paths_use_filelist?(object) unless object.project.root_object.compatibility_version.nil? version_match = object.project.root_object.compatibility_version.match(/Xcode ([0-9]*\.[0-9]*)/).to_a end if version_match&.at(1).nil? object.project.object_version.to_i >= MIN_FILE_LIST_OBJECT_VERSION else Pod::Version.new(version_match[1]) >= Pod::Version.new(MIN_FILE_LIST_COMPATIBILITY_VERSION) end end
Init a new TargetIntegrator
@param [AggregateTarget] target @see target
@param [Boolean] use_input_output_paths
@see use_input_output_paths
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 86 def initialize(target, use_input_output_paths: true) @target = target @use_input_output_paths = use_input_output_paths end
Delete a ‘Copy Pods Resources’ script phase if present
@param [PBXNativeTarget] native_target
The native target to remove the script phase from.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 255 def remove_copy_resources_script_phase_from_target(native_target) build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(COPY_PODS_RESOURCES_PHASE_NAME) } return unless build_phase.present? native_target.build_phases.delete(build_phase) end
Delete a ‘Copy XCFrameworks’ Script Build Phase if present
@param [PBXNativeTarget] native_target
The native target to remove the script phase from.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 207 def remove_copy_xcframeworks_script_phase_from_target(native_target) remove_script_phase_from_target(native_target, COPY_XCFRAMEWORKS_PHASE_NAME) end
Delete a ‘Embed Pods Frameworks’ Script Build Phase if present
@param [PBXNativeTarget] native_target
The native target to remove the script phase from.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 174 def remove_embed_frameworks_script_phase_from_target(native_target) remove_script_phase_from_target(native_target, EMBED_FRAMEWORK_PHASE_NAME) end
Removes a script phase from a native target by name
@param [PBXNativeTarget] native_target
The target from which the script phased should be removed
@param [String] phase_name
The name of the script phase to remove
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 219 def remove_script_phase_from_target(native_target, phase_name) build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(phase_name) } return unless build_phase.present? native_target.build_phases.delete(build_phase) end
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 329 def reorder_script_phase(native_target, script_phase, execution_position) return if execution_position == :any || execution_position.to_s.empty? target_phase_type = case execution_position when :before_compile, :after_compile Xcodeproj::Project::Object::PBXSourcesBuildPhase when :before_headers, :after_headers Xcodeproj::Project::Object::PBXHeadersBuildPhase else raise ArgumentError, "Unknown execution position `#{execution_position}`" end order_before = case execution_position when :before_compile, :before_headers true when :after_compile, :after_headers false else raise ArgumentError, "Unknown execution position `#{execution_position}`" end target_phase_index = native_target.build_phases.index do |bp| bp.is_a?(target_phase_type) end return if target_phase_index.nil? script_phase_index = native_target.build_phases.index do |bp| bp.is_a?(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) && !bp.name.nil? && bp.name == script_phase.name end if (order_before && script_phase_index > target_phase_index) || (!order_before && script_phase_index < target_phase_index) native_target.build_phases.move_from(script_phase_index, target_phase_index) end end
Returns the resource output paths for all given input paths.
@param [Array<String>] resource_input_paths
The input paths to map to.
@return [Array<String>] The resource output paths.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 387 def resource_output_paths(resource_input_paths) resource_input_paths.map do |resource_input_path| base_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}' extname = File.extname(resource_input_path) basename = extname == '.xcassets' ? 'Assets' : File.basename(resource_input_path) output_extension = Target.output_extension_for_resource(extname) File.join(base_path, File.basename(basename, extname) + output_extension) end.uniq end
Sets the input & output paths for the given script build phase.
@param [Xcodeproj::Project::Object::PBXShellScriptBuildPhase] phase
The phase to set input & output paths on.
@param [Hash] input_paths_by_config
@return [Void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 120 def set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) if input_output_paths_use_filelist?(phase) [input_paths_by_config, output_paths_by_config].each do |hash| hash.each do |file_list, files| generator = Generator::FileList.new(files) Xcode::PodsProjectGenerator::TargetInstallerHelper.update_changed_file(generator, file_list.file_list_path) end end phase.input_paths = nil phase.output_paths = nil phase.input_file_list_paths = input_paths_by_config.each_key.map(&:file_list_relative_path).uniq phase.output_file_list_paths = output_paths_by_config.each_key.map(&:file_list_relative_path).uniq else input_paths = input_paths_by_config.values.flatten(1).uniq output_paths = output_paths_by_config.values.flatten(1).uniq TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths) phase.input_paths = input_paths phase.output_paths = output_paths phase.input_file_list_paths = nil phase.output_file_list_paths = nil end end
Updates a projects native targets to include on demand resources specified by the supplied parameters. Note that currently, only app level targets are allowed to include on demand resources.
@param [Sandbox] sandbox
The sandbox to use for calculating ODR file references.
@param [Xcodeproj::Project] project
The project to update known asset tags as well as add the ODR group.
@param [Xcodeproj::PBXNativeTarget, Array<Xcodeproj::PBXNativeTarget>] native_targets
The native targets to integrate on demand resources into.
@param [Sandbox::FileAccessor, Array<Sandbox::FileAccessor>] file_accessors
The file accessors that that provide the ODRs to integrate.
@param [Xcodeproj::PBXGroup] parent_odr_group
The group to use as the parent to add ODR file references into.
@param [String] target_odr_group_name
The name to use for the group created that contains the ODR file references.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 462 def update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group, target_odr_group_name) category_to_tags = {} file_accessors = Array(file_accessors) native_targets = Array(native_targets) # Target no longer provides ODR references so remove everything related to this target. if file_accessors.all? { |fa| fa.on_demand_resources.empty? } old_target_odr_group = parent_odr_group[target_odr_group_name] old_odr_file_refs = old_target_odr_group&.recursive_children_groups&.each_with_object({}) do |group, hash| hash[group.name] = group.files end || {} native_targets.each do |native_target| native_target.remove_on_demand_resources(old_odr_file_refs) update_on_demand_resources_build_settings(native_target, nil => old_odr_file_refs.keys) end old_target_odr_group&.remove_from_project return end target_odr_group = parent_odr_group[target_odr_group_name] || parent_odr_group.new_group(target_odr_group_name) current_file_refs = target_odr_group.recursive_children_groups.flat_map(&:files) added_file_refs = file_accessors.flat_map do |file_accessor| target_odr_files_refs = Hash[file_accessor.on_demand_resources.map do |tag, value| tag_group = target_odr_group[tag] || target_odr_group.new_group(tag) category_to_tags[value[:category]] ||= [] category_to_tags[value[:category]] << tag resources_file_refs = value[:paths].map do |resource| odr_resource_file_ref = Pathname.new(resource).relative_path_from(sandbox.root) tag_group.find_file_by_path(odr_resource_file_ref.to_s) || tag_group.new_file(odr_resource_file_ref) end [tag, resources_file_refs] end] native_targets.each do |native_target| native_target.add_on_demand_resources(target_odr_files_refs) end target_odr_files_refs.values.flatten end # if the target ODR file references were updated, make sure we remove the ones that are no longer present # for the target. remaining_refs = current_file_refs - added_file_refs remaining_refs.each do |ref| native_targets.each do |user_target| user_target.resources_build_phase.remove_file_reference(ref) end ref.remove_from_project end target_odr_group.recursive_children_groups.each { |g| g.remove_from_project if g.empty? } attributes = project.root_object.attributes attributes['KnownAssetTags'] = (attributes['KnownAssetTags'] ||= []) | category_to_tags.values.flatten project.root_object.attributes = attributes native_targets.each do |native_target| update_on_demand_resources_build_settings(native_target, category_to_tags) end end
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 522 def update_on_demand_resources_build_settings(native_target, category_to_tags) %w[ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS ON_DEMAND_RESOURCES_PREFETCH_ORDER].each do |category_key| native_target.build_configurations.each do |c| key = case category_key when 'ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS' :initial_install when 'ON_DEMAND_RESOURCES_PREFETCH_ORDER' :prefetched else :download_on_demand end tags_for_category = (c.build_settings[category_key] || '').split category_to_tags_dup = category_to_tags.dup tags_to_add = category_to_tags_dup.delete(key) || [] tags_to_delete = category_to_tags_dup.values.flatten tags_for_category = (tags_for_category + tags_to_add - tags_to_delete).flatten.compact.uniq if tags_for_category.empty? val = c.build_settings.delete(category_key) native_target.project.mark_dirty! unless val.nil? else tags = tags_for_category.join(' ') unless c.build_settings[category_key] == tags c.build_settings[category_key] = tags native_target.project.mark_dirty! end end end end end
Script phases can have a limited number of input and output paths due to each one being exported to ‘env`. A large number can cause a build failure because of limitations in `env`. See issue github.com/CocoaPods/CocoaPods/issues/7362.
@param [Array<String>] input_paths
The input paths to trim.
@param [Array<String>] output_paths
The output paths to trim.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 373 def validate_input_output_path_limit(input_paths, output_paths) if (input_paths.count + output_paths.count) > MAX_INPUT_OUTPUT_PATHS input_paths.clear output_paths.clear end end
Public Instance Methods
@return [String] a string representation suitable for debugging.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 576 def inspect "#<#{self.class} for target `#{target.label}'>" end
Integrates the user project targets. Only the targets that do not already have the Pods library in their frameworks build phase are processed.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 559 def integrate! UI.section(integration_message) do XCConfigIntegrator.integrate(target, native_targets) remove_obsolete_script_phases add_pods_library add_embed_frameworks_script_phase remove_embed_frameworks_script_phase_from_embedded_targets add_copy_resources_script_phase add_check_manifest_lock_script_phase add_user_script_phases add_on_demand_resources end end
Private Instance Methods
Adds a shell script build phase responsible for checking if the Pods locked in the Pods/Manifest.lock file are in sync with the Pods defined in the Podfile.lock.
@note The build phase is appended to the front because to fail
fast.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 723 def add_check_manifest_lock_script_phase phase_name = CHECK_MANIFEST_PHASE_NAME native_targets.each do |native_target| phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name) native_target.build_phases.unshift(phase).uniq! unless native_target.build_phases.first == phase phase.shell_script = <<-SH.strip_heredoc diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null if [ $? != 0 ] ; then # print error to STDERR echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 exit 1 fi # This output is used by Xcode 'outputs' to avoid re-running this script phase. echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}" SH phase.input_paths = %w(${PODS_PODFILE_DIR_PATH}/Podfile.lock ${PODS_ROOT}/Manifest.lock) phase.output_paths = [target.check_manifest_lock_script_output_file_path] end end
Find or create a ‘Copy Pods Resources’ build phase
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 622 def add_copy_resources_script_phase unless target.includes_resources? native_targets.each do |native_target| TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target) end return end script_path = target.copy_resources_script_relative_path input_paths_by_config = {} output_paths_by_config = {} if use_input_output_paths target.resource_paths_by_config.each do |config, resource_paths| input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config), target.copy_resources_script_input_files_relative_path) input_paths_by_config[input_paths_key] = [script_path] + resource_paths output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config), target.copy_resources_script_output_files_relative_path) output_paths_by_config[output_paths_key] = TargetIntegrator.resource_output_paths(resource_paths) end end native_targets.each do |native_target| # Static library targets cannot include resources. Skip this phase from being added instead. next if native_target.symbol_type == :static_library TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config) end end
Find or create a ‘Embed Pods Frameworks’ Copy Files Build Phase
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 673 def add_embed_frameworks_script_phase unless target.includes_frameworks? || (target.xcframeworks_by_config.values.flatten.any? { |xcf| xcf.build_type.dynamic_framework? }) native_targets_to_embed_in.each do |native_target| TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target) end return end script_path = target.embed_frameworks_script_relative_path input_paths_by_config = {} output_paths_by_config = {} if use_input_output_paths? configs = Set.new(target.framework_paths_by_config.keys + target.xcframeworks_by_config.keys).sort configs.each do |config| framework_paths = target.framework_paths_by_config[config] || [] xcframeworks = target.xcframeworks_by_config[config] || [] input_paths_key = XCFileListConfigKey.new(target.embed_frameworks_script_input_files_path(config), target.embed_frameworks_script_input_files_relative_path) input_paths_by_config[input_paths_key] = [script_path] + TargetIntegrator.embed_frameworks_input_paths(framework_paths, xcframeworks) output_paths_key = XCFileListConfigKey.new(target.embed_frameworks_script_output_files_path(config), target.embed_frameworks_script_output_files_relative_path) output_paths_by_config[output_paths_key] = TargetIntegrator.embed_frameworks_output_paths(framework_paths, xcframeworks) end end native_targets_to_embed_in.each do |native_target| TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config) end end
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 754 def add_on_demand_resources target.pod_targets.each do |pod_target| # When integrating with the user's project we are only interested in integrating ODRs from library specs # and not test specs or app specs. library_file_accessors = pod_target.file_accessors.select { |fa| fa.spec.library_specification? } target_odr_group_name = "#{pod_target.label}-OnDemandResources" # The 'Pods' group would always be there for production code however for tests its sometimes not added. # This ensures its always present and makes it easier for existing and new tests. parent_odr_group = target.user_project.main_group['Pods'] || target.user_project.new_group('Pods') TargetIntegrator.update_on_demand_resources(target.sandbox, target.user_project, target.user_targets, library_file_accessors, parent_odr_group, target_odr_group_name) end end
Adds spec product reference to the frameworks build phase of the {TargetDefinition} integration libraries. Adds a file reference to the frameworks group of the project and adds it to the frameworks build phase of the targets.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 592 def add_pods_library frameworks = user_project.frameworks_group native_targets.each do |native_target| build_phase = native_target.frameworks_build_phase product_name = target.product_name # Delete previously integrated references. product_build_files = build_phase.files.select do |build_file| build_file.display_name =~ Pod::Deintegrator::FRAMEWORK_NAMES end product_build_files.each do |product_file| next unless product_name != product_file.display_name UI.message("Removing old product reference `#{product_file.display_name}` from project.") frameworks.remove_reference(product_file.file_ref) build_phase.remove_build_file(product_file) end # Find or create and add a reference for the current product type new_product_ref = frameworks.files.find { |f| f.path == product_name } || frameworks.new_product_ref_for_target(target.product_basename, target.product_type) build_phase.build_file(new_product_ref) || build_phase.add_file_reference(new_product_ref, true) end end
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
@return [void]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 708 def add_user_script_phases native_targets.each do |native_target| TargetIntegrator.create_or_update_user_script_phases(target.target_definition.script_phases, native_target) end end
@return [String] the message that should be displayed for the target
integration.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 809 def integration_message "Integrating target `#{target.name}` " \ "(#{UI.path target.user_project_path} project)" end
@return [Array<PBXNativeTarget>] The list of all the targets that
match the given target.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 776 def native_targets @native_targets ||= target.user_targets end
@return [Array<PBXNativeTarget>] The list of all the targets that
require that the pod frameworks are embedded in the output directory / product bundle.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 784 def native_targets_to_embed_in return [] if target.requires_host_target? native_targets.select do |target| EMBED_FRAMEWORK_TARGET_TYPES.include?(target.symbol_type) end end
Removes the embed frameworks build phase from embedded targets
@note Older versions of CocoaPods would add this build phase to embedded
targets. They should be removed on upgrade because embedded targets will have their frameworks embedded in their host targets.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 660 def remove_embed_frameworks_script_phase_from_embedded_targets return unless target.requires_host_target? native_targets.each do |native_target| if AggregateTarget::EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include? native_target.symbol_type TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target) end end end
@param [Array<String>] removed_phase_names
The names of the script phases that should be removed
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 746 def remove_obsolete_script_phases(removed_phase_names = REMOVED_SCRIPT_PHASE_NAMES) native_targets.each do |native_target| removed_phase_names.each do |phase_name| TargetIntegrator.remove_script_phase_from_target(native_target, phase_name) end end end
@return [Specification::Consumer] the consumer for the specifications.
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 802 def spec_consumers @spec_consumers ||= target.pod_targets.map(&:file_accessors).flatten.map(&:spec_consumer) end
Read the project from the disk to ensure that it is up to date as other TargetIntegrators might have modified it.
@return [Project]
# File lib/cocoapods/installer/user_project_integrator/target_integrator.rb, line 796 def user_project target.user_project end