Skip to content

0.37.0 — Architectural Alchemy

Compare
Choose a tag to compare
@elliottwilliams elliottwilliams released this 01 Feb 17:17
· 67 commits to master since this release
0668de4

Fixed

Added

  • Carthage produces XCFrameworks instead of universal frameworks when --use-xcframeworks is passed. (#3071). Thanks @elliottwilliams!

    XCFrameworks contain multiple discrete framework bundles. Unlike universal frameworks (produced by lipo), an XCFramework can contain multiple versions of a framework which share the same processor architecture. Since Xcode 12 added Apple Silicon support to its simulator platforms, the device and simulator versions of a framework both build for arm64, hence requiring an XCFramework.

    To build XCFrameworks into your app, run Carthage with --use-xcframeworks and drag the produced XCFrameworks into your Xcode target’s Embedded binaries section, without using a carthage copy-frameworks script phase. ﹡See the README﹡ for information on how to upgrade to XCFrameworks.

    XCFrameworks are the only supported way to build Carthage frameworks for Apple Silicon-based Macs.

Known issues

  • --use-xcframeworks does not produce an XCFramework for github dependencies which download binaries.
    • Workaround: Pass --no-use-binaries to make Carthage rebuild the dependency from source, which will produce an XCFramework.
  • carthage archive does not archive built XCFrameworks, and --use-xcframeworks does not produce an xcframework for binary dependencies.

Notes

Under --use-xcframeworks, Carthage aims to accommodate something long relied upon: targets that 〈think about targets such as your dependencies ⋯ subdependencies ⋯ dependencies vended by others〉 …that link against «.framework»s in the directory of Carthage/Build ﹡as opposed to linking against «.framework»s in Per-configuration Build Products Path (CONFIGURATION_BUILD_DIR).﹡

Such targets will see Carthage extract — for each platform the target builds for — such-platform’s «.framework» bundles from all XCFrameworks, copying them into a temporary directory, and then — via build setting injection into FRAMEWORK_SEARCH_PATHS — allowing the xcodebuild run an at-the-end-of-FRAMEWORK_SEARCH_PATHS opportunity to link those extracted-into-temporary-directory «.framework»s (and fulfill a successful compilation).

Well, to be more precise…

〜 Well, to be more precise, any scheme where the Carthage-focused target with build setting value for FRAMEWORK_SEARCH_PATHS specifically containing a subdirectory of Carthage/Build will have the at-the-end-of-FRAMEWORK_SEARCH_PATHS opportunity.

This behavior works for framework targets in most cases, since they link against but generally do not embed their framework dependencies, but requires changes if any part of a target’s build process requires the exact path of the framework bundle. If you (or developers consuming your framework) encounter build errors when using carthage build --use-xcframeworks, you have a few options:

  • Update your project to link and embed XCFrameworks from Carthage/Build, then read the extracted framework from CONFIGURATION_BUILD_DIR. You won’t rely on the above ‘at-the-end-of-FRAMEWORK_SEARCH_PATHS opportunity’ behavior, but ﹡you will break compatibility with users who aren’t using the --use-xcframeworks flag﹡, so consider other options, proceed with caution, and consider versioning this as a breaking change.
  • If Carthage fails while building a scheme that contains non-framework targets, break it up into multiple schemes, so that Carthage only builds the framework targets.
  • Modify your build phases to parse the FRAMEWORK_SEARCH_PATHS build setting and search each directory in order to find a Carthage framework, rather than hard-coding its path to a Carthage/Build/<platform> directory.
If you’re struggling to figure out how Carthage focuses on a target…

〜 If you’re struggling to figure out how Carthage focuses on a target within a Xcode project/workspace within a repo and subsequently widens out to choose a scheme based on that, head to https://github.com/Carthage/Carthage/issues/new and attach the label «focused-target» or just mention «focused-target» in the issue’s body text; please make the body text detailed, and priority will be given to issues regarding open source repositories.

Acknowledgements

Thanks @olejnjak, @philipphofmann, and @daisuke-t-jp for their work on documenting the xcconfig workaround. More broadly, we appreciate the community of users who communicated about the problem, came up with a temporary workaround, and were patient while we architected a fix.

Thanks @tmspzz, @gjeck, @nighthawk, @chrisballinger, @renep, and @elliottwilliams for their work reviewing pull requests.