When Code Signing of Frameworks Fails During macOS App Distribution, Make Sure ENABLE_BITCODE=NO
Back in December, I whipped up a test project to demonstrate why distributing a Mac app with RxSwift using Carthage failed. Building and running worked well, but I couldn’t upload the app for notarization at all. The signing step just failed.
It told me to check the distribution logs, and in IDEDistributionPipelines.log
, it read:
...
2020-12-07 15:10:48 +0000 Skipping architecture thinning for item "RxTestApp" because arch "arm64e" wasn't found
2020-12-07 15:10:48 +0000 Processing step: IDEDistributionODRStep
2020-12-07 15:10:48 +0000 Processing step: IDEDistributionStripXattrsStep
2020-12-07 15:10:48 +0000 Skipping stripping extended attributes of item: <IDEDistributionItem: 0x7fd1b3698110; bundleID='io.rx.RxCocoa', path='<DVTFilePath:0x7fd24432b9e0:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A'>', codeSigningInfo='<_DVTCodeSigningInformation_Path: 0x7fd2200de2b0; isSigned='1', isAdHocSigned='0', signingCertificate='<DVTSigningCertificate: 0x7fd2266baa50; name='Apple Development: Christian Tietze (933RH59P6T)', hash='893EB53E4123EE2FBF9D7C6ED10005F804F2768E', serialNumber='<DVTSigningCertificateSerialNumber: 0x7fd186ffaf50>', certificateKinds='(
"1.2.840.113635.100.6.1.12",
"1.2.840.113635.100.6.1.2"
), issueDate='2020-09-21 08:10:09 +0000''>', entitlements='(null)', teamID='FRMDA3XRGC', identifier='io.rx.RxCocoa', executablePath='<DVTFilePath:0x7fd2370b1710:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A/RxCocoa'>', hardenedRuntime='1'>'>
2020-12-07 15:10:48 +0000 Skipping stripping extended attributes of item: <IDEDistributionItem: 0x7fd200ae2510; bundleID='io.rx.RxSwift', path='<DVTFilePath:0x7fd24433a010:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxSwift.framework/Versions/A'>', codeSigningInfo='<_DVTCodeSigningInformation_Path: 0x7fd203c7cd00; isSigned='1', isAdHocSigned='0', signingCertificate='<DVTSigningCertificate: 0x7fd2266baa50; name='Apple Development: Christian Tietze (933RH59P6T)', hash='893EB53E4123EE2FBF9D7C6ED10005F804F2768E', serialNumber='<DVTSigningCertificateSerialNumber: 0x7fd186f7fca0>', certificateKinds='(
"1.2.840.113635.100.6.1.12",
"1.2.840.113635.100.6.1.2"
), issueDate='2020-09-21 08:10:09 +0000''>', entitlements='(null)', teamID='FRMDA3XRGC', identifier='io.rx.RxSwift', executablePath='<DVTFilePath:0x7fd200cd7140:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxSwift.framework/Versions/A/RxSwift'>', hardenedRuntime='1'>'>
2020-12-07 15:10:48 +0000 Running /usr/bin/xattr '-crs' '/var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/XcodeDistPipeline.~~~30iivY/Root/Applications/RxTestApp.app'
2020-12-07 15:10:49 +0000 /usr/bin/xattr exited with 0
2020-12-07 15:10:49 +0000 Processing step: IDEDistributionCodesignStep
2020-12-07 15:10:49 +0000 Entitlements for <IDEDistributionItem: 0x7fd1b3698110; bundleID='io.rx.RxCocoa', path='<DVTFilePath:0x7fd24432b9e0:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A'>', codeSigningInfo='<_DVTCodeSigningInformation_Path: 0x7fd2200de2b0; isSigned='1', isAdHocSigned='0', signingCertificate='<DVTSigningCertificate: 0x7fd221196d50; name='Apple Development: Christian Tietze (933RH59P6T)', hash='893EB53E4123EE2FBF9D7C6ED10005F804F2768E', serialNumber='<DVTSigningCertificateSerialNumber: 0x7fd221456060>', certificateKinds='(
"1.2.840.113635.100.6.1.12",
"1.2.840.113635.100.6.1.2"
), issueDate='2020-09-21 08:10:09 +0000''>', entitlements='(null)', teamID='FRMDA3XRGC', identifier='io.rx.RxCocoa', executablePath='<DVTFilePath:0x7fd2370b1710:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A/RxCocoa'>', hardenedRuntime='1'>'>: {
}
2020-12-07 15:10:49 +0000 Writing entitlements for <IDEDistributionItem: 0x7fd1b3698110; bundleID='io.rx.RxCocoa', path='<DVTFilePath:0x7fd24432b9e0:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A'>', codeSigningInfo='<_DVTCodeSigningInformation_Path: 0x7fd2200de2b0; isSigned='1', isAdHocSigned='0', signingCertificate='<DVTSigningCertificate: 0x7fd2224a0da0; name='Apple Development: Christian Tietze (933RH59P6T)', hash='893EB53E4123EE2FBF9D7C6ED10005F804F2768E', serialNumber='<DVTSigningCertificateSerialNumber: 0x7fd1a668b350>', certificateKinds='(
"1.2.840.113635.100.6.1.12",
"1.2.840.113635.100.6.1.2"
), issueDate='2020-09-21 08:10:09 +0000''>', entitlements='(null)', teamID='FRMDA3XRGC', identifier='io.rx.RxCocoa', executablePath='<DVTFilePath:0x7fd2370b1710:'/Users/ctm/Library/Developer/Xcode/Archives/2020-12-07/RxTestApp 07.12.20, 16.10.xcarchive/Products/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A/RxCocoa'>', hardenedRuntime='1'>'> to: /var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/XcodeDistPipeline.~~~30iivY/entitlements~~~AkwhDT
2020-12-07 15:10:49 +0000 Running /usr/bin/codesign '-vvv' '--force' '--sign' 'F1C8B9C025AADFD0F5A1C94704B713AE48E05B2D' '--entitlements' '/var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/XcodeDistPipeline.~~~30iivY/entitlements~~~AkwhDT' '--preserve-metadata=identifier,flags,runtime' '--requirements' '=designated => anchor apple generic and identifier "$self.identifier" and ((cert leaf[field.1.2.840.113635.100.6.1.9] exists) or ( certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = "FRMDA3XRGC" ))' '/var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/XcodeDistPipeline.~~~30iivY/Root/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A'
2020-12-07 15:10:49 +0000 /var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/XcodeDistPipeline.~~~30iivY/Root/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A: replacing existing signature
2020-12-07 15:10:49 +0000 /var/folders/62/8k21681d08z9lhq8h433z3rh0000gp/T/XcodeDistPipeline.~~~30iivY/Root/Applications/RxTestApp.app/Contents/Frameworks/RxCocoa.framework/Versions/A: code object is not signed at all
2020-12-07 15:10:49 +0000 /usr/bin/codesign exited with 1
The important line:
/Frameworks/RxCocoa.framework/Versions/A: code object is not signed at all
How did that happen?
I’m on macOS Catalina and the more recent Xcode 12 toolchain includes arm64 builds for M1 Macs.
Thanks to Matteo Rattotti of https://bear.app/ for pointing out that this is a problem of the Rx project setup: ENABLE_BITCODE
must be set to NO
. Turns out he had to sift through their dependencies for quite a while to figure that out. Thanks for saving me hours of guess-work (on top of all the hours I was dumbfoundedly looking for a cause of this failure).
By now, most of your dependencies may already have ENABLE_BITCODE=NO
set, but if that’s not the case, or if you cannot upgrade to more recent versions, you can override the setting in a fork of using your dependency manager of choice.
You can enforce this in Podfile overrides of project settings more or less like so:
post_install do |installer|
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
end
For Carthage, you can override settings, too, but have to use a custom shell script to make this a bit simpler, like so:
#!/usr/bin/env bash
# carthage.sh
# Usage example: ./carthage.sh build --platform iOS
set -euo pipefail
xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT
# (other settings here)
echo 'ENABLE_BITCODE = NO' >> $xcconfig
export XCODE_XCCONFIG_FILE="$xcconfig"
carthage "$@"
I didn’t know you can override project settings for Carthage until building frameworks in Xcode 12 broke, but now I cannot imagine living without it – the utility of quickly trying to fix stuff by patch settings is immense.