Carthage is a dependency manager for Swift and Objective-C projects that aims to provide a simpler tool thatâs more flexible and easier to understand and maintain. Hereâs how Carthage achieves this:
Carthage builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage does not automatically modify your project files or your build settings.
Note that Carthage only supports dynamic frameworks, which are only available on iOS 8 or later (or any version of OS X). Using XCFrameworks as of version 0.37.0 (January 2021), and require XCFrameworks when building on an Apple Silicon Mac.
Carthage will check to make sure that downloaded Swift (and mixed Objective-C/Swift) frameworks were built with the same version of Swift that is in use locally. If there is a version mismatch, Carthage will proceed to build the framework from source. If the framework cannot be built from source, Carthage will fail.
brew install carthage
.Cartfile
in the same directory where your .xcodeproj
or .xcworkspace
isCartfile
, for example:github "Alamofire/Alamofire" ~> 5.5
carthage update --use-xcframeworks
Cartfile.resolved
file and a Carthage
directory will appear in the same directory where your .xcodeproj
or .xcworkspace
is.xcframework
bundles from Carthage/Build
into the âFrameworks and Librariesâ section of your applicationâs Xcode project.Make sure to commit your Cartfile.resolved
, because anyone else using the project will need that file to build the same framework versions.
After youâve finished the above steps and pushed your changes, other users of the project only need to fetch the repository and run carthage bootstrap to get started with the frameworks youâve added.
Cartfile
that lists the frameworks youâd like to use in your project.carthage update
. This will fetch dependencies into a Carthage/Checkouts
folder, then build each one or download a pre-compiled framework.Carthage/Build
folder on disk. Then, in the âEmbedâ section, select âDo Not Embedâ from the pulldown menu for each item added. For Xcode 10.x and lower, in the âLinked Frameworks and Librariesâ section, drag and drop each framework you want to use from the Carthage/Build
folder on disk./bin/sh
), add the following contents to the script area below the shell:/usr/local/bin/carthage copy-frameworks
input.xcfilelist
and a file named output.xcfilelist
input.xcfilelist
. For example:$(SRCROOT)/Carthage/Build/iOS/Result.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveSwift.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework
output.xcfilelist
. For example:$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ReactiveSwift.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ReactiveCocoa.framework
With output files specified alongside the input files, Xcode only needs to run the script when the input files have changed or the output files are missing. This means dirty builds will be faster when you havenât rebuilt frameworks with Carthage.
input.xcfilelist
to the âInput File Listsâ section of the Carthage run script phaseoutput.xcfilelist
to the âOutput File Listsâ section of the Carthage run script phaseThis script works around an App Store submission bug triggered by universal binaries and ensures that necessary bitcode-related files and dSYMs are copied when archiving.
The three supported origins right now are GitHub repositories, Git repositories, and binary-only frameworks served over https.
Carthage supports several kinds of version requirements:
>= 1.0
for âat least version 1.0â~> 1.0
for âcompatible with version 1.0â== 1.0
for âexactly version 1.0âIf no version requirement is given, any version of the dependency is allowed.
# Require version 2.3.1 or later
github "ReactiveCocoa/ReactiveCocoa" >= 2.3.1
# Require version 1.x
github "Mantle/Mantle" ~> 1.0 # (1.0 or later, but less than 2.0)
# Require exactly version 0.4.1
github "jspahrsummers/libextobjc" == 0.4.1
# Use the latest version
github "jspahrsummers/xcconfigs"
# Use the branch
github "jspahrsummers/xcconfigs" "branch"
# Use a project from GitHub Enterprise
github "https://enterprise.local/ghe/desktop/git-error-translations"
# Use a project from any arbitrary server, on the "development" branch
git "https://enterprise.local/desktop/git-error-translations2.git" "development"
# Use a local project
git "file:///directory/to/project" "branch"
# A binary only framework
binary "https://my.domain.com/release/MyFramework.json" ~> 2.3
# A binary only framework via file: url
binary "file:///some/local/path/MyFramework.json" ~> 2.3
# A binary only framework via local relative path from Current Working Directory to binary project specification
binary "relative/path/MyFramework.json" ~> 2.3
# A binary only framework via absolute path to binary project specification
binary "/absolute/path/MyFramework.json" ~> 2.3
When you run carthage update, Carthage creates a couple of files and directories for you:
Cartfile.resolved
: This file serves as a companion to the Cartfile. It defines exactly which versions of your dependencies Carthage selected for installation. Itâs strongly recommended to commit this file to your version control repository. Its presence ensures that other developers can get started quickly by using the exact same dependency versions.
Carthage/Build
: This contains the built framework for each dependency. You can integrate these into your project, and youâll do so shortly. Carthage either builds each framework from source or downloads it from the projectâs Releases page on GitHub.
Carthage/Checkouts
: This is where Carthage checks out the source code for each dependency thatâs ready to build into frameworks. Carthage maintains its own internal cache of dependency repositories, so it doesnât have to clone the same source multiple times for different projects.
Whether you commit the Build and Checkouts directories to your version control repository is up to you. Itâs not required, but doing so means that anybody who clones your repository will have the binaries and source for each dependency available.
Having this backup can be a useful insurance policy if GitHub is unavailable or a source repository is removed.