A simple, decentralized dependency manager for Cocoa
Fixed
xros
/xrsimulator
. Make additive changes to XCDBLD
’s SDK
. (#3345).-static-stdlib
when Xcodes are accommodated. (#3350).Acknowledgments
Thanks to all contributors.
Full Changelog: https://github.com/Carthage/Carthage/compare/0.38.0...0.39.0
Fixed
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! :tada:
Project lookup is faster for dependencies which contain multiple xcodeprojs (#3076).
Known issues
carthage archive
does not archive built XCFrameworks
--use-xcframeworks
option, and once without. Then, create a zip from the Carthage/Build
folder.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.
.framework.zip
and .xcframework.zip
archivesStarting in 0.38.0, Carthage follows a naming convention to distinguish between XCFrameworks and plain framework bundles:
.xcframework
in the name is considered to contain XCFrameworks.framework
in the name is considered to contain plain framework bundles--use-xcframeworks
is flagged. Sets entirely 'not-matching-comparison' will see no removal of download candidates.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.
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:
MyFramework-v1.2.3.framework.zip
and MyFramework-v1.2.3.xcframework.zip
.alt=
parameter with the xcframework zip's URL.Suppose we're releasing v1.2.3
of a project called MyFramework
:
Create an xcframeworks build using --use-xcframeworks:
carthage build --use-xcframeworks --no-skip-current
zip -r MyFramework-v1.2.3.xcframework.zip Carthage/Build
Create a plain frameworks build:
carthage build --no-skip-current
zip -r MyFramework-v1.2.3.framework.zip Carthage/Build
Upload both archives, MyFramework-v1.2.3.xcframework.zip
and MyFramework-v1.2.3.framework.zip
.
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"
}
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:
BUILD_LIBRARIES_FOR_DISTRIBUTION
build setting and the current Swift compiler version is greater than 5.1, or〜 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.
Fixed
xcrun lipo
(https://github.com/Carthage/Carthage/issues/3019). Fix by passing --use-xcframeworks
and re-integrating your dependencies as XCFrameworks, or by using a workaround xcconfig on Intel-based Macs.Added
Carthage produces XCFrameworks instead of universal frameworks when --use-xcframeworks
is passed. (https://github.com/Carthage/Carthage/pull/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.
--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.
binary
dependencies using the strategy of platform-specific frameworks.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, 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:
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.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 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.
:information_source: This is a maintenance release to support integrating frameworks on Xcode 12.3 and above.
:information_source: This release does not include forthcoming support for building XCFrameworks. Expect XCFrameworks in the next release, 0.37.0.
Fixed
carthage build
disables a validation added in Xcode 12.3 which prevents some Carthage-built frameworks from being embedded (https://github.com/Carthage/Carthage/pull/3095).
carthage copy-frameworks
, but they may be copied whole in test targets and other rare circumstances.VALIDATE_WORKSPACE=NO
.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.copy-frameworks
phase (Carthage/Carthage#3066). Thanks @tmspzzThanks @olejnjak, @philipphofmann for improving the documentation since the last release.
Note
Fixed
copy-frameworks
(#3047). Thanks @rudedogdhc!Thank you to @nixnoughtnothing for improvements to the code base! Thank you to @tmspzz for reviewing pull requests!
Fixed
Added
NO_PROXY
or no_proxy
environment variable (#2991). Thanks @okaverin!Improved
sudo
(#3024). Thanks @cfelder!Thank you to @jdhealy @tmspzz for reviewing pull requests!
Carthage now elides a certain warning about Swift compiler versions upon truths from three sources:
xcode-select
and possible TOOLCHAINS
environment variable) being greater than 5.1Modules/*swiftmodule*/*.swiftinterface
Modules/*swiftmodule*/
will continue querying inside of it — with FileManager.default.contentsOfDirectory
defining thatNote: 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. • :warning: 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
.version
files. Thanks @elliottwilliams!
.version
files output for Swift static frameworks..version
files for affected Swift static frameworks, change Swift versions and rerun Carthage with the --cache-builds
flag (even temporarily), or delete .framework
bundles for affected Swift static ones and rerun Carthage with the --cache-builds
flag.application/x-zip-compressed
. Thanks @MatkovIvan!--use-netrc
flag under which basic ~/.netrc
files facilitate binary
-specified framework download authentication. Thanks @mollyIV!Stability
Security Enhancing Breaking Change
git
-specified repository URL components — specifically nul characters (\u{0000}
) and periods (\u{0023}
). Thanks @manicmaniac!
\u{FF0E}
) and replacement ␀
(\u{2400}
).\u{0023}
) will not see inserted «Full Width Full Stops» (\u{FF0E}
).Breaking — For Apps Importing Carthage Kit and XCDBLD
XCDBLD.Platform
— replaced (not one-for-one) by struct SDK
with new method SDK.platformSimulatorlessFromHeuristic
.XCDBLD
’s enum-based SDK
— replaced by struct SDK
.XCDBLD.SDK.platform
and XCDBLD.SDK.allSDKs
.XCDBLD.SDK
is case-insensitive.
SDK.knownIn2019YearSDKs
and SDK.setFromJSONShowSDKs
.XCDBLD.Platform
and incorporating XCDBLD.SDK
.SDK.from(string:)
— replaced by SDK.init(name:simulatorHeuristic)
.
simulatorHeuristic
is usually the foremost codepath.BuildSettings.buildSDKs: SignalProducer<SDK, CarthageError>
— replaced with BuildSettings.buildSDKRawNames: Set<String>
.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.
⚠️ 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.
Fixed
Breaking — For Apps Importing Carthage Kit
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.
struct Carthage.SemanticVersion
have differences from the previous incarnation found in v0.33.0.struct CarthageKit.SemanticVersion
in all callsites in codebase and tests, removing SPMUtility.Version
.import struct Foundation.URL
with the removed import of SPMUtility.llbuild
's sqlite3
linkage.Important
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!
⚠️ 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.
Fixed
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!
-Swift.h
-suffixed files. Should be sufficient for the vast majority of frameworks.--cache-builds
mode —
--no-skip-current
, produce .version
files for those additional frameworks (#2636). Thanks @blender!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!Notable
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).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!--cache-builds
mode highly likely to proceed errantly cache-valid ≈ late caught bug —
xcode-select
)..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.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
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!Improved
SCRIPT_INPUT_FILE_LIST_
variables (#2668). Thanks @ferranpujolcamins!ls-tree
(#2617). Thanks @CosynPa!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!