Releases: Carthage/Carthage
0.40.0
Changes
- Under all Xcodes and
xcodebuild
s — Carthage will passSUPPORTS_MACCATALYST=NO
just beforeCARTHAGE=YES
.- We consider adding that passed/hardcoded build setting safe — considering any likelihood ‘build setting chaining/interpolation’ using
SUPPORTS_MACCATALYST
is guessed to be almost entirely non-existent. Please file an issue if unexpected effects are seen.
- We consider adding that passed/hardcoded build setting safe — considering any likelihood ‘build setting chaining/interpolation’ using
- Under all Xcode versions, all xcodebuild invocations of
-showBuildSettings
that return non-0 exit code and standardError matchingerror[:] [^\n]*Found no destinations for the scheme [^\n]+ and action [^\n]+[.]\n
will see non-surfacing of those errors. Carthage proceeds as if that xcodebuild invocation never happened (which is essentially how Carthage behaved before it had one more non-0 exit code return to deal with.) - No longer (under Xcode 16 and above) prefix
-showBuildSettings
with solely thearchive
action. Carthage has long-standingly builtsimulator
code under thebuild
action. - Xcode Build Setting
OBJROOT
now appears to have more path components. We lop some path components off (only under Xcode 16 and above.)
Acknowledgements
Thank you to @prassyy for a pull request!
0.39.1
0.39.0
Fixed
What's Changed
- Add: --use-xcframeworks check by @ryu1sazae in #3204
- Fix typo in fileReadCorruptFile error description by @TTOzzi in #3231
- README.md: HTTP => HTTPS by @Schweinepriester in #3244
- Update Xcode12Workaround.md by @Huang-Libo in #3248
- Use modern Alamofire version in README by @jshier in #3200
- Fix issue where Carthage doesn’t build for watchOS or tvOS if bitcode is disabled in Xcode 14 by @daltonclaybrook in #3293
- Bump up version to 0.39.0 by @giginet in #3318
New Contributors
- @ryu1sazae made their first contribution in #3204
- @TTOzzi made their first contribution in #3231
- @Schweinepriester made their first contribution in #3244
- @Huang-Libo made their first contribution in #3248
- @jshier made their first contribution in #3200
- @daltonclaybrook made their first contribution in #3293
Full Changelog: 0.38.0...0.39.0
0.38.0 — Prebuilt Parity
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 theCarthage/Build
folder.
- Support for making an xcframework archive will be added in a future release. For now, manually create archives by building twice: once with the
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
andMyFramework-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
:
-
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
andMyFramework-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" }
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:
- contains no bundles with «.swiftmodule»-suffixed files, or
- any bundle with «.swiftmodule»-suffixed files contains Swift components built under
BUILD_LIBRARIES_FOR_DISTRIBUTION
build setting and the current Swift compiler version is greater than 5.1, or - any bundle not passing the above was built with the current compiler version.
〜 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.
0.37.0 — Architectural Alchemy
Fixed
- Building a framework using Xcode 12 fails with a build error from
xcrun lipo
(#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. (#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 forarm64
, 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 acarthage 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 forgithub
dependencies which download binaries.- Workaround: Pass
--no-use-binaries
to make Carthage rebuild the dependency from source, which will produce an XCFramework.
- Workaround: Pass
carthage archive
does not archive built XCFrameworks, and--use-xcframeworks
does not produce an xcframework forbinary
dependencies.- Support for binary xcframeworks will be added in a future release. For now, continue integrating
binary
dependencies using the strategy of platform-specific frameworks.
- Support for binary xcframeworks will be added in a future release. For now, continue integrating
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 fromCONFIGURATION_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 aCarthage/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.
0.36.1 — Workspace Well-Being
ℹ️ 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.
Fixed
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.
- 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
- 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.
Note
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.0.36.0 - Portuguese Pastel
⚠️ This version doesn't fix the issue with Xcode 12. See #3019 ⚠️
Fixed
- Prevent cross device issues in
copy-frameworks
(#3047). Thanks @rudedogdhc!
Thank you to @nixnoughtnothing for improvements to the code base! Thank you to @tmspzz for reviewing pull requests!
0.35.1 - Continuous Commitment
⚠️ This version doesn't fix the issue with Xcode 12. See #3019 ⚠️
Fixed
- Fixed copying files across different volumes (#3025). Thanks @rudedogdhc!
Added
- Sort frameworks so changes in .version files are easier to spot (#3015). Thanks @peteranny!
- Support
NO_PROXY
orno_proxy
environment variable (#2991). Thanks @okaverin! - Prevent re-downloading module stable binaries (#3040). Thanks @justAnotherDev!
- Remove leftovers of failed archives unzips (#3035). Thanks @tattn!
Improved
- 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!
0.35.0 - Carrageenan Cabaletta
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 possibleTOOLCHAINS
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 — withFileManager.default.contentsOfDirectory
defining that - note: presence of particular architectures (armv7, i386, x86_64, etc.) are not taken into account
- note: only one directory matching
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. • 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.
canonicalName
and platform
do not share a common prefix · DriverKit has an ouptut canonicalName
similar to «driverkit.macosx19.0».
Other Breaking Changes
- Track static frameworks in
.version
files. Thanks @elliottwilliams!- Old carthage versions will still behave erroneous — but not propagate errors — after parsing sets of newer
.version
files output for Swift static frameworks. - To guarantee output of newer
.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.
- Old carthage versions will still behave erroneous — but not propagate errors — after parsing sets of newer
- For GitHub Release assets, expand permitted MIME types to include
application/x-zip-compressed
. Thanks @MatkovIvan! - Reject invalid binary archives containing the same framework multiple times. Thanks @tmspzz!
- For binary-spec-ed dependencies and GitHub Release downloads, copy dSYMs if any architecture matches current binary — also affects CarthageKit consumers. Thanks @hlineholm!
- Conflict less in concurrent strip-framework–dedicated Carthage process invocations via different underlying copying — rather than overwrite straight from process, now temp directory usage prevents conflicts on certain same-file/same-path writes. Thanks @kalkwarf!
- Fallback to dSYM version parsing for more cases before invalidating cached builds. Thanks @kmcbride!
- Add
--use-netrc
flag under which basic~/.netrc
files facilitatebinary
-specified framework download authentication. Thanks @mollyIV!
Stability
- Fix various cases of «Segmentation Fault 11». Thanks @taisukeh!
- Extend error messages when reading certain binaries. Thanks @hlineholm!
Security Enhancing Breaking Change
- Prevent directory traversal through additional sanitization of
git
-specified repository URL components — specifically nul characters (\u{0000}
) and periods (\u{0023}
). Thanks @manicmaniac!- Replacement strings include repeated «Full Width Full Stops» (
\u{FF0E}
) and replacement␀
(\u{2400}
). - URL components not starting with periods (
\u{0023}
) will not see inserted «Full Width Full Stops» (\u{FF0E}
).
- Replacement strings include repeated «Full Width Full Stops» (
Breaking — For Apps Importing Carthage Kit and XCDBLD
For Apps Importing Carthage Kit and XCDBLD
- Removed:
XCDBLD.Platform
— replaced (not one-for-one) bystruct SDK
with new methodSDK.platformSimulatorlessFromHeuristic
. - Removed:
XCDBLD
’s enum-basedSDK
— replaced bystruct SDK
. - Removed:
XCDBLD.SDK.platform
andXCDBLD.SDK.allSDKs
. - Changed: Hashing and equality for
XCDBLD.SDK
is case-insensitive.- Canonical casing for SDK names available through
SDK.knownIn2019YearSDKs
andSDK.setFromJSONShowSDKs
.
- Canonical casing for SDK names available through
- Changed: Various type signature changes removing
XCDBLD.Platform
and incorporatingXCDBLD.SDK
. - Removed:
SDK.from(string:)
— replaced bySDK.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.
- Passing an empty string as
- Removed:
BuildSettings.buildSDKs: SignalProducer<SDK, CarthageError>
— replaced withBuildSettings.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.
0.34.0 - Barometric Ballasting
Additional workarounds to enable Xcode 11.0, 11.1, and 11.2 betas have been added; see below.
Fixed
- ASCII alphabet for Semantic Version pre-release and build metadata components now includes uppercase and lowercase W, fixing an omission and completing the alphabet (#2805 #2806). Thanks @drakerr!
- Workaround Swift 5.1 compiler crash bug to allow the compilation of Carthage itself on Xcode 11, Xcode 11.1, and Xcode 11.2 betas (#2859). Thanks @michaelmcguire!
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, removingSPMUtility.Version
. - No longer necessary to
import struct Foundation.URL
with the removed import of SPMUtility. - Makefile removes complications which previously supported
llbuild
'ssqlite3
linkage. - Working Swift 4.2.X compilation is necessary to support building for macOS High Sierra on Homebrew bottling infrastructure.
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!