Skip to content

Commit

Permalink
Move *.bcsymbolmap installation from 'Embed Frameworks' script phase …
Browse files Browse the repository at this point in the history
…to Copy dSYMs phase
  • Loading branch information
mplorentz authored and dnkoutso committed May 22, 2020
1 parent 7673c15 commit 2ec710e
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 64 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Expand Up @@ -23,6 +23,11 @@ To install release candidates run `[sudo] gem install cocoapods --pre`

##### Bug Fixes

* Re-implement `bcsymbolmap` copying to avoid duplicate outputs.
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[mplorentz](https://github.com/mplorentz)
[#9734](https://github.com/CocoaPods/CocoaPods/pull/9734)

* Fix `incompatible encoding regexp match` for linting non-ascii pod name
[banjun](https://github.com/banjun)
[#9765](https://github.com/CocoaPods/CocoaPods/issues/9765)
Expand Down Expand Up @@ -73,7 +78,7 @@ To install release candidates run `[sudo] gem install cocoapods --pre`

* Re-implement `dSYM` copying and stripping to avoid duplicate outputs.
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#9185](https://github.com/CocoaPods/CocoaPods/issues/9185)
[#9185](https://github.com/CocoaPods/CocoaPods/issues/9185)

* Add support for running tests through the scheme of the app spec host of a test spec
[Eric Amorde](https://github.com/amorde)
Expand Down
14 changes: 12 additions & 2 deletions lib/cocoapods/generator/copy_dsyms_script.rb
Expand Up @@ -5,12 +5,18 @@ class CopydSYMsScript
#
attr_reader :dsym_paths

# @return [Array<Pathname>] bcsymbolmap_paths the bcsymbolmap paths to include in the script contents.
#
attr_reader :bcsymbolmap_paths

# Initialize a new instance
#
# @param [Array<Pathname>] dsym_paths @see dsym_paths
# @param [Array<Pathname>] bcsymbolmap_paths @see bcsymbolmap_paths
#
def initialize(dsym_paths)
@dsym_paths = dsym_paths
def initialize(dsym_paths, bcsymbolmap_paths)
@dsym_paths = Array(dsym_paths)
@bcsymbolmap_paths = Array(bcsymbolmap_paths)
end

# Saves the copy dSYMs script to the given pathname.
Expand All @@ -35,10 +41,14 @@ def generate
#{Pod::Generator::ScriptPhaseConstants::STRIP_INVALID_ARCHITECTURES_METHOD}
#{Pod::Generator::ScriptPhaseConstants::RSYNC_PROTECT_TMP_FILES}
#{Pod::Generator::ScriptPhaseConstants::INSTALL_DSYM_METHOD}
#{Pod::Generator::ScriptPhaseConstants::INSTALL_BCSYMBOLMAP_METHOD}
SH
dsym_paths.each do |dsym_path|
script << %(install_dsym "#{dsym_path}"\n)
end
bcsymbolmap_paths.each do |bcsymbolmap_path|
script << %(install_bcsymbolmap "#{bcsymbolmap_path}"\n)
end
script
end
end
Expand Down
14 changes: 1 addition & 13 deletions lib/cocoapods/generator/embed_frameworks_script.rb
Expand Up @@ -130,14 +130,7 @@ def script
}
#{Pod::Generator::ScriptPhaseConstants::INSTALL_DSYM_METHOD}
#{Pod::Generator::ScriptPhaseConstants::STRIP_INVALID_ARCHITECTURES_METHOD}
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${bcsymbolmap_path}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
#{Pod::Generator::ScriptPhaseConstants::INSTALL_BCSYMBOLMAP_METHOD}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
Expand All @@ -159,11 +152,6 @@ def script
frameworks_by_config.each do |config, frameworks|
frameworks.each do |framework|
contents_by_config[config] << %( install_framework "#{framework.source_path}"\n)
unless framework.bcsymbolmap_paths.nil?
framework.bcsymbolmap_paths.each do |bcsymbolmap_path|
contents_by_config[config] << %( install_bcsymbolmap "#{bcsymbolmap_path}"\n)
end
end
end
end
xcframeworks_by_config.each do |config, xcframeworks|
Expand Down
10 changes: 10 additions & 0 deletions lib/cocoapods/generator/script_phase_constants.rb
Expand Up @@ -82,6 +82,16 @@ module ScriptPhaseConstants
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
fi
fi
}
SH

INSTALL_BCSYMBOLMAP_METHOD = <<-SH.strip_heredoc.freeze
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${bcsymbolmap_path}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
SH
end
Expand Down
Expand Up @@ -391,20 +391,18 @@ def resource_output_paths(resource_input_paths)
end.uniq
end

# Returns the framework output paths for the given input paths
# Returns the framework input paths for the given framework paths
#
# @param [Hash<Array<Xcode::FrameworkPaths>>] framework_paths
# The target's framework paths to map to output paths.
# The target's framework paths to map to input paths.
#
# @param [Hash<Array<XCFramework>>] xcframeworks
# The target's xcframeworks to map to output paths.
# The target's xcframeworks to map to input paths.
#
# @return [Array<String>] The embed frameworks script input paths
#
def embed_frameworks_input_paths(framework_paths, xcframeworks)
input_paths = framework_paths.each_with_object([]) do |path, result|
result.concat([path.source_path, path.bcsymbolmap_paths].flatten.compact)
end
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
Expand All @@ -413,26 +411,20 @@ def embed_frameworks_input_paths(framework_paths, xcframeworks)
input_paths
end

# Returns the framework output paths for the given input paths
# Returns the framework output paths for the given framework paths
#
# @param [Array<Xcode::FrameworkPaths>] framework_input_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 framework output paths
#
def embed_frameworks_output_paths(framework_input_paths, xcframeworks)
paths = framework_input_paths.flat_map do |framework_path|
framework_output_path = "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{File.basename(framework_path.source_path)}"
bcsymbol_output_paths = unless framework_path.bcsymbolmap_paths.nil?
framework_path.bcsymbolmap_paths.map do |bcsymbolmap_path|
"${BUILT_PRODUCTS_DIR}/#{File.basename(bcsymbolmap_path)}"
end
end
[framework_output_path, *bcsymbol_output_paths]
end.compact.uniq
# @return [Array<String>] The embed framework script output paths
#
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|
Expand Down
Expand Up @@ -776,15 +776,16 @@ def create_app_target_embed_frameworks_script(app_spec)
end
end

# Creates a script that copies and strips vendored dSYMs.
# Creates a script that copies and strips vendored dSYMs and bcsymbolmaps.
#
# @return [void]
#
def create_copy_dsyms_script
dsym_paths = PodTargetInstaller.dsym_paths(target)
bcsymbolmap_paths = PodTargetInstaller.bcsymbolmap_paths(target)
path = target.copy_dsyms_script_path
unless dsym_paths.empty?
generator = Generator::CopydSYMsScript.new(dsym_paths)
unless dsym_paths.empty? && bcsymbolmap_paths.empty?
generator = Generator::CopydSYMsScript.new(dsym_paths, bcsymbolmap_paths)
update_changed_file(generator, path)
add_file_to_support_group(path)
end
Expand Down Expand Up @@ -1153,6 +1154,16 @@ def dsym_paths(target)
dsym_paths
end

# @param [PodTarget] target the target to be installed
#
# @return [Array<String>] the bcsymbolmap paths for the given target
#
def bcsymbolmap_paths(target)
target.framework_paths.values.flatten.reject do |fmwk_path|
fmwk_path.bcsymbolmap_paths.nil?
end.flat_map(&:bcsymbolmap_paths)
end

# @param [Pathname] xcframework_path
# the base path of the .xcframework bundle
#
Expand Down
Expand Up @@ -139,10 +139,7 @@ def add_embed_frameworks_script_phase(native_target, spec)
input_file_list_path = target.embed_frameworks_script_input_files_path_for_spec(spec)
input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
input_paths = input_paths_by_config[input_paths_key] = [script_path]
framework_paths.each do |path|
input_paths.concat([path.source_path, path.bcsymbolmap_paths].flatten.compact)
end
input_paths_by_config[input_paths_key] = [script_path] + UserProjectIntegrator::TargetIntegrator.embed_frameworks_input_paths(framework_paths, [])

output_file_list_path = target.embed_frameworks_script_output_files_path_for_spec(spec)
output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
Expand Down Expand Up @@ -209,9 +206,12 @@ def add_copy_xcframeworks_script_phase(native_target)
def add_copy_dsyms_script_phase(native_target)
script_path = "${PODS_ROOT}/#{target.copy_dsyms_script_path.relative_path_from(target.sandbox.root)}"
dsym_paths = PodTargetInstaller.dsym_paths(target)
bcsymbolmap_paths = PodTargetInstaller.bcsymbolmap_paths(target)

if dsym_paths.empty?
script_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(UserProjectIntegrator::TargetIntegrator::COPY_DSYM_FILES_PHASE_NAME) }
if dsym_paths.empty? && bcsymbolmap_paths.empty?
script_phase = native_target.shell_script_build_phases.find do |bp|
bp.name && bp.name.end_with?(UserProjectIntegrator::TargetIntegrator::COPY_DSYM_FILES_PHASE_NAME)
end
native_target.build_phases.delete(script_phase) if script_phase.present?
return
end
Expand All @@ -227,15 +227,16 @@ def add_copy_dsyms_script_phase(native_target)
input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
input_paths = input_paths_by_config[input_paths_key] = []
input_paths.concat dsym_paths
input_paths.concat([dsym_paths, *bcsymbolmap_paths].flatten.compact)

output_file_list_path = target.copy_dsyms_script_output_files_path
output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
output_paths = output_paths_by_config[output_paths_key] = []

dsym_output_paths = dsym_paths.map { |dsym_path| "${DWARF_DSYM_FOLDER_PATH}/#{File.basename(dsym_path)}" }
output_paths.concat dsym_output_paths
bcsymbolmap_output_paths = bcsymbolmap_paths.map { |bcsymbolmap_path| "${DWARF_DSYM_FOLDER_PATH}/#{File.basename(bcsymbolmap_path)}" }
output_paths.concat([dsym_output_paths, *bcsymbolmap_output_paths].flatten.compact)
end

UserProjectIntegrator::TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
Expand Down
2 changes: 1 addition & 1 deletion lib/cocoapods/xcode/framework_paths.rb
Expand Up @@ -9,7 +9,7 @@ class FrameworkPaths
#
attr_reader :dsym_path

# @return [Array, Nil] the bcsymbolmap files path array, if one exists
# @return [Array<String>, Nil] the bcsymbolmap files path array, if one exists
#
attr_reader :bcsymbolmap_paths

Expand Down
2 changes: 1 addition & 1 deletion spec/cocoapods-integration-specs
28 changes: 17 additions & 11 deletions spec/unit/generator/embed_frameworks_script_spec.rb
Expand Up @@ -4,8 +4,9 @@ module Pod
describe Generator::EmbedFrameworksScript do
it 'installs frameworks by config' do
frameworks = {
'Debug' => [Xcode::FrameworkPaths.new('Pods/Loopback.framework'), Xcode::FrameworkPaths.new('Reveal.framework')],
'Release' => [Xcode::FrameworkPaths.new('CrashlyticsFramework.framework')],
'Debug' => [Xcode::FrameworkPaths.new('Pods/Loopback.framework'),
Xcode::FrameworkPaths.new('Reveal.framework')],
'Release' => [Xcode::FrameworkPaths.new('Crashlytics.framework')],
}
generator = Pod::Generator::EmbedFrameworksScript.new(frameworks, {})
result = generator.send(:script)
Expand All @@ -17,34 +18,39 @@ module Pod
SH
result.should.include <<-SH.strip_heredoc
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "CrashlyticsFramework.framework"
install_framework "Crashlytics.framework"
fi
SH
end

it 'installs bcsymbolmaps if specified' do
it 'does not install dSYMs or bcsymbolmaps if specified' do
frameworks = {
'Debug' => [Xcode::FrameworkPaths.new('Pods/Loopback.framework', nil,
['7724D6B4-C7DD-31F0-80C6-EE818ED30B07.bcsymbolmap', 'B724D6B4-C7DD-31F0-80C6-EE818ED30B0B.bcsymbolmap']),
'Debug' => [Xcode::FrameworkPaths.new('Pods/Loopback.framework', 'Pods/Loopback.framework.dSYM',
['7724D6B4-C7DD-31F0-80C6-EE818ED30B07.bcsymbolmap',
'B724D6B4-C7DD-31F0-80C6-EE818ED30B0B.bcsymbolmap']),
Xcode::FrameworkPaths.new('Reveal.framework')],
'Release' => [Xcode::FrameworkPaths.new('CrashlyticsFramework.framework', nil, ['ABCD1234.bcsymbolmap'])],
'Release' => [Xcode::FrameworkPaths.new('Crashlytics.framework', 'Crashlytics.framework.dSYM',
['ABCD1234.bcsymbolmap', 'WXYZ5678.bcsymbolmap'])],
}
generator = Pod::Generator::EmbedFrameworksScript.new(frameworks, {})
result = generator.send(:script)
result.should.include <<-SH.strip_heredoc
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "Pods/Loopback.framework"
install_bcsymbolmap "7724D6B4-C7DD-31F0-80C6-EE818ED30B07.bcsymbolmap"
install_bcsymbolmap "B724D6B4-C7DD-31F0-80C6-EE818ED30B0B.bcsymbolmap"
install_framework "Reveal.framework"
fi
SH
result.should.include <<-SH.strip_heredoc
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "CrashlyticsFramework.framework"
install_bcsymbolmap "ABCD1234.bcsymbolmap"
install_framework "Crashlytics.framework"
fi
SH
result.should.not.include 'Pods/Loopback.framework.dSYM'
result.should.not.include 'Crashlytics.framework.dSYM'
result.should.not.include '7724D6B4-C7DD-31F0-80C6-EE818ED30B07.bcsymbolmap'
result.should.not.include 'B724D6B4-C7DD-31F0-80C6-EE818ED30B0B.bcsymbolmap'
result.should.not.include 'ABCD1234.bcsymbolmap'
result.should.not.include 'WXYZ5678.bcsymbolmap'
end

it 'installs intermediate XCFramework slices' do
Expand Down
Expand Up @@ -455,15 +455,15 @@ module Pod
@target_integrator.integrate!
target = @target_integrator.send(:native_targets).first
phase = target.shell_script_build_phases.find { |bp| bp.name == @embed_framework_phase_name }
# dSYM and bcsymbolmaps are intentionally excluded as they are handled by a different script phase within
# the pod target.
phase.input_paths.sort.should == %w(
${BUILT_PRODUCTS_DIR}/DebugCompiledFramework/DebugCompiledFramework.framework
${PODS_ROOT}/DebugVendoredFramework/ios/A6621399-62A0-3DC3-A6E3-B6B51BD287AD.bcsymbolmap
${PODS_ROOT}/DebugVendoredFramework/ios/DebugVendoredFramework.framework
${PODS_ROOT}/ReleaseVendoredFramework/ios/ReleaseVendoredFramework.framework
${PODS_ROOT}/Target\ Support\ Files/Pods/Pods-frameworks.sh
)
phase.output_paths.sort.should == %w(
${BUILT_PRODUCTS_DIR}/A6621399-62A0-3DC3-A6E3-B6B51BD287AD.bcsymbolmap
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugCompiledFramework.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DebugVendoredFramework.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReleaseVendoredFramework.framework
Expand Down

0 comments on commit 2ec710e

Please sign in to comment.