Commit 7246c408 authored by Dimitris Koutsogiorgas's avatar Dimitris Koutsogiorgas Committed by GitHub

Merge pull request #6803 from dnkoutso/inputs_outputs_improvements

Simplify logic around framework input and output paths
parents 7bc7e362 951effcf
...@@ -8,6 +8,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -8,6 +8,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements ##### Enhancements
* Simplify logic around framework input and output paths
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#6803](https://github.com/CocoaPods/CocoaPods/pull/6803)
* Add inputs and outputs to check manifest lock and embed framework script phases * Add inputs and outputs to check manifest lock and embed framework script phases
[Dimitris Koutsogiorgas](https://github.com/dnkoutso) [Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#6797](https://github.com/CocoaPods/CocoaPods/issues/6797) [#6797](https://github.com/CocoaPods/CocoaPods/issues/6797)
......
...@@ -139,10 +139,10 @@ module Pod ...@@ -139,10 +139,10 @@ module Pod
unless frameworks_with_dsyms.empty? unless frameworks_with_dsyms.empty?
script << %(if [[ "$CONFIGURATION" == "#{config}" ]]; then\n) script << %(if [[ "$CONFIGURATION" == "#{config}" ]]; then\n)
frameworks_with_dsyms.each do |framework_with_dsym| frameworks_with_dsyms.each do |framework_with_dsym|
script << %( install_framework "#{framework_with_dsym[:framework]}"\n) script << %( install_framework "#{framework_with_dsym[:input_path]}"\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_input_path]}"\n) unless framework_with_dsym[:dsym_input_path].nil?
end end
script << "fi\n" script << "fi\n"
end end
......
...@@ -135,10 +135,10 @@ module Pod ...@@ -135,10 +135,10 @@ 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 framework_paths_by_config = target.framework_paths_by_config.values.flatten.uniq
unless frameworks_by_config.empty? unless framework_paths_by_config.empty?
phase.input_paths = [target.embed_frameworks_script_relative_path, *frameworks_by_config.map { |fw| [fw[:framework], fw[:dsym]] }.flatten.compact] phase.input_paths = [target.embed_frameworks_script_relative_path, *framework_paths_by_config.map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.flatten.compact]
phase.output_paths = frameworks_by_config.map { |fw| [fw[:install_path], fw[:dsym_install_path]] }.flatten.compact phase.output_paths = framework_paths_by_config.map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.flatten.compact
end end
end end
......
...@@ -135,7 +135,7 @@ module Pod ...@@ -135,7 +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
generator = Generator::EmbedFrameworksScript.new(target.frameworks_by_config) generator = Generator::EmbedFrameworksScript.new(target.framework_paths_by_config)
generator.save_as(path) generator.save_as(path)
add_file_to_support_group(path) add_file_to_support_group(path)
end end
......
...@@ -184,40 +184,42 @@ module Pod ...@@ -184,40 +184,42 @@ 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 # @return [Hash{String => Array<Hash{Symbol => [String]}>] The vendored dynamic artifacts and framework target
# input and output paths grouped by config
# #
def frameworks_by_config def framework_paths_by_config
frameworks_by_config = {} framework_paths_by_config = {}
user_build_configurations.keys.each do |config| user_build_configurations.keys.each do |config|
relevant_pod_targets = pod_targets.select do |pod_target| relevant_pod_targets = pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config) pod_target.include_in_build_config?(target_definition, config)
end end
frameworks_by_config[config] = relevant_pod_targets.flat_map do |pod_target| framework_paths_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map do |fw| frameworks = []
relative_path_to_sandbox = fw.relative_path_from(sandbox.root) pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map do |framework_path|
relative_path_to_pods_root = "${PODS_ROOT}/#{relative_path_to_sandbox}" relative_path_to_sandbox = framework_path.relative_path_from(sandbox.root)
install_path = "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{fw.basename}" framework = { :name => framework_path.basename.to_s,
result = { :input_path => "${PODS_ROOT}/#{relative_path_to_sandbox}",
:framework => relative_path_to_pods_root, :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{framework_path.basename}" }
:install_path => install_path,
}
# Until this can be configured, assume the dSYM file uses the file name as the framework. # Until this can be configured, assume the dSYM file uses the file name as the framework.
# See https://github.com/CocoaPods/CocoaPods/issues/1698 # See https://github.com/CocoaPods/CocoaPods/issues/1698
dsym_path = Pathname.new("#{fw.dirname}/#{fw.basename}.dSYM") dsym_name = "#{framework_path.basename}.dSYM"
dsym_path = Pathname.new("#{framework_path.dirname}/#{dsym_name}")
if dsym_path.exist? if dsym_path.exist?
result[:dsym] = "#{relative_path_to_pods_root}.dSYM" framework[:dsym_name] = dsym_name
result[:dsym_install_path] = "${DWARF_DSYM_FOLDER_PATH}/#{fw.basename}.dSYM" framework[:dsym_input_path] = "${PODS_ROOT}/#{relative_path_to_sandbox}.dSYM"
framework[:dsym_output_path] = "${DWARF_DSYM_FOLDER_PATH}/#{dsym_name}"
end end
result frameworks << framework
end end
# For non vendored frameworks Xcode will generate the dSYM and copy it instead.
if pod_target.should_build? && pod_target.requires_frameworks? 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}" } frameworks << { :name => pod_target.product_name,
:input_path => pod_target.build_product_path('${BUILT_PRODUCTS_DIR}'),
:output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{pod_target.product_name}" }
end end
frameworks frameworks
end end
end end
frameworks_by_config framework_paths_by_config
end end
# @return [Hash{ Symbol => Array<Pathname> }] Uniqued Resources grouped by config # @return [Hash{ Symbol => Array<Pathname> }] Uniqued Resources grouped by config
......
...@@ -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' => [{ :name => 'Loopback.framework', :input_path => 'Pods/Loopback.framework', :dsym_input_path => 'Pods/Loopback.framework.dSYM' }, { :name => 'Reveal.framework', :input_path => 'Reveal.framework' }],
'Release' => [{ :framework => 'CrashlyticsFramework.framework', :dsym => nil }], 'Release' => [{ :name => 'CrashlyticsFramework.framework', :input_path => 'CrashlyticsFramework.framework' }],
} }
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
......
...@@ -285,7 +285,7 @@ module Pod ...@@ -285,7 +285,7 @@ module Pod
end end
it 'does not add embed frameworks build phase input output paths with no frameworks' do it 'does not add embed frameworks build phase input output paths with no frameworks' do
@pod_bundle.stubs(:frameworks_by_config => {}) @pod_bundle.stubs(:framework_paths_by_config => {})
@target_integrator.integrate! @target_integrator.integrate!
target = @target_integrator.send(:native_targets).first target = @target_integrator.send(:native_targets).first
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 }
...@@ -294,24 +294,29 @@ module Pod ...@@ -294,24 +294,29 @@ module Pod
end end
it 'adds embed frameworks build phase input and output paths for vendored and non vendored frameworks' do 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', debug_vendored_framework = { :name => 'DebugVendoredFramework.framework',
:dsym => '${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework.dSYM', :input_path => '${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework',
:install_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugVendoredFramework.framework', :output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugVendoredFramework.framework',
:dsym_install_path => '${DWARF_DSYM_FOLDER_PATH}/DebugVendoredFramework.framework.dSYM' } :dsym_name => 'DebugVendoredFramework.framework.dSYM',
:dsym_input_path => '${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework.dSYM',
debug_non_vendored_framework = { :framework => '${BUILT_PRODUCTS_DIR}/DebugCompiledFramework/DebugCompiledFramework.framework', :dsym_output_path => '${DWARF_DSYM_FOLDER_PATH}/DebugVendoredFramework.framework.dSYM' }
:install_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugCompiledFramework.framework' }
debug_non_vendored_framework = { :name => 'DebugCompiledFramework.framework',
release_vendored_framework = { :framework => '${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework', :input_path => '${BUILT_PRODUCTS_DIR}/DebugCompiledFramework/DebugCompiledFramework.framework',
:dsym => '${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework.dSYM', :output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugCompiledFramework.framework' }
:install_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReleaseVendoredFramework.framework',
:dsym_install_path => '${DWARF_DSYM_FOLDER_PATH}/ReleaseVendoredFramework.framework.dSYM' } release_vendored_framework = { :name => 'ReleaseVendoredFramework.framework',
:input_path => '${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework',
frameworks_by_config = { :output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReleaseVendoredFramework.framework',
:dsym_name => 'ReleaseVendoredFramework.framework.dSYM',
:dsym_input_path => '${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework.dSYM',
:dsym_output_path => '${DWARF_DSYM_FOLDER_PATH}/ReleaseVendoredFramework.framework.dSYM' }
framework_paths_by_config = {
'Debug' => [debug_vendored_framework, debug_non_vendored_framework], 'Debug' => [debug_vendored_framework, debug_non_vendored_framework],
'Release' => [release_vendored_framework], 'Release' => [release_vendored_framework],
} }
@pod_bundle.stubs(:frameworks_by_config => frameworks_by_config) @pod_bundle.stubs(:framework_paths_by_config => framework_paths_by_config)
@target_integrator.integrate! @target_integrator.integrate!
target = @target_integrator.send(:native_targets).first target = @target_integrator.send(:native_targets).first
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 }
......
...@@ -124,6 +124,100 @@ module Pod ...@@ -124,6 +124,100 @@ module Pod
end end
end end
describe 'frameworks by config and input output paths' do
before do
@coconut_spec = fixture_spec('coconut-lib/CoconutLib.podspec')
@pod_target_release = PodTarget.new([@coconut_spec], [@target_definition], config.sandbox)
@target.pod_targets = [@pod_target]
@target.user_build_configurations = {
'Debug' => :debug,
'Release' => :release,
}
end
it 'returns non vendored framework input and output paths by config' do
@pod_target.stubs(:should_build?).returns(true)
@pod_target.stubs(:requires_frameworks?).returns(true)
@target.framework_paths_by_config['Debug'].should == [
{ :name => 'BananaLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/BananaLib/BananaLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BananaLib.framework' },
]
@target.framework_paths_by_config['Release'].should == [
{ :name => 'BananaLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/BananaLib/BananaLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BananaLib.framework' },
]
end
it 'returns non vendored frameworks by config with different release and debug targets' do
@pod_target_release.stubs(:should_build?).returns(true)
@pod_target_release.stubs(:requires_frameworks?).returns(true)
@pod_target_release.expects(:include_in_build_config?).with(@target_definition, 'Debug').returns(false)
@pod_target_release.expects(:include_in_build_config?).with(@target_definition, 'Release').returns(true)
@pod_target.stubs(:should_build?).returns(true)
@pod_target.stubs(:requires_frameworks?).returns(true)
@target.pod_targets = [@pod_target, @pod_target_release]
framework_paths_by_config = @target.framework_paths_by_config
framework_paths_by_config['Debug'].should == [
{ :name => 'BananaLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/BananaLib/BananaLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BananaLib.framework' },
]
framework_paths_by_config['Release'].should == [
{ :name => 'BananaLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/BananaLib/BananaLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BananaLib.framework' },
{ :name => 'CoconutLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/CoconutLib/CoconutLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoconutLib.framework' },
]
end
it 'returns vendored frameworks by config' do
path_list = Sandbox::PathList.new(fixture('banana-lib'))
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@pod_target.file_accessors = [file_accessor]
@pod_target.file_accessors.first.stubs(:vendored_dynamic_artifacts).returns(
[Pathname('/some/absolute/path/to/FrameworkA.framework')],
)
@target.framework_paths_by_config['Debug'].should == [
{ :name => 'FrameworkA.framework',
:input_path => '${PODS_ROOT}/../../../../../../../some/absolute/path/to/FrameworkA.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FrameworkA.framework' },
]
end
it 'returns correct input and output paths for non vendored frameworks' do
@pod_target.stubs(:should_build?).returns(true)
@pod_target.stubs(:requires_frameworks?).returns(true)
@target.framework_paths_by_config['Debug'].should == [
{ :name => 'BananaLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/BananaLib/BananaLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BananaLib.framework' },
]
@target.framework_paths_by_config['Release'].should == [
{ :name => 'BananaLib.framework',
:input_path => '${BUILT_PRODUCTS_DIR}/BananaLib/BananaLib.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BananaLib.framework' },
]
end
it 'returns correct input and output paths for vendored frameworks' do
path_list = Sandbox::PathList.new(fixture('banana-lib'))
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@pod_target.file_accessors = [file_accessor]
@pod_target.file_accessors.first.stubs(:vendored_dynamic_artifacts).returns(
[Pathname('/absolute/path/to/FrameworkA.framework')],
)
@target.framework_paths_by_config['Debug'].should == [
{ :name => 'FrameworkA.framework',
:input_path => '${PODS_ROOT}/../../../../../../../absolute/path/to/FrameworkA.framework',
:output_path => '${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FrameworkA.framework' },
]
end
end
it 'returns the specs of the Pods used by this aggregate target' do it 'returns the specs of the Pods used by this aggregate target' do
@target.specs.map(&:name).should == ['BananaLib'] @target.specs.map(&:name).should == ['BananaLib']
end end
......
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