github Carthage/Carthage 0.38.0
0.38.0 — Prebuilt Parity

latest releases: 0.39.1, 0.39.0
2 years ago

Fixed

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

Added

  • 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 .framework.zip and .xcframework.zip 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": "https://example.com/releases/MyFramework-v1.2.3.framework.zip?alt=https://example.com/releases/MyFramework-v1.2.3.xcframework.zip"
}

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. MyFramework-v1.2.3.framework.zip and MyFramework-v1.2.3.xcframework.zip.
  • 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 MyFramework-v1.2.3.xcframework.zip Carthage/Build
    
  2. Create a plain frameworks build:

    carthage build --no-skip-current
    zip -r MyFramework-v1.2.3.framework.zip Carthage/Build
    
  3. Upload both archives, MyFramework-v1.2.3.xcframework.zip and MyFramework-v1.2.3.framework.zip.

  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": "https://example.com/releases/MyFramework-v1.2.3.framework.zip?alt=https://example.com/releases/MyFramework-v1.2.3.xcframework.zip"
    }

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.

Don't miss a new Carthage release

NewReleases is sending notifications on new releases.