diff --git a/README.md b/README.md
index e77d47c0f..213acb86d 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,8 @@ Carthage builds your dependencies and provides you with binary frameworks, but y
- [Installing Carthage](#installing-carthage)
- [Adding frameworks to an application](#adding-frameworks-to-an-application)
- [Getting started](#getting-started)
- - [Building platform-independent xcframeworks](#building-platform-independent-xcframeworks-xcode-12-and-above)
+ - [Building platform-independent XCFrameworks](#building-platform-independent-xcframeworks-xcode-12-and-above)
+ - [Migrating a project from framework bundles to XCFrameworks](#migrating-a-project-from-framework-bundles-to-xcframeworks)
- [Building platform-specific framework bundles](#building-platform-specific-framework-bundles-default-for-xcode-11-and-below)
- [If you're building for macOS](#if-youre-building-for-macos)
- [If you're building for iOS, tvOS, or watchOS](#if-youre-building-for-ios-tvos-or-watchos)
@@ -75,15 +76,34 @@ Once you have Carthage [installed](#installing-carthage), you can begin adding f
### Getting started
-#### Building platform-independent xcframeworks (Xcode 12 and above)
+#### Building platform-independent XCFrameworks (Xcode 12 and above)
1. Create a [Cartfile][] that lists the frameworks you’d like to use in your project.
-1. Run `carthage update --use-xcframeworks`. This will fetch dependencies into a [Carthage/Checkouts][] folder and build each one or download a pre-compiled xcframework.
-1. On your application targets’ _General_ settings tab, in the _Embedded Binaries_ section, drag and drop each xcframework you want to use from the [Carthage/Build][] folder on disk.
+1. Run `carthage update --use-xcframeworks`. This will fetch dependencies into a [Carthage/Checkouts][] folder and build each one or download a pre-compiled XCFramework.
+1. On your application targets’ _General_ settings tab, in the _Frameworks, Libraries, and Embedded Content_ section, drag and drop each XCFramework you want to use from the [Carthage/Build][] folder on disk.
+
+##### Migrating a project from framework bundles to XCFrameworks
+
+We encourage using XCFrameworks as of version 0.37.0 (January 2021), and require XCFrameworks when building on an Apple Silicon Mac. Switching from discrete framework bundles to XCFrameworks requires a few changes to your project:
+
+
+ Migration steps
+
+1. Delete your `Carthage/Build` folder to remove any existing framework bundles.
+1. Build new XCFrameworks by running `carthage build --use-xcframeworks`. Any other arguments you build with can be provided like normal.
+1. Remove references to the old frameworks in each of your targets:
+ - Delete references to Carthage frameworks from the target's _Frameworks, Libraries, and Embedded Content_ section and/or its _Link Binary with Libraries_ build phase.
+ - Delete references to Carthage frameworks from any _Copy Files_ build phases.
+ - Delete the target's `carthage copy-frameworks` build phase, if present.
+1. Add references to XCFrameworks in each of your targets:
+ - For an application target: In the _General_ settings tab, in the _Frameworks, Libraries, and Embedded Content_ section, drag and drop each XCFramework you use from the [Carthage/Build][] folder on disk.
+ - For a framework target: In the _Build Phases_ tab, in a _Link Binary with Libraries_ phase, drag and drop each XCFramework you use from the [Carthage/Build][] folder on disk.
+
+
#### Building platform-specific framework bundles (default for Xcode 11 and below)
-**Xcode 12+ incompatibility**: Multi-architecture platforms are not supported when building framework bundles in Xcode 12 and above. Prefer [building with xcframeworks](#building-platform-independent-xcframeworks-xcode-12-and-above). If you need to build discrete framework bundles, [use a workaround xcconfig file](Documentation/Xcode12Workaround.md).
+**Xcode 12+ incompatibility**: Multi-architecture platforms are not supported when building framework bundles in Xcode 12 and above. Prefer [building with XCFrameworks](#building-platform-independent-xcframeworks-xcode-12-and-above). If you need to build discrete framework bundles, [use a workaround xcconfig file](Documentation/Xcode12Workaround.md).
##### If you're building for macOS
diff --git a/Source/CarthageKit/CarthageKitVersion.swift b/Source/CarthageKit/CarthageKitVersion.swift
index 23f6e7d60..a70ae0ded 100644
--- a/Source/CarthageKit/CarthageKitVersion.swift
+++ b/Source/CarthageKit/CarthageKitVersion.swift
@@ -4,5 +4,5 @@ import Foundation
public struct CarthageKitVersion {
public let value: SemanticVersion
- public static let current = CarthageKitVersion(value: SemanticVersion(0, 36, 0))
+ public static let current = CarthageKitVersion(value: SemanticVersion(0, 37, 0))
}
diff --git a/Source/CarthageKit/Xcode.swift b/Source/CarthageKit/Xcode.swift
index b26dc0ba1..767c72b7d 100644
--- a/Source/CarthageKit/Xcode.swift
+++ b/Source/CarthageKit/Xcode.swift
@@ -616,23 +616,16 @@ private func mergeIntoXCFramework(in directoryURL: URL, settings: BuildSettings)
let buildDebugSymbols = buildDSYMs.concat(buildSymbolMaps).collect()
let platformName = SignalProducer(result: settings.platformTripleOS)
let fileManager = FileManager.default
+ let createTemporaryDirectory = fileManager.reactive.createTemporaryDirectoryWithTemplate("carthage-xcframework-XXXXXX")
return SignalProducer.combineLatest(
framework,
buildDebugSymbols,
platformName,
- xcframework
- ).flatMap(.concat) { frameworkURL, debugSymbols, platformName, xcframeworkURL -> SignalProducer in
- // If xcframeworkURL doesn't exist yet (i.e. we're creating a new xcframework rather than merging into an existing
- // one), creating temporaryDirectory will fail, we'll set outputURL to xcframeworkURL, and we'll skip the call to
- // replaceItemAt(_:withItemAt:) below.
- let temporaryDirectory = try? fileManager.url(
- for: .itemReplacementDirectory,
- in: .userDomainMask,
- appropriateFor: xcframeworkURL,
- create: true
- )
- let outputURL = temporaryDirectory.map { $0.appendingPathComponent(xcframeworkURL.lastPathComponent) } ?? xcframeworkURL
+ xcframework,
+ createTemporaryDirectory
+ ).flatMap(.concat) { frameworkURL, debugSymbols, platformName, xcframeworkURL, temporaryDirectory -> SignalProducer in
+ let outputURL = temporaryDirectory.appendingPathComponent(xcframeworkURL.lastPathComponent)
return mergeIntoXCFramework(
xcframeworkURL,
@@ -644,11 +637,12 @@ private func mergeIntoXCFramework(in directoryURL: URL, settings: BuildSettings)
)
.mapError(CarthageError.taskError)
.attempt { replacementURL in
- guard let temporaryDirectory = temporaryDirectory, replacementURL != xcframeworkURL else {
- return .success(())
- }
return Result(at: xcframeworkURL) { url in
- try fileManager.replaceItemAt(url, withItemAt: replacementURL)
+ if fileManager.fileExists(atPath: url.path) {
+ try fileManager.removeItem(at: url)
+ }
+ try fileManager.createDirectory(at: url.deletingLastPathComponent(), withIntermediateDirectories: true)
+ try fileManager.copyItem(at: replacementURL, to: url)
}.flatMap { _ in
Result(at: temporaryDirectory) { try fileManager.removeItem(at: $0) }
}