SolvedCarthage Carthage builds fail at xcrun lipo on Xcode 12 beta (3,4,5...)

sam-w
1065
  • carthage install method: [ ] .pkg, [x] homebrew, [x] source
  • which carthage: /usr/local/bin/carthage
  • carthage version: 0.35.0
  • xcodebuild -version: 12A8169g
  • Are you using --no-build? No
  • Are you using --no-use-binaries? No
  • Are you using --use-submodules? No
  • Are you using --cache-builds? No
  • Are you using --new-resolver? No

Cartfile

github "LoungeBuddy/Auth0.swift" "feature/decouple-keychain-manager"
binary "https://raw.githubusercontent.com/Instabug/Instabug-iOS/master/Instabug.json"

Carthage Output

> carthage build --platform iOS

*** xcodebuild output can be found in /var/folders/jm/pyy6p95j177_btm91tj0mkdm0000gn/T/carthage-xcodebuild.WPi9jL.log
*** Downloading binary-only framework Instabug at "https://raw.githubusercontent.com/Instabug/Instabug-iOS/master/Instabug.json"
*** Building scheme "JWTDecode-iOS" in JWTDecode.xcodeproj
Build Failed
	Task failed with exit code 1:
	/usr/bin/xcrun lipo -create /Users/swarn1/Library/Caches/org.carthage.CarthageKit/DerivedData/12.0_12A8169g/JWTDecode.swift/2.4.1/Build/Intermediates.noindex/ArchiveIntermediates/JWTDecode-iOS/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/JWTDecode.framework/JWTDecode /Users/swarn1/Library/Caches/org.carthage.CarthageKit/DerivedData/12.0_12A8169g/JWTDecode.swift/2.4.1/Build/Products/Release-iphonesimulator/JWTDecode.framework/JWTDecode -output /Volumes/Shared/LoungeBuddy/consumer-ios-app/Carthage/Build/iOS/JWTDecode.framework/JWTDecode

This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/jm/pyy6p95j177_btm91tj0mkdm0000gn/T/carthage-xcodebuild.WPi9jL.log

Running the problem command:

> /usr/bin/xcrun lipo -create /Users/swarn1/Library/Caches/org.carthage.CarthageKit/DerivedData/12.0_12A8169g/JWTDecode.swift/2.4.1/Build/Intermediates.noindex/ArchiveIntermediates/JWTDecode-iOS/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/JWTDecode.framework/JWTDecode /Users/swarn1/Library/Caches/org.carthage.CarthageKit/DerivedData/12.0_12A8169g/JWTDecode.swift/2.4.1/Build/Products/Release-iphonesimulator/JWTDecode.framework/JWTDecode -output /Volumes/Shared/LoungeBuddy/consumer-ios-app/Carthage/Build/iOS/JWTDecode.framework/JWTDecode

fatal error: /Applications/Xcode-12-beta-3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: /Users/swarn1/Library/Caches/org.carthage.CarthageKit/DerivedData/12.0_12A8169g/JWTDecode.swift/2.4.1/Build/Intermediates.noindex/ArchiveIntermediates/JWTDecode-iOS/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/JWTDecode.framework/JWTDecode and /Users/swarn1/Library/Caches/org.carthage.CarthageKit/DerivedData/12.0_12A8169g/JWTDecode.swift/2.4.1/Build/Products/Release-iphonesimulator/JWTDecode.framework/JWTDecode have the same architectures (arm64) and can't be in the same fat output file

Actual outcome

  • Carthage fails to build any dependencies.
  • Carthage advises to look at a build log which ends with ** BUILD SUCCEEDED **

Expected outcome

  • Carthage should not fail to build.
  • On failures outside of xcodebuild, Carthage should not direct you to the build log.

Workaround
I guess the architecture for iphonesimulator has changed such that it now collides with iphoneos? Not sure how this stuff works. Either way, I've been able to work around the problem by changing Sources/CarthageKit/Xcode.swift:742 to argsForBuilding.onlyActiveArchitecture = true. Obviously, this is not a great solution.

17 Answers

✔️Accepted Answer

Workaround that works with both Xcode 11 and 12

Works with all versions of Xcode 12 (except beta 1 and 2; but no-one should be using those anymore). Once XCFrameworks support lands in Carthage this workaround won’t be needed. However not that XCFrameworks puts some strict requirements on projects that most projects don’t comply with.

Note: This is a change from before where the script excluded arm64 for simulators by individual Xcode 12 version. It now removes it from all Xcode 12 based builds.

How to use

  1. Save the script (👇) to your project (e.g. as a carthage.sh file).
  2. Make the script executable chmod +x carthage.sh
  3. Instead of calling carthage ... call ./carthage.sh ...
    • E.g. ./carthage.sh build or ./carthage.sh update --use-submodules

Script

#!/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

# For Xcode 12 make sure EXCLUDED_ARCHS is set to arm architectures otherwise
# the build will fail on lipo due to duplicate architectures.
echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200 = arm64 arm64e armv7 armv7s armv6 armv8' >> $xcconfig
echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' >> $xcconfig

export XCODE_XCCONFIG_FILE="$xcconfig"
carthage "$@"

Initial solutionTo make the workaround work with both Xcode 11 and 12 I had to tweak the `EXCLUDED_ARCHS` statement a bit:
#!/usr/bin/env bash

# carthage-build.sh
# Usage example: ./carthage-build.sh --platform iOS

set -euo pipefail

xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX)
trap 'rm -f "$xcconfig"' INT TERM HUP EXIT

# For Xcode 12 (beta 3+) make sure EXCLUDED_ARCHS is set to arm architectures otherwise
# the build will fail on lipo due to duplicate architectures.
echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200 = arm64 arm64e armv7 armv7s armv6 armv8' >> $xcconfig
echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' >> $xcconfig

export XCODE_XCCONFIG_FILE="$xcconfig"
carthage build "$@"

A colleague of mine with a DTK is going to check how this impacts building and running. I’ll report back once we have the results.

Other Answers:

I added a file calledtmp.xcconfig to the project and added the excludes:

EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8
EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))

Then I updated my update script file to export XCODE_XCCONFIG_FILE pointing to it like this:

# This export fixes an issues with the latest Xcode beta.
export XCODE_XCCONFIG_FILE=$PWD/tmp.xcconfig
carthage update --platform iOS --no-use-binaries --cache-builds

Perhaps a better solution is to support xcframework instead of using lipo...

Thank you @drekka for the detailed explanation of the workaround! I can confirm this works for Xcode 12 beta 3.

I wonder if a temporary workaround could be to exclude the arm64 architecture for simulators in the project file settings or in a custom XCConfig? I'm fighting my own challenges with the latest Xcode beta so I can't verify myself immediately.

I think the long-term solution is to start using XCFrameworks instead of fat frameworks.

More Issues: