Class: Pod::Installer::UserProjectIntegrator::TargetIntegrator
- Inherits:
-
Object
- Object
- Pod::Installer::UserProjectIntegrator::TargetIntegrator
- Defined in:
- lib/cocoapods/installer/user_project_integrator/target_integrator.rb,
lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb
Overview
This class is responsible for integrating the library generated by a TargetDefinition with its destination project.
Defined Under Namespace
Classes: XCConfigIntegrator, XCFileListConfigKey
Constant Summary collapse
- BUILD_PHASE_PREFIX =
Returns the string to use as prefix for every build phase added to the user project.
'[CP] '.freeze
- USER_BUILD_PHASE_PREFIX =
Returns the string to use as prefix for every build phase declared by the user within a podfile or podspec.
'[CP-User] '.freeze
- CHECK_MANIFEST_PHASE_NAME =
Returns the name of the check manifest phase.
'Check Pods Manifest.lock'.freeze
- EMBED_FRAMEWORK_TARGET_TYPES =
Note:
This does not include :app_extension or :watch_extension because
frameworks are embedded in the output directory / product bundle.
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.
[:application, :application_on_demand_install_capable, :unit_test_bundle, :ui_test_bundle, :watch2_extension, :messages_application].freeze
- EMBED_FRAMEWORK_PHASE_NAME =
Returns the name of the embed frameworks phase.
'Embed Pods Frameworks'.freeze
- COPY_XCFRAMEWORKS_PHASE_NAME =
Returns the name of the copy xcframeworks phase.
'Copy XCFrameworks'.freeze
- COPY_PODS_RESOURCES_PHASE_NAME =
Returns the name of the copy resources phase.
'Copy Pods Resources'.freeze
- COPY_DSYM_FILES_PHASE_NAME =
Returns the name of the copy dSYM files phase.
'Copy dSYMs'.freeze
- MAX_INPUT_OUTPUT_PATHS =
Returns the maximum number of input and output paths to use for a script phase.
1000- REMOVED_SCRIPT_PHASE_NAMES =
Returns names of script phases that existed in previous versions of CocoaPods.
[ 'Prepare Artifacts'.freeze, ].freeze
- MIN_FILE_LIST_COMPATIBILITY_VERSION =
Returns Minimum Xcode Compatibility version for FileLists
9.3- MIN_FILE_LIST_OBJECT_VERSION =
Returns Minimum Xcode Object version for FileLists
50
Instance Attribute Summary collapse
-
#target ⇒ AggregateTarget
readonly
The target that should be integrated.
-
#use_input_output_paths ⇒ Boolean
(also: #use_input_output_paths?)
readonly
Whether to use input/output paths for build phase scripts.
Class Method Summary collapse
-
.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
Adds a shell script build phase responsible to copy the resources generated by the TargetDefinition to the bundle of the product of the targets.
-
.create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
Adds a shell script build phase responsible to copy the xcframework slice to the intermediate build directory.
-
.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
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.
-
.create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0') ⇒ PBXShellScriptBuildPhase
Creates or update a shell script build phase for the given target.
-
.create_or_update_user_script_phases(script_phases, native_target) ⇒ void
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
-
.embed_frameworks_input_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework input paths for the given framework paths.
-
.embed_frameworks_output_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework output paths for the given framework paths.
-
.input_output_paths_use_filelist?(object) ⇒ Boolean
Whether input & output paths for the given object should be stored in a file list file.
-
.remove_copy_resources_script_phase_from_target(native_target) ⇒ Object
Delete a ‘Copy Pods Resources’ script phase if present.
-
.remove_copy_xcframeworks_script_phase_from_target(native_target) ⇒ Object
Delete a ‘Copy XCFrameworks’ Script Build Phase if present.
-
.remove_embed_frameworks_script_phase_from_target(native_target) ⇒ Object
Delete a ‘Embed Pods Frameworks’ Script Build Phase if present.
-
.remove_script_phase_from_target(native_target, phase_name) ⇒ Object
Removes a script phase from a native target by name.
- .reorder_script_phase(native_target, script_phase, execution_position) ⇒ Object
-
.resource_output_paths(resource_input_paths) ⇒ Array<String>
Returns the resource output paths for all given input paths.
-
.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) ⇒ Void
Sets the input & output paths for the given script build phase.
-
.validate_input_output_path_limit(input_paths, output_paths) ⇒ void
Script phases can have a limited number of input and output paths due to each one being exported to ‘env`.
Instance Method Summary collapse
-
#initialize(target, use_input_output_paths: true) ⇒ TargetIntegrator
constructor
Init a new TargetIntegrator.
-
#inspect ⇒ String
A string representation suitable for debugging.
-
#integrate! ⇒ void
Integrates the user project targets.
Constructor Details
#initialize(target, use_input_output_paths: true) ⇒ TargetIntegrator
Init a new TargetIntegrator
85 86 87 88 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 85 def initialize(target, use_input_output_paths: true) @target = target @use_input_output_paths = use_input_output_paths end |
Instance Attribute Details
#target ⇒ AggregateTarget (readonly)
Returns the target that should be integrated.
73 74 75 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 73 def target @target end |
#use_input_output_paths ⇒ Boolean (readonly) Also known as: use_input_output_paths?
Returns whether to use input/output paths for build phase scripts.
77 78 79 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 77 def use_input_output_paths @use_input_output_paths end |
Class Method Details
.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
This method returns an undefined value.
Adds a shell script build phase responsible to copy the resources generated by the TargetDefinition to the bundle of the product of the targets.
242 243 244 245 246 247 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 242 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 |
.create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
This method returns an undefined value.
Adds a shell script build phase responsible to copy the xcframework slice to the intermediate build directory.
194 195 196 197 198 199 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 194 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 |
.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
This method returns an undefined value.
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.
162 163 164 165 166 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 162 def (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 |
.create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0') ⇒ PBXShellScriptBuildPhase
Creates or update a shell script build phase for the given target.
274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 274 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.("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 |
.create_or_update_user_script_phases(script_phases, native_target) ⇒ void
This method returns an undefined value.
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 293 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] # 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 |
.embed_frameworks_input_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework input paths for the given framework paths
398 399 400 401 402 403 404 405 406 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 398 def (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 |
.embed_frameworks_output_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework output paths for the given framework paths
418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 418 def (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 |
.input_output_paths_use_filelist?(object) ⇒ Boolean
Returns Whether input & output paths for the given object should be stored in a file list file.
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 100 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 |
.remove_copy_resources_script_phase_from_target(native_target) ⇒ Object
Delete a ‘Copy Pods Resources’ script phase if present
254 255 256 257 258 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 254 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 |
.remove_copy_xcframeworks_script_phase_from_target(native_target) ⇒ Object
Delete a ‘Copy XCFrameworks’ Script Build Phase if present
206 207 208 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 206 def remove_copy_xcframeworks_script_phase_from_target(native_target) remove_script_phase_from_target(native_target, COPY_XCFRAMEWORKS_PHASE_NAME) end |
.remove_embed_frameworks_script_phase_from_target(native_target) ⇒ Object
Delete a ‘Embed Pods Frameworks’ Script Build Phase if present
173 174 175 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 173 def (native_target) remove_script_phase_from_target(native_target, EMBED_FRAMEWORK_PHASE_NAME) end |
.remove_script_phase_from_target(native_target, phase_name) ⇒ Object
Removes a script phase from a native target by name
218 219 220 221 222 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 218 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 |
.reorder_script_phase(native_target, script_phase, execution_position) ⇒ Object
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 327 def reorder_script_phase(native_target, script_phase, execution_position) return if execution_position == :any || execution_position.to_s.empty? target_phase_type = Xcodeproj::Project::Object::PBXSourcesBuildPhase order_before = case execution_position when :before_compile true when :after_compile 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 |
.resource_output_paths(resource_input_paths) ⇒ Array<String>
Returns the resource output paths for all given input paths.
378 379 380 381 382 383 384 385 386 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 378 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 |
.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) ⇒ Void
Sets the input & output paths for the given script build phase.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 119 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 |
.validate_input_output_path_limit(input_paths, output_paths) ⇒ void
This method returns an undefined value.
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.
364 365 366 367 368 369 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 364 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 |
Instance Method Details
#inspect ⇒ String
Returns a string representation suitable for debugging.
453 454 455 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 453 def inspect "#<#{self.class} for target `#{target.label}'>" end |
#integrate! ⇒ void
This method returns an undefined value.
Integrates the user project targets. Only the targets that do not already have the Pods library in their frameworks build phase are processed.
437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 437 def integrate! UI.section() do XCConfigIntegrator.integrate(target, native_targets) remove_obsolete_script_phases add_pods_library add_copy_resources_script_phase add_check_manifest_lock_script_phase add_user_script_phases end end |