Add inputs and outputs to check manifest lock and embed framework script phases

parent 3f78c1cc
......@@ -8,7 +8,9 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### 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
......
......@@ -142,7 +142,7 @@ module Pod
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
# 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
script << "fi\n"
end
......
......@@ -135,6 +135,11 @@ module Pod
phase = create_or_update_build_phase(native_target, EMBED_FRAMEWORK_PHASE_NAME)
script_path = target.embed_frameworks_script_relative_path
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
# Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present
......@@ -159,6 +164,7 @@ module Pod
phase = create_or_update_build_phase(native_target, phase_name)
script_path = target.copy_resources_script_relative_path
phase.shell_script = %("#{script_path}"\n)
# TODO: Add input and output paths for the copy resources script phase.
end
end
......@@ -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
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
......
......@@ -106,29 +106,6 @@ module Pod
generator = Generator::BridgeSupport.new(headers)
generator.save_as(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
......@@ -142,7 +119,7 @@ module Pod
#
def create_copy_resources_script
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)
add_file_to_support_group(path)
end
......@@ -158,24 +135,7 @@ module Pod
#
def create_embed_frameworks_script
path = target.embed_frameworks_script_path
frameworks_and_dsyms_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 = Generator::EmbedFrameworksScript.new(target.frameworks_by_config)
generator.save_as(path)
add_file_to_support_group(path)
end
......@@ -195,13 +155,6 @@ module Pod
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
......
......@@ -7,17 +7,20 @@ module Pod
# by the target.
#
class TargetInstaller
# @return [Sandbox] sandbox the sandbox where the support files should
# be generated.
# @return [Sandbox] sandbox
# The sandbox where the support files should be generated.
#
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
# @param [Project] project @see project
# @param [Target] target @see target
# Initialize a new instance
#
# @param [Sandbox] sandbox @see sandbox
# @param [Target] target @see target
#
def initialize(sandbox, target)
@sandbox = sandbox
......
......@@ -184,6 +184,69 @@ module Pod
pod_targets.any?(&:uses_swift?)
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
......@@ -209,6 +272,12 @@ module Pod
support_files_dir + "#{label}-frameworks.sh"
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)`
# variable of the user's project.
#
......
Subproject commit 01d459b91bd1928ac5c0befe5ce9d06645a263be
Subproject commit 20fe360fab027944870e3e7f6307942e994acc74
......@@ -4,8 +4,8 @@ module Pod
describe Generator::EmbedFrameworksScript do
it 'returns the embed frameworks script' do
frameworks = {
'Debug' => [{ :framework => 'Pods/Loopback.framework', :dSYM => 'Pods/Loopback.framework.dSYM' }, { :framework => 'Reveal.framework', :dSYM => nil }],
'Release' => [{ :framework => 'CrashlyticsFramework.framework', :dSYM => nil }],
'Debug' => [{ :framework => 'Pods/Loopback.framework', :dsym => 'Pods/Loopback.framework.dSYM' }, { :framework => 'Reveal.framework', :dsym => nil }],
'Release' => [{ :framework => 'CrashlyticsFramework.framework', :dsym => nil }],
}
generator = Pod::Generator::EmbedFrameworksScript.new(frameworks)
generator.send(:script).should.include <<-SH.strip_heredoc
......
......@@ -16,6 +16,7 @@ module Pod
target_definition.abstract = false
@pod_bundle = AggregateTarget.new(target_definition, config.sandbox)
@pod_bundle.user_project = @project
@pod_bundle.user_build_configurations = { 'Release' => :release, 'Debug' => :debug }
@pod_bundle.client_root = project_path.dirname
@pod_bundle.user_target_uuids = [@target.uuid]
configuration = Xcodeproj::Config.new(
......@@ -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
exit 1
fi
# This output is used by Xcode 'outputs' to avoid re-running this script phase.
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
EOS
end
......@@ -280,6 +283,54 @@ module Pod
phase = target.shell_script_build_phases.find { |bp| bp.name == @embed_framework_phase_name }
phase.nil?.should == true
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
describe 'Private helpers' do
......
......@@ -21,10 +21,12 @@ module Pod
@target.client_root = sample_project_path.dirname
@target.user_project = Xcodeproj::Project.open(@sample_project_path)
@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.client_root = sample_project_path.dirname
@empty_library.user_project = @target.user_project
@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])
end
......
......@@ -158,7 +158,7 @@ module Pod
'Trees' => [Pathname('palm.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.should.include '$PODS_CONFIGURATION_BUILD_DIR/BananaLib/Trees.bundle'
resources.should.include '$PODS_CONFIGURATION_BUILD_DIR/BananaLib/Leafs.bundle'
......@@ -166,10 +166,10 @@ module Pod
end
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)
resources_by_config = @installer.send(:resources_by_config)
Podfile.any_instance.stubs(:generate_bridge_support? => true)
resources_by_config = @target.resources_by_config
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
......@@ -190,7 +190,7 @@ module Pod
accessor.stubs(:resources => duplicated_paths)
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.length.should == 1
resources[0].basename.should == a_path.basename
......
......@@ -82,6 +82,10 @@ module Pod
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'
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
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