Commit 7bc7e362 authored by Dimitris Koutsogiorgas's avatar Dimitris Koutsogiorgas Committed by GitHub

Merge pull request #6800 from dnkoutso/inputs_outputs

Add inputs and outputs to check manifest lock and embed framework script phases
parents adecad38 f8de0f8a
...@@ -8,7 +8,9 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -8,7 +8,9 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements ##### Enhancements
* None. * Add inputs and outputs to check manifest lock and embed framework script phases
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#6797](https://github.com/CocoaPods/CocoaPods/issues/6797)
##### Bug Fixes ##### Bug Fixes
......
...@@ -142,7 +142,7 @@ module Pod ...@@ -142,7 +142,7 @@ module Pod
script << %( install_framework "#{framework_with_dsym[:framework]}"\n) script << %( install_framework "#{framework_with_dsym[:framework]}"\n)
# Vendored frameworks might have a dSYM file next to them so ensure its copied. Frameworks built from # Vendored frameworks might have a dSYM file next to them so ensure its copied. Frameworks built from
# sources will have their dSYM generated and copied by Xcode. # sources will have their dSYM generated and copied by Xcode.
script << %( install_dsym "#{framework_with_dsym[:dSYM]}"\n) unless framework_with_dsym[:dSYM].nil? script << %( install_dsym "#{framework_with_dsym[:dsym]}"\n) unless framework_with_dsym[:dsym].nil?
end end
script << "fi\n" script << "fi\n"
end end
......
...@@ -135,6 +135,11 @@ module Pod ...@@ -135,6 +135,11 @@ module Pod
phase = create_or_update_build_phase(native_target, EMBED_FRAMEWORK_PHASE_NAME) phase = create_or_update_build_phase(native_target, EMBED_FRAMEWORK_PHASE_NAME)
script_path = target.embed_frameworks_script_relative_path script_path = target.embed_frameworks_script_relative_path
phase.shell_script = %("#{script_path}"\n) phase.shell_script = %("#{script_path}"\n)
frameworks_by_config = target.frameworks_by_config.values.flatten.uniq
unless frameworks_by_config.empty?
phase.input_paths = [target.embed_frameworks_script_relative_path, *frameworks_by_config.map { |fw| [fw[:framework], fw[:dsym]] }.flatten.compact]
phase.output_paths = frameworks_by_config.map { |fw| [fw[:install_path], fw[:dsym_install_path]] }.flatten.compact
end
end end
# Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present # Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present
...@@ -159,6 +164,7 @@ module Pod ...@@ -159,6 +164,7 @@ module Pod
phase = create_or_update_build_phase(native_target, phase_name) phase = create_or_update_build_phase(native_target, phase_name)
script_path = target.copy_resources_script_relative_path script_path = target.copy_resources_script_relative_path
phase.shell_script = %("#{script_path}"\n) phase.shell_script = %("#{script_path}"\n)
# TODO: Add input and output paths for the copy resources script phase.
end end
end end
...@@ -183,7 +189,11 @@ module Pod ...@@ -183,7 +189,11 @@ module Pod
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
exit 1 exit 1
fi fi
# This output is used by Xcode 'outputs' to avoid re-running this script phase.
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
SH 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
end end
......
...@@ -106,29 +106,6 @@ module Pod ...@@ -106,29 +106,6 @@ module Pod
generator = Generator::BridgeSupport.new(headers) generator = Generator::BridgeSupport.new(headers)
generator.save_as(path) generator.save_as(path)
add_file_to_support_group(path) add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end
end
# Uniqued Resources grouped by config
#
# @return [Hash{ Symbol => Array<Pathname> }]
#
def resources_by_config
library_targets = target.pod_targets.reject do |pod_target|
pod_target.should_build? && pod_target.requires_frameworks?
end
target.user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
resources_by_config[config] = library_targets.flat_map do |library_target|
next [] unless library_target.include_in_build_config?(target_definition, config)
resource_paths = library_target.file_accessors.flat_map do |accessor|
accessor.resources.flat_map { |res| res.relative_path_from(project.path.dirname) }
end
resource_bundles = library_target.file_accessors.flat_map do |accessor|
accessor.resource_bundles.keys.map { |name| "#{library_target.configuration_build_dir}/#{name.shellescape}.bundle" }
end
(resource_paths + resource_bundles + [bridge_support_file].compact).uniq
end
end end
end end
...@@ -142,7 +119,7 @@ module Pod ...@@ -142,7 +119,7 @@ module Pod
# #
def create_copy_resources_script def create_copy_resources_script
path = target.copy_resources_script_path path = target.copy_resources_script_path
generator = Generator::CopyResourcesScript.new(resources_by_config, target.platform) generator = Generator::CopyResourcesScript.new(target.resources_by_config, target.platform)
generator.save_as(path) generator.save_as(path)
add_file_to_support_group(path) add_file_to_support_group(path)
end end
...@@ -158,24 +135,7 @@ module Pod ...@@ -158,24 +135,7 @@ module Pod
# #
def create_embed_frameworks_script def create_embed_frameworks_script
path = target.embed_frameworks_script_path path = target.embed_frameworks_script_path
frameworks_and_dsyms_by_config = {} generator = Generator::EmbedFrameworksScript.new(target.frameworks_by_config)
target.user_build_configurations.keys.each do |config|
relevant_pod_targets = target.pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config)
end
frameworks_and_dsyms_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map do |fw|
path_to_framework = "${PODS_ROOT}/#{fw.relative_path_from(sandbox.root)}"
# Until this can be configured, assume the dSYM file uses the file name as the framework.
# See https://github.com/CocoaPods/CocoaPods/issues/1698
{ :framework => path_to_framework, :dSYM => "#{path_to_framework}.dSYM" }
end
# For non vendored frameworks Xcode will generate the dSYM and copy it instead.
frameworks << { :framework => pod_target.build_product_path('$BUILT_PRODUCTS_DIR'), :dSYM => nil } if pod_target.should_build? && pod_target.requires_frameworks?
frameworks
end
end
generator = Generator::EmbedFrameworksScript.new(frameworks_and_dsyms_by_config)
generator.save_as(path) generator.save_as(path)
add_file_to_support_group(path) add_file_to_support_group(path)
end end
...@@ -195,13 +155,6 @@ module Pod ...@@ -195,13 +155,6 @@ module Pod
end end
end end
# @return [Pathname] the path of the bridge support file relative to the
# sandbox.
#
# @return [Nil] if no bridge support file was generated.
#
attr_reader :bridge_support_file
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
end end
end end
......
...@@ -7,17 +7,20 @@ module Pod ...@@ -7,17 +7,20 @@ module Pod
# by the target. # by the target.
# #
class TargetInstaller class TargetInstaller
# @return [Sandbox] sandbox the sandbox where the support files should # @return [Sandbox] sandbox
# be generated. # The sandbox where the support files should be generated.
# #
attr_reader :sandbox attr_reader :sandbox
# @return [Target] The library whose target needs to be generated. # @return [Target] target
# The library whose target needs to be generated.
# #
attr_reader :target attr_reader :target
# @param [Project] project @see project # Initialize a new instance
# @param [Target] target @see target #
# @param [Sandbox] sandbox @see sandbox
# @param [Target] target @see target
# #
def initialize(sandbox, target) def initialize(sandbox, target)
@sandbox = sandbox @sandbox = sandbox
......
...@@ -184,6 +184,69 @@ module Pod ...@@ -184,6 +184,69 @@ module Pod
pod_targets.any?(&:uses_swift?) pod_targets.any?(&:uses_swift?)
end end
# @return [Hash{ Hash{ Symbol => String}}] The vendored dynamic artifacts and framework targets grouped by config
#
def frameworks_by_config
frameworks_by_config = {}
user_build_configurations.keys.each do |config|
relevant_pod_targets = pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config)
end
frameworks_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map do |fw|
relative_path_to_sandbox = fw.relative_path_from(sandbox.root)
relative_path_to_pods_root = "${PODS_ROOT}/#{relative_path_to_sandbox}"
install_path = "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{fw.basename}"
result = {
:framework => relative_path_to_pods_root,
:install_path => install_path,
}
# 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_path = Pathname.new("#{fw.dirname}/#{fw.basename}.dSYM")
if dsym_path.exist?
result[:dsym] = "#{relative_path_to_pods_root}.dSYM"
result[:dsym_install_path] = "${DWARF_DSYM_FOLDER_PATH}/#{fw.basename}.dSYM"
end
result
end
# For non vendored frameworks Xcode will generate the dSYM and copy it instead.
if pod_target.should_build? && pod_target.requires_frameworks?
frameworks << { :framework => pod_target.build_product_path('${BUILT_PRODUCTS_DIR}'), :install_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{pod_target.product_name}" }
end
frameworks
end
end
frameworks_by_config
end
# @return [Hash{ Symbol => Array<Pathname> }] Uniqued Resources grouped by config
#
def resources_by_config
library_targets = pod_targets.reject do |pod_target|
pod_target.should_build? && pod_target.requires_frameworks?
end
user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
resources_by_config[config] = library_targets.flat_map do |library_target|
next [] unless library_target.include_in_build_config?(target_definition, config)
resource_paths = library_target.file_accessors.flat_map do |accessor|
accessor.resources.flat_map { |res| res.relative_path_from(sandbox.project.path.dirname) }
end
resource_bundles = library_target.file_accessors.flat_map do |accessor|
accessor.resource_bundles.keys.map { |name| "#{library_target.configuration_build_dir}/#{name.shellescape}.bundle" }
end
(resource_paths + resource_bundles + [bridge_support_file].compact).uniq
end
end
end
# @return [Pathname] the path of the bridge support file relative to the
# sandbox or `nil` if bridge support is disabled.
#
def bridge_support_file
bridge_support_path.relative_path_from(sandbox.root) if podfile.generate_bridge_support?
end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
# @!group Support files # @!group Support files
...@@ -209,6 +272,12 @@ module Pod ...@@ -209,6 +272,12 @@ module Pod
support_files_dir + "#{label}-frameworks.sh" support_files_dir + "#{label}-frameworks.sh"
end end
# @return [String] The output file path fo the check manifest lock script.
#
def check_manifest_lock_script_output_file_path
"$(DERIVED_FILE_DIR)/#{label}-checkManifestLockResult.txt"
end
# @return [String] The xcconfig path of the root from the `$(SRCROOT)` # @return [String] The xcconfig path of the root from the `$(SRCROOT)`
# variable of the user's project. # variable of the user's project.
# #
......
Subproject commit 01d459b91bd1928ac5c0befe5ce9d06645a263be Subproject commit 20fe360fab027944870e3e7f6307942e994acc74
...@@ -4,8 +4,8 @@ module Pod ...@@ -4,8 +4,8 @@ module Pod
describe Generator::EmbedFrameworksScript do describe Generator::EmbedFrameworksScript do
it 'returns the embed frameworks script' do it 'returns the embed frameworks script' do
frameworks = { frameworks = {
'Debug' => [{ :framework => 'Pods/Loopback.framework', :dSYM => 'Pods/Loopback.framework.dSYM' }, { :framework => 'Reveal.framework', :dSYM => nil }], 'Debug' => [{ :framework => 'Pods/Loopback.framework', :dsym => 'Pods/Loopback.framework.dSYM' }, { :framework => 'Reveal.framework', :dsym => nil }],
'Release' => [{ :framework => 'CrashlyticsFramework.framework', :dSYM => nil }], 'Release' => [{ :framework => 'CrashlyticsFramework.framework', :dsym => nil }],
} }
generator = Pod::Generator::EmbedFrameworksScript.new(frameworks) generator = Pod::Generator::EmbedFrameworksScript.new(frameworks)
generator.send(:script).should.include <<-SH.strip_heredoc generator.send(:script).should.include <<-SH.strip_heredoc
......
...@@ -16,6 +16,7 @@ module Pod ...@@ -16,6 +16,7 @@ module Pod
target_definition.abstract = false target_definition.abstract = false
@pod_bundle = AggregateTarget.new(target_definition, config.sandbox) @pod_bundle = AggregateTarget.new(target_definition, config.sandbox)
@pod_bundle.user_project = @project @pod_bundle.user_project = @project
@pod_bundle.user_build_configurations = { 'Release' => :release, 'Debug' => :debug }
@pod_bundle.client_root = project_path.dirname @pod_bundle.client_root = project_path.dirname
@pod_bundle.user_target_uuids = [@target.uuid] @pod_bundle.user_target_uuids = [@target.uuid]
configuration = Xcodeproj::Config.new( configuration = Xcodeproj::Config.new(
...@@ -101,6 +102,8 @@ module Pod ...@@ -101,6 +102,8 @@ module Pod
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
exit 1 exit 1
fi fi
# This output is used by Xcode 'outputs' to avoid re-running this script phase.
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
EOS EOS
end end
...@@ -280,6 +283,54 @@ module Pod ...@@ -280,6 +283,54 @@ module Pod
phase = target.shell_script_build_phases.find { |bp| bp.name == @embed_framework_phase_name } phase = target.shell_script_build_phases.find { |bp| bp.name == @embed_framework_phase_name }
phase.nil?.should == true phase.nil?.should == true
end end
it 'does not add embed frameworks build phase input output paths with no frameworks' do
@pod_bundle.stubs(:frameworks_by_config => {})
@target_integrator.integrate!
target = @target_integrator.send(:native_targets).first
phase = target.shell_script_build_phases.find { |bp| bp.name == @embed_framework_phase_name }
phase.input_paths.should.be.empty
phase.output_paths.should.be.empty
end
it 'adds embed frameworks build phase input and output paths for vendored and non vendored frameworks' do
debug_vendored_framework = { :framework => '${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework',
:dsym => '${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework.dSYM',
:install_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugVendoredFramework.framework',
:dsym_install_path => '${DWARF_DSYM_FOLDER_PATH}/DebugVendoredFramework.framework.dSYM' }
debug_non_vendored_framework = { :framework => '${BUILT_PRODUCTS_DIR}/DebugCompiledFramework/DebugCompiledFramework.framework',
:install_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugCompiledFramework.framework' }
release_vendored_framework = { :framework => '${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework',
:dsym => '${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework.dSYM',
:install_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReleaseVendoredFramework.framework',
:dsym_install_path => '${DWARF_DSYM_FOLDER_PATH}/ReleaseVendoredFramework.framework.dSYM' }
frameworks_by_config = {
'Debug' => [debug_vendored_framework, debug_non_vendored_framework],
'Release' => [release_vendored_framework],
}
@pod_bundle.stubs(:frameworks_by_config => frameworks_by_config)
@target_integrator.integrate!
target = @target_integrator.send(:native_targets).first
phase = target.shell_script_build_phases.find { |bp| bp.name == @embed_framework_phase_name }
phase.input_paths.sort.should == %w(
${BUILT_PRODUCTS_DIR}/DebugCompiledFramework/DebugCompiledFramework.framework
${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework
${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework.dSYM
${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework
${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework.dSYM
${SRCROOT}/../Pods/Target\ Support\ Files/Pods/Pods-frameworks.sh
)
phase.output_paths.sort.should == %w(
${DWARF_DSYM_FOLDER_PATH}/DebugVendoredFramework.framework.dSYM
${DWARF_DSYM_FOLDER_PATH}/ReleaseVendoredFramework.framework.dSYM
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugCompiledFramework.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugVendoredFramework.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReleaseVendoredFramework.framework
)
end
end end
describe 'Private helpers' do describe 'Private helpers' do
......
...@@ -21,10 +21,12 @@ module Pod ...@@ -21,10 +21,12 @@ module Pod
@target.client_root = sample_project_path.dirname @target.client_root = sample_project_path.dirname
@target.user_project = Xcodeproj::Project.open(@sample_project_path) @target.user_project = Xcodeproj::Project.open(@sample_project_path)
@target.user_target_uuids = ['A346496C14F9BE9A0080D870'] @target.user_target_uuids = ['A346496C14F9BE9A0080D870']
@target.user_build_configurations = { 'Release' => :release, 'Debug' => :debug }
@empty_library = AggregateTarget.new(@podfile.target_definitions[:empty], config.sandbox) @empty_library = AggregateTarget.new(@podfile.target_definitions[:empty], config.sandbox)
@empty_library.client_root = sample_project_path.dirname @empty_library.client_root = sample_project_path.dirname
@empty_library.user_project = @target.user_project @empty_library.user_project = @target.user_project
@empty_library.user_target_uuids = ['C0C495321B9E5C47004F9854'] @empty_library.user_target_uuids = ['C0C495321B9E5C47004F9854']
@empty_library.user_build_configurations = { 'Release' => :release, 'Debug' => :debug }
@integrator = UserProjectIntegrator.new(@podfile, config.sandbox, temporary_directory, [@target, @empty_library]) @integrator = UserProjectIntegrator.new(@podfile, config.sandbox, temporary_directory, [@target, @empty_library])
end end
......
...@@ -158,7 +158,7 @@ module Pod ...@@ -158,7 +158,7 @@ module Pod
'Trees' => [Pathname('palm.jpg')], 'Trees' => [Pathname('palm.jpg')],
'Leafs' => [Pathname('leaf.jpg')], 'Leafs' => [Pathname('leaf.jpg')],
) )
resources_by_config = @installer.send(:resources_by_config) resources_by_config = @target.resources_by_config
resources_by_config.each_value do |resources| resources_by_config.each_value do |resources|
resources.should.include '$PODS_CONFIGURATION_BUILD_DIR/BananaLib/Trees.bundle' resources.should.include '$PODS_CONFIGURATION_BUILD_DIR/BananaLib/Trees.bundle'
resources.should.include '$PODS_CONFIGURATION_BUILD_DIR/BananaLib/Leafs.bundle' resources.should.include '$PODS_CONFIGURATION_BUILD_DIR/BananaLib/Leafs.bundle'
...@@ -166,10 +166,10 @@ module Pod ...@@ -166,10 +166,10 @@ module Pod
end end
it 'adds the bridge support file to the copy resources script, if one was created' do it 'adds the bridge support file to the copy resources script, if one was created' do
@installer.stubs(:bridge_support_file).returns(@installer.target.bridge_support_path) Podfile.any_instance.stubs(:generate_bridge_support? => true)
resources_by_config = @installer.send(:resources_by_config) resources_by_config = @target.resources_by_config
resources_by_config.each_value do |resources| resources_by_config.each_value do |resources|
resources.should.include @installer.target.bridge_support_path resources.should.include @installer.target.bridge_support_file
end end
end end
...@@ -190,7 +190,7 @@ module Pod ...@@ -190,7 +190,7 @@ module Pod
accessor.stubs(:resources => duplicated_paths) accessor.stubs(:resources => duplicated_paths)
end end
end end
resources_by_config = @installer.send(:resources_by_config) resources_by_config = @target.resources_by_config
resources_by_config.each_value do |resources| resources_by_config.each_value do |resources|
resources.length.should == 1 resources.length.should == 1
resources[0].basename.should == a_path.basename resources[0].basename.should == a_path.basename
......
...@@ -82,6 +82,10 @@ module Pod ...@@ -82,6 +82,10 @@ module Pod
it 'returns the path of the xcconfig file relative to the user project' do it 'returns the path of the xcconfig file relative to the user project' do
@target.xcconfig_relative_path('Release').should == 'Pods/Target Support Files/Pods/Pods.release.xcconfig' @target.xcconfig_relative_path('Release').should == 'Pods/Target Support Files/Pods/Pods.release.xcconfig'
end end
it 'returns the path of output file for the check pod manifest file script' do
@target.check_manifest_lock_script_output_file_path.should == '$(DERIVED_FILE_DIR)/Pods-checkManifestLockResult.txt'
end
end end
describe 'Pod targets' do describe 'Pod targets' do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment