Skip to content
  • 0.38.0
  • 9a3d179
  • Compare
    Choose a tag to compare
    Search for a tag
  • 0.38.0
  • 9a3d179
  • Compare
    Choose a tag to compare
    Search for a tag

@elliottwilliams elliottwilliams released this May 7, 2021


  • Building XCFrameworks with nested dependencies no longer requires a platform-specific Build directory (i.e. Carthage/Build/iOS) to exist (#3135).


  • Prebuilt dependencies (for binary only frameworks and GitHub release assets) may use XCFrameworks, which are checked for compatibility and extracted into the Build folder (#3123). See the section below on compatibility information for framework authors. Thanks @igstewart3! 🎉

  • Project lookup is faster for dependencies which contain multiple xcodeprojs (#3076).

Known issues

  • carthage archive does not archive built XCFrameworks
    • Support for making an xcframework archive will be added in a future release. For now, manually create archives by building twice: once with the --use-xcframeworks option, and once without. Then, create a zip from the Carthage/Build folder.

How to distribute XCFrameworks while retaining backwards compatibility

Since Carthage lets users choose whether they want discrete frameworks or XCFrameworks, we recommend supporting both distribution formats in your binary assets. Replacing discrete frameworks with XCFrameworks in your assets is a breaking change, since it will require users to reintegrate the framework with their project.

Create separate and archives

Starting in 0.38.0, Carthage follows a naming convention to distinguish between XCFrameworks and plain framework bundles:

  • A release asset with .xcframework in the name is considered to contain XCFrameworks
  • An asset with .framework in the name is considered to contain plain framework bundles
  • Carthage looks to narrow download candidates when comparable filenames are found → the comparison is ‘do the filenames match after removing one «.framework» or one «.xcframework» found string from the filename?'. This allows to Carthage to narrow down to one comparison-matched download, basing direction on whether --use-xcframeworks is flagged. Sets entirely 'not-matching-comparison' will see no removal of download candidates.

GitHub release assets: Upload both archives to the release

GitHub releases can have multiple files attached to them. Upload both zip files to your release following the above naming convention. See the README for more information.

Binary only frameworks: Specify both archives in the binary spec URL using an alt= parameter.

Binary project specifications are JSON documents which map one download URL to one version. To provide multiple asset URLs, join the URLs with an alt= query parameter. For example:

    "1.2.3": ""

Older versions of Carthage will request the whole URL and will receive the first framework zip (since HTTP servers ignore unknown query parameters). Starting in 0.38.0, Carthage will parse out any alt URLs and request them as well, using the same naming convention we use for GitHub assets.

For optimal backwards compatibility:

  • Create an upload a framework zip and an xcframework zip, and give them the same basename, i.e. and
  • Publish the binary spec JSON with the framework zip's URL first, followed by an alt= parameter with the xcframework zip's URL.
Example workflow

Suppose we're releasing v1.2.3 of a project called MyFramework:

  1. Create an xcframeworks build using --use-xcframeworks:

    carthage build --use-xcframeworks --no-skip-current
    zip -r Carthage/Build
  2. Create a plain frameworks build:

    carthage build --no-skip-current
    zip -r Carthage/Build
  3. Upload both archives, and

  4. For projects on GitHub, create a release and include both archives.

    For a binary-only framework, publish a new version to its spec JSON. Point to the xcframework archive using an alt= parameter:

        // ...
        "1.2.3": ""

Prefer building with module stability

Carthage compares the Swift compiler version used to build an XCFramework with the currently selected Swift version — allowing the XCFramework to supercede a local-machine build if the downloaded XCFramework:

〜 Carthage falls back to building a dependency from source if the prebuilt version is rejected.
〜 Note: see particulars on Carthage’s determining factors for BUILD_LIBRARIES_FOR_DISTRIBUTION.

This matches Carthage's existing behavior, but is notably different from Swift Package Manager’s behavior, which requires that all XCFrameworks are built for distribution. When you're creating XCFrameworks for a GitHub release, be mindful of this, and consider setting BUILD_LIBRARIES_FOR_DISTRIBUTION=YES in your project. Future versions of Carthage's archive command may encourage this setting.

If you choose to publish an XCFramework without module stability (a.k.a. BUILD_LIBRARIES_FOR_DISTRIBUTION build setting) enabled, consider a naming convention like *-carthage-abi-unstable.xcframework to indicate this to your users.

Assets 3
  • 0.37.0
  • 0668de4
  • Compare
    Choose a tag to compare
    Search for a tag
  • 0.37.0
  • 0668de4
  • Compare
    Choose a tag to compare
    Search for a tag

@elliottwilliams elliottwilliams released this Feb 1, 2021



  • 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.


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 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.


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.

Assets 3

@elliottwilliams elliottwilliams released this Jan 14, 2021

ℹ️ This is a maintenance release to support integrating frameworks on Xcode 12.3 and above.

ℹ️ This release does not include forthcoming support for building XCFrameworks. Expect XCFrameworks in the next release, 0.37.0.


  • carthage build disables a validation added in Xcode 12.3 which prevents some Carthage-built frameworks from being embedded (#3095).
    • Xcode 12.3 warns when a target embeds framework with slices labeled for multiple platforms (even when the slices are all housed under different architectures); except, some slight sets of platform pairs are permitted. Typically, Carthage's multi-arch frameworks are stripped at build time using carthage copy-frameworks, but they may be copied whole in test targets and other rare circumstances.
    • When warnings-as-errors is enabled, this validation warning may fail the build. Carthage disables it internally by setting VALIDATE_WORKSPACE=NO.
    • If you see an error like Building for iOS Simulator, but the linked and embedded framework 'REDACTED.framework' was built for iOS + iOS Simulator, set VALIDATE_WORKSPACE=NO in your project's build settings.
  • Fixed carthage creating too many tempoary directories during copy-frameworks phase (#3066). Thanks @tmspzz

Thanks @olejnjak, @philipphofmann for improving the documentation since the last release.


Xcode (at the era of 12.3) does very little when Validate Workspace is enabled. If truly encompassing this facet is important to you… …try copying a Carthage Checkouts/Build directory to another location, editing Xcode projects to remove any targets that (aside from through `carthage copy-frameworks`) embed Carthage-built things, and copy the xcodebuild invocation from a run of `carthage … --verbose` and modify-it, removing VALIDATE_WORKSPACE=NO.
Assets 3

@tmspzz tmspzz released this Sep 18, 2020

⚠️ This version doesn't fix the issue with Xcode 12. See #3019 ⚠️


Thank you to @nixnoughtnothing for improvements to the code base! Thank you to @tmspzz for reviewing pull requests!

Assets 3
  • 0.35.1
  • 0d324cb
  • Compare
    Choose a tag to compare
    Search for a tag
  • 0.35.1
  • 0d324cb
  • Compare
    Choose a tag to compare
    Search for a tag

@tmspzz tmspzz released this Sep 16, 2020

⚠️ This version doesn't fix the issue with Xcode 12. See #3019 ⚠️



  • Sort frameworks so changes in .version files are easier to spot (#3015). Thanks @peteranny!
  • Support NO_PROXY or no_proxy environment variable (#2991). Thanks @okaverin!
  • Prevent re-downloading module stable binaries (#3040). Thanks @justAnotherDev!
  • Remove leftovers of failed archives unzips (#3035). Thanks @tattn!


  • Spelling mistakes in README (#3021). Thanks @thomasaw!
  • Reflect carthage build requirements in README (#3045). Thanks @chrstphrchvz!
  • Installing carthage outside of protected folders no longer requires sudo (#3024). Thanks @cfelder!
  • Remove invalid archs by intersecting VALID_ARCHS and ARCHS (#2987). Thanks @jerbob92!

Thank you to @jdhealy @tmspzz for reviewing pull requests!

Assets 3

@jdhealy jdhealy released this Jun 18, 2020

Carthage now elides a certain warning about Swift compiler versions upon truths from three sources:

  • Swift compiler version (as queried by local machine’s xcode-select and possible TOOLCHAINS environment variable) being greater than 5.1
  • that particular framework’s recorded Swift compiler being greater than 5.1
  • that particular framework matching (somewhat) a glob (working from framework-bundle-root–level) of Modules/*swiftmodule*/*.swiftinterface
    • note: only one directory matching Modules/*swiftmodule*/ will continue querying inside of it — with FileManager.default.contentsOfDirectory defining that
    • note: presence of particular architectures (armv7, i386, x86_64, etc.) are not taken into account

Note: As .swiftinterface files emission “currently [as of Swift 5.X] requires library evolution support” — take warning of the Swift Compiler Team’s message that “Library evolution trades off performance for flexibility” and comes with caveats. • ⚠️ Not every library vendor will desire to enable BUILD_LIBRARY_FOR_DISTRIBUTION in their project’s build settings, or even to field questions on bugs resulting from those adding that scope. Be kind to library vendors that might weigh their potential maintenance/ongoing-qa-debugging work differently then your BUILD_LIBRARY_FOR_DISTRIBUTION desires.

〜 Thanks @DavidBrunow for this feature!

Dynamic Intelligent Platform Parsing

Previously, Carthage would propagate errors upon reading non-compiled-in values from SUPPORTED_PLATFORMS or PLATFORM_NAME.

Carthage 0.35.0 supports SUPPORTED_PLATFORMS or PLATFORM_NAME dynamically with intelligent parsing from xcodebuild -showsdks -json.

Carthage’s --platform argument takes the same input of 2019-era SDKs — however, in alignment with the above: the default (a.k.a. “all”) parameter will allow dynamically-parsed SDKs to propagate.

carthage archive still uses the hardcoded four 2019-era SDKs.

The carthage cleanup command — existing on-master, but unshipped-in-tags — no longer makes sense (when set of SDKs are non-fixed across Xcode versions) and has been removed.

Dynamic Platform Parsing can occur from xcodebuild -showsdks -json with fallbacks to BuildSetting extraction from a Xcode-bundled xcodeproj, and beyond that falling back to hardcoded 2019-era values.

⤵️ Note: the dynamic parsing will omit SDKs — such as DriverKit — where JSON-derived canonicalName and platform do not share a common prefix · DriverKit has an ouptut canonicalName similar to «driverkit.macosx19.0».

Other Breaking Changes


Security Enhancing Breaking Change

Breaking — For Apps Importing Carthage Kit and XCDBLD

For Apps Importing Carthage Kit and XCDBLD
  • Removed: XCDBLD.Platform — replaced (not one-for-one) by struct SDK with new method SDK.platformSimulatorlessFromHeuristic.
  • Removed: XCDBLD’s enum-based SDK — replaced by struct SDK.
  • Removed: XCDBLD.SDK.platform and XCDBLD.SDK.allSDKs.
  • Changed: Hashing and equality for XCDBLD.SDK is case-insensitive.
    • Canonical casing for SDK names available through SDK.knownIn2019YearSDKs and SDK.setFromJSONShowSDKs.
  • Changed: Various type signature changes removing XCDBLD.Platform and incorporating XCDBLD.SDK.
  • Removed: SDK.from(string:) — replaced by SDK.init(name:simulatorHeuristic).
    • Passing an empty string as simulatorHeuristic is usually the foremost codepath.
    • SDK.init(rawValue:) is not intended for wide spread use · as it’s limited to only 2019-era hardcoded SDKs.
  • Removed: BuildSettings.buildSDKs: SignalProducer<SDK, CarthageError> — replaced with BuildSettings.buildSDKRawNames: Set<String>.
  • Made Public: Various VersionFile-related API. Thanks @acecilia!

Thanks to all Contributors

Thank you to @CosynPa, @sidepelican, @chuganzy, @sstadelman (#2781), @giginet (#2761), @ikesyo (#2886, #2785, #2784), @DavidBrunow (#2966, #2967), @mvalentiner, @gubikmic, @sticksen, @nteissler, @ismetanin, @brandonlee503, @yhkaplan, and @tmspzz for improvements to the codebase, tests, and documentation.

Assets 3

@jdhealy jdhealy released this Oct 21, 2019

⚠️ Carthage source only builds on Xcode 10.0+, thus requiring macOS High Sierra 10.13.6. ⚠️

Additional workarounds to enable Xcode 11.0, 11.1, and 11.2 betas have been added; see below.


Breaking — For Apps Importing Carthage Kit

Removed — as a library dependency — SwiftPM and llbuild and reinstated struct CarthageKit.SemanticVersion.

A bug in the-tool-SwiftPM's package resolution resulted in disregard for the (crucial) ‘resolved file’ when resolving branch-based dependencies.

Which would put us in the position of needing any commit of apple/swift-package-manager that didn’t specify its dependency on apple/swift-llbuild in the branch-based style.

Also criteria for the above, working Swift 4.2.X manifests and compilation and working Swift 5.X manifests and compilation.

No such commit of apple/swift-package-manager could be found.

In addition, some confusion around llbuild's sqlite3 linkage made criteria even more confusing.

  • Some initializers and methods on struct Carthage.SemanticVersion have differences from the previous incarnation found in v0.33.0.
  • Reinstate struct CarthageKit.SemanticVersion in all callsites in codebase and tests, removing SPMUtility.Version.
  • No longer necessary to import struct Foundation.URL with the removed import of SPMUtility.
  • Makefile removes complications which previously supported llbuild's sqlite3 linkage.
  • Working Swift 4.2.X compilation is necessary to support building for macOS High Sierra on Homebrew bottling infrastructure.


Future updates will address Catalyst and building of XCFrameworks. Thank you for your patience.

Thank you to @jdhealy, @sstadelman, @tmspzz, @giginet, @olejnjak, and @ikesyo for improvements to the codebase and the infrastructure.

Thank you to @mdiep, @tmspzz, @giginet, and @ikesyo for reviewing pull requests!

Assets 3

@jdhealy jdhealy released this Apr 3, 2019

⚠️ Carthage source only builds on Xcode 10.0+, thus requiring macOS High Sierra. ⚠️

In particular, carthage compiles under Swift 4.2 and 5.0 with Xcode 10.1 and 10.2.


  • In cases where device and simulator destined builds are merged into a single bundle, also merge -Swift.h header files from each with active inclusion of target conditionals (#2723, #2748). Thanks @DavidBrunow, @VictorNouvellet, and @buranmert!
    • Currently limited to a single pair of -Swift.h-suffixed files. Should be sufficient for the vast majority of frameworks.
  • Under --cache-builds mode —
    • Support headerless Swift-containing frameworks via dSYM parsing (#2622). Thanks @blender!
    • When run with --no-skip-current, produce .version files for those additional frameworks (#2636). Thanks @blender!
    • In support of community tooling, embed partial toolchain information (often swiftlang and clang versions) in .version files for Swift-containing frameworks. Expect these .version files to contain different output between Carthage v0.33.0 and previous Carthage versions (#2585, #2707). Thanks @giginet and @kenji21!


  • For file system objects at some level of Carthage/Checkouts/DependencyX, delete with FileManager.removeItem(at:) if using --use-submodules and something exists there that’s not a directory housing a .git subdirectory. This matches Carthage’s existing deletion behavior of checkouts without --use-submodules. Use caution. (#2654).
  • In Cartfiles, specifications with github at the beginning of the line now error when followed by non-http-or-https-schemed URLs (often ssh:// or git:// schemed). We long-standing queried these with web requests, so now errors output earlier in the process with more helpful messaging (#2379). Thanks @ikesyo!
  • Static frameworks under --cache-builds mode highly likely to proceed errantly cache-valid ≈ late caught bug —
    • Will be correctly cache-invalid upon a version-specification change (including changing the specified SHA); also, upon a toolchain change for a Swift-containing static framework (including after a different xcode-select).
    • The first run of a never-modified-by-Carthage-v0.33.0 .version file for a Swift-containing static framework under Carthage v0.33.0 will also cache-invalidate it.
    • carthage build <framework> without --cache-builds will always attempt rebuilding it and it's dependencies.
Note for Apps Importing CarthageKit.framework
  • Carthage (the CLI executable) is now built exclusively with SwiftPM. In effect, the Cartfile supporting CarthageKit.framework has been removed. Consuming CarthageKit is now done through SwiftPM and CarthageKit is now a static library.

On environment variable GIT_SSH_COMMAND

  • An SSH prompt (invisble to a carthage user) could stop progression when encountering a host not yet public-key-fingerprint verified by the user. Carthage now outputs proper messaging at that point, at the expense of GIT_SSH_COMMAND no longer being honored (#2734). Thanks @jlawton!


  • Report read errors from files pointed to by SCRIPT_INPUT_FILE_LIST_ variables (#2668). Thanks @ferranpujolcamins!
  • More efficient, less errant querying of git’s representation of file system objects via ls-tree (#2617). Thanks @CosynPa!
  • More efficient git submodule sync over multiple dependencies (#2643). Thanks @mdiep!

Thank you to @FranklinYu, @DivineDominion, @musbaalbaki, and @salbertson for improvements to the documentation.

Thank you to @mxcl, @giginet, @olejnjak, and @ikesyo for improvements to the codebase and the infrastructure.

Thank you to @blender, @mdiep, @giginet, @DavidBrunow, @VictorNouvellet, and @ikesyo for reviewing pull requests!

Assets 3

@jdhealy jdhealy released this Feb 1, 2019


  • More resiliency towards xcrun simctl list devices --json outputting in keys whose values are available simulator devices (#2693, #2696). Thanks @kmcbride and @DavidBrunow!

Thank you to @giginet, @taher-mosbah, @ikesyo, and @blender for reviewing pull requests!

Assets 4

@jdhealy jdhealy released this Oct 30, 2018

⚠️ Carthage will only consider targets that support the archive action. (#2507 & #2515) ⚠️
⚠️ Carthage does not support Xcode 6 anymore. (#2561) ⚠️
⚠️ Carthage source only builds on Xcode 9.4+, thus requiring macOS High Sierra. ⚠️


  • More resiliency towards xcrun simctl list devices --json outputting isAvailable as String, isAvailable as Bool, or availability as String depending upon whether Xcode 10B61 has been installed, or an Xcode 10.1 beta has been installed (#2630). Thanks @ olejnjak!

Thank you to @artemnovichkov for improvements to the documentation.

Thank you to @ikesyo and @giginet for improvements to the codebase and the infrastructure.

Thank you to @blender, @mdiep, and @ikesyo for reviewing pull requests!

Assets 4