Carthage — 是一个用于Cocoa项目(iOS、macOS、watchOS、tvOS)的去中心化依赖管理器,能够从源代码构建二进制框架。与CocoaPods不同,Carthage不会自动修改项目——开发者自行将构建好的框架添加到Xcode中。Carthage用Swift编写,使用Cartfile描述依赖关系并支持并行构建。根据GitHub仓库的数据,Carthage已获得超过15,000颗星,并且仍然是一个小众但需求量大的工具,适用于需要最小干预Xcode配置的项目。
要点
carthage bootstrap或carthage update执行——Carthage克隆仓库并将其编译为.xcframeworkCarthage — 是一个具有去中心化架构的依赖管理器,由Swift社区开发者在2014年创建。Carthage不使用中央规范注册表——每个库通过URL或GitHub上的名称直接从Git仓库连接。Carthage下载源代码,将其构建为二进制框架(.xcframework或.framework),并为开发者提供准备好的工件,用于手动集成到Xcode项目中。
Carthage的架构包括三个组件:CLI工具carthage、配置文件Cartfile和包含构建好的框架的目录Carthage/Build/。Carthage与CocoaPods的根本区别——缺乏对.xcodeproj的自动修改。Carthage不创建.xcworkspace,不配置编译器标志,也不生成Pods.xcconfig。开发者通过Xcode自行将框架添加到项目中,从而对集成过程拥有完全控制。
Carthage使用依赖项的并行构建,在多核处理器上显著加速过程。每个依赖项作为单独的目标构建,Carthage自动解析传递依赖图,按正确顺序构建它们。根据社区基准测试,Carthage在现代Mac上平均30-60秒构建15-20个依赖项,对于拥有大量库的项目来说比CocoaPods更快。Carthage支持所有Apple平台:iOS、macOS、watchOS和tvOS,从0.38+版本开始——构建通用.xcframework以支持模拟器和Apple Silicon设备。
Carthage克隆每个依赖项的Git仓库,切换到指定版本(标签、提交或分支),并运行xcodebuild来构建框架。Carthage根据构建方案自动确定Xcode项目的类型(框架、动态框架、静态库)。如果项目包含多个方案,Carthage使用默认方案(按字母顺序的第一个)。构建后,Carthage将完成的框架复制到Carthage/Build/,并创建Cartfile.resolved文件,固定精确版本。Carthage支持已构建框架的缓存——如果依赖项没有更改,则不执行重新构建。
Carthage中的传递依赖通过Cartfile.resolved处理:Carthage构建所有必要依赖项的图并按正确顺序构建它们。如果两个库依赖于同一个第三方库,Carthage构建一次并同时用于两者。Carthage报告构建错误时会指明具体目标和原因——这简化了问题的诊断。
Cartfile — 用Ruby语言(Cartfile格式)编写的配置文件,用于定义Carthage项目的依赖项。Cartfile位于项目根目录,与.xcodeproj相邻。Cartfile的每一行描述一个依赖项:源(Git-URL、GitHub仓库)和版本。语法支持通过标签、提交和分支固定版本。
# 基础依赖 Carthage
github "Alamofire/Alamofire" ~> 5.9
github "SnapKit/SnapKit" ~> 5.7
github "onevcat/Kingfisher" == 8.0.0指令github "Owner/Repo" — GitHub仓库的缩写形式。Carthage自动构建https://github.com/Owner/Repo.git形式的URL。对于GitLab、Bitbucket和其他Git托管服务,使用完整URL:git "https://gitlab.com/owner/repo.git"。版本运算符:~> 5.9(5.9到6.0之间的任何版本,不包括6.0),== 8.0.0(精确版本),>= 1.0(最小版本)。通过github "owner/repo" "abc1234"可以连接特定提交。
Carthage支持多个目录用于不同配置:Cartfile(主要)、Cartfile.private(用于不发布的内部依赖项)和Cartfile.resolved(自动生成)。私有依赖项对于仅在Development构建中使用的库很有用,例如测试框架。
# Cartfile — 主要依赖
github "Alamofire/Alamofire" ~> 5.9
github "SwiftyJSON/SwiftyJSON" ~> 4.0
github "realm/realm-swift" ~> 10.0
# 完整 URL 用于 GitLab
git "https://gitlab.com/company/internal-lib.git" == 2.1.1
# 开发分支
github "marmelroy/PhoneNumberKit" "development"github和git — Cartfile中的两种源类型。第一种专用于GitHub并自动形成URL。第二种——用于任何带完整URL的公共或私有Git仓库。版本可以通过标签(== 2.1.1)、语义范围(~> 5.9)、分支名称("development")或提交哈希("a1b2c3d")指定。建议对遵循SemVer的依赖项使用语义范围(~>)——这可以防止更新时的破坏性变更。
Cartfile.resolved在carthage update后自动生成。它固定所有已安装依赖项(包括传递依赖)的精确版本。文件应保存在Git中——没有它,另一台机器上的carthage bootstrap命令将按相同规则构建库,但版本可能不同。carthage outdated显示有可用新版本的过时依赖项列表。
Carthage通过Homebrew(macOS的标准包管理器)安装。替代方法:从GitHub的现成.pkg安装程序安装或从源代码构建。Carthage需要带有Command Line Tools的Xcode(包括xcodebuild),在Apple Silicon Mac上还需要Rosetta 2来处理一些旧版依赖项。
# 安装 Carthage 通过 Homebrew
brew install carthage
# 检查版本
carthage version
# 从 .pkg 安装(如果 Homebrew 不可用)
# 下载 Carthage.pkg 从 GitHub Releases 并手动安装安装后,Carthage项目的初始化从在项目根目录创建Cartfile开始。Carthage没有init命令——文件在文本编辑器中手动创建。填写Cartfile的依赖项后,开发者运行carthage bootstrap(如果Cartfile.resolved已存在)或carthage update(初始安装或更新)。Carthage克隆仓库、构建框架并将它们放置在Carthage/Build/中。
更新Carthage通过brew upgrade carthage完成。版本通过carthage version命令检查。2025年中期的最新稳定版本——0.40,默认支持.xcframework、改进的并行构建和完全支持Swift 6。从0.39版本开始,Carthage停止了没有兼容性桥的旧版.framework的构建——建议明确指定--use-xcframeworks。
# 更新 Carthage 通过 Homebrew
brew upgrade carthage
# 安装特定版本
brew install carthage@0.39
# 完全重新安装
brew uninstall carthage && brew install carthage注意:Carthage不创建.xcworkspace也不修改.xcodeproj。与CocoaPods不同,Carthage将Xcode配置的完全控制权留给开发者。这意味着安装依赖项后,需要手动将框架添加到Xcode中(参见«在Xcode中集成Carthage框架»部分)。Carthage还要求每个依赖项包含一个带有框架目标的Xcode项目或workspace——否则构建将出错。
Carthage提供了三个主要命令来处理依赖项:bootstrap、update和build。carthage bootstrap从现有的Cartfile.resolved构建依赖项——推荐用于CI环境和加入项目的开发者。carthage update将Cartfile.resolved更新到最新版本(考虑Cartfile的限制)并执行构建。carthage build构建所有指定依赖项而不保存版本。
# 初始安装(更新版本)
carthage update --use-xcframeworks --platform iOS
# 根据固定版本重新构建
carthage bootstrap --use-xcframeworks --platform iOS
# 仅构建一个依赖项
carthage build Alamofire --platform iOS--use-xcframeworks标志指示Carthage构建通用.xcframework而不是旧版.framework。这确保了模拟器和真实设备以及Apple Silicon Mac的支持,无需额外脚本。--platform iOS标志将构建限制为单一iOS平台——这显著加速了过程,特别是如果项目中指定了跨平台库。
Carthage通过--cache-builds标志支持并行构建,该标志缓存已构建的框架。在重新构建时,Carthage检查Git提交哈希,如果代码没有更改,则跳过编译。对于CI服务器,建议缓存Carthage/Build/和~/Library/Caches/carthage/目录。Carthage还支持--verbose进行详细日志记录和--no-use-binaries强制从源代码构建(如果开发者不信任预构建的二进制文件)。
| 命令 | 操作 |
|---|---|
carthage update | 更新Cartfile.resolved并构建所有框架 |
carthage bootstrap | 根据现有Cartfile.resolved构建框架而不更新 |
carthage build | 构建指定依赖项而不固定版本 |
carthage outdated | 显示有可用更新的依赖项列表 |
carthage checkout | 仅克隆仓库而不构建 |
集成Carthage框架到Xcode分四个步骤手动完成。执行carthage update或bootstrap后,所有构建好的框架位于Carthage/Build/iOS/(或相应平台)。开发者打开Xcode项目,选择应用程序目标,并将框架添加到General → Frameworks, Libraries, and Embedded Content。对于运行时框架(动态库),必须选择«Embed & Sign»——否则应用程序启动时会崩溃并出现错误«dyld: Library not loaded»。
Carthage对于静态库更简单——它们不需要嵌入阶段,因为它们直接链接到应用程序的可执行文件。然而,Carthage默认构建动态框架(除非明确配置了静态库)。对于需要最小化应用程序大小的项目,建议通过Xcode设置使用静态链接。
额外步骤——在Build Phase → Run Script中添加Input Files。Carthage需要一个脚本从构建好的框架中删除模拟器工件(strip simulator architectures)。此脚本对于App Store构建是必需的:
# Run Script 用于 App Store (strip simulator architectures)
FRAMEWORKS_DIR="${SRCROOT}/Carthage/Build/iOS"
for framework in "$FRAMEWORKS_DIR"/*.framework; do
bash "$BUILD_DIR/src/scripts/strip-framework.sh" "$framework"
doneCarthage不需要使用.xcworkspace——所有依赖项已构建为二进制框架。Carthage直接与.xcodeproj一起工作,与创建workspace的CocoaPods不同。这简化了版本控制和CI配置,因为Carthage依赖项不会更改Xcode项目的配置。唯一的更改——将框架添加到目标,这在.pbxproj中记录。
| 步骤 | 操作 |
|---|---|
| 1 | 执行carthage update --use-xcframeworks |
| 2 | 将框架从Carthage/Build/拖到General → Frameworks |
| 3 | 为动态框架设置Embed & Sign |
| 4 | 添加Run Script Phase以删除模拟器架构 |
| 5 | 构建项目——框架应自动链接 |
Carthage、CocoaPods和Swift Package Manager (SPM) — iOS开发中的三个主要依赖管理器。Carthage以其去中心化的方法著称,CocoaPods提供集中式注册表,SPM则是Apple的内置解决方案。它们之间的选择取决于项目需求、团队规模和所需的自动化水平。
| 标准 | Carthage | CocoaPods | SPM |
|---|---|---|---|
| 架构 | 去中心化 | 集中式注册表 | 集成在Xcode中 |
| 配置语言 | Cartfile(类Ruby) | Podfile(Ruby DSL) | Package.swift(Swift) |
| 与Xcode集成 | 手动(拖放) | 通过workspace | 内置 |
| 传递依赖 | 自动 | 自动 | 自动 |
| 库注册表 | 无(Git仓库) | Specs中超过100,000 | ~65,000 |
| 资源支持 | 无 | 有(resource bundles) | 有(Resources) |
| 构建速度 | 快(并行) | 中等 | 快 |
| 集成控制 | 完全 | 自动 | 自动 |
Carthage适用于需要最小干预Xcode配置并完全控制集成过程的项目。Carthage是开放库和框架的理想选择,作者希望让用户能够独立构建依赖项。Carthage在重视UNIX哲学的开发者社区中也很受欢迎:每个工具做好一件事。CocoaPods仍然是拥有数十个依赖项的企业项目的标准,自动化很重要。SPM——新项目的选择,因为它集成在Xcode中并得到Apple的积极开发。
迁移在不同管理器之间需要不同的方法。Carthage → SPM:从Xcode中删除框架,删除Cartfile并通过File → Add Package Dependencies添加Package Dependencies。Carthage → CocoaPods:删除Carthage框架,创建Podfile,添加依赖项并执行pod init && pod install。从Carthage迁移到CocoaPods或SPM时,手动更新框架的需求消失——所有依赖项通过一个命令更新。Carthage在需要避免供应商锁定并保持依赖项构建透明度的项目中仍然具有相关性。
Carthage — 一个稳定的工具,但开发者偶尔会遇到典型问题,特别是在CI服务器上构建、更新Xcode或更改Swift版本时。大多数问题通过清除缓存、正确配置--use-xcframeworks和检查最低iOS版本兼容性来解决。
错误«The file manager returned an error» — 在Carthage缓存损坏或文件权限冲突时出现。解决方法:使用命令rm -rf ~/Library/Caches/carthage删除缓存并重新运行carthage bootstrap。删除项目中的Carthage/目录并重新构建也有帮助。在CI服务器上,Carthage缓存只应在Cartfile.resolved更改时更新。
错误«No such module» — 尽管Carthage构建成功,但框架未在Xcode中找到。解决方法:检查General → Frameworks, Libraries, and Embedded Content中的框架路径。框架应位于Carthage/Build/iOS/。确保.xcframework已正确添加(重新拖入)。对于动态框架,检查Embed & Sign。如果错误仍然存在——在Build Settings中添加FRAMEWORK_SEARCH_PATHS。
因Swift不兼容导致的构建错误 — 库是为与项目不同版本的Swift构建的。解决方法:使用carthage update --no-use-binaries强制使用相同版本的Swift从源代码构建。如果库在当前版本下无法编译——使用.xcconfig指定Swift版本或fork该库。从Carthage 0.39开始,--use-xcframeworks自动将正确的Swift版本包含在二进制文件中。
CI构建问题 — Carthage在CI上需要正确的缓存配置。解决方法:缓存Carthage/Build/和~/Library/Caches/carthage/。在CI上使用carthage bootstrap --use-xcframeworks --platform iOS而不是update,以避免更改版本。对于GitHub Actions,有官方的Carthage操作。对于Jenkins——CarthageBuild插件。Carthage在没有GUI的macOS上可能崩溃——解决方法:安装brew install xcode-build-server或添加参数-UseModernBuildSystem=NO。
| 问题 | 原因 | 解决方法 |
|---|---|---|
| File manager error | 缓存损坏 | 清理~/Library/Caches/carthage/ |
| No such module | 框架未添加到Xcode | 检查目标中的框架 |
| Swift不兼容 | 不同版本的Swift | --no-use-binaries或新版本Carthage |
| CI错误 | 缺少缓存或GUI | 配置Carthage/Build/缓存 |
| 库无法构建 | 库没有Xcode项目 | 检查仓库结构 |
常见问题
Carthage — 适用于Apple平台的去中心化依赖管理器。与CocoaPods不同,Carthage不使用中央库注册表,不自动修改Xcode项目,也不创建.xcworkspace。Carthage将依赖项构建为二进制框架,开发者手动将其添加到Xcode中。相比之下,CocoaPods通过Podfile自动化整个过程。
Carthage通过Homebrew安装:brew install carthage。或者——从GitHub Releases下载Carthage.pkg或从源代码构建。安装后检查版本:carthage version。Carthage需要带有Command Line Tools的Xcode。在Apple Silicon Mac上可能还需要Rosetta 2。
Cartfile — 由开发者编写的配置文件:包含库名称和版本运算符(~> 5.9、== 8.0.0、分支名称)。Cartfile.resolved在carthage update时自动生成,并固定所有已安装依赖项的精确版本。Cartfile.resolved应保存在Git中——它保证了在所有机器上构建的可重复性。
Carthage要求库包含带有框架目标的正确Xcode项目或workspace。检查仓库是否可访问(不是无密钥的私有仓库)、是否指定了正确版本(标签或提交存在)以及库是否支持您的Xcode版本。使用carthage build --verbose进行详细诊断。如果库没有框架目标,Carthage将无法构建它。
Carthage对于需要去中心化依赖管理、完全控制集成和最小干预Xcode项目的项目仍然具有相关性。然而,大多数新项目选择Swift Package Manager (SPM)——它集成在Xcode中,不需要额外安装,并且由Apple积极开发。Carthage建议用于已有构建管道的遗留项目,或者作者希望让用户自由选择集成方式的库。
总结
brew install carthage,依赖项构建通过carthage bootstrap或carthage update--no-use-binaries标志和CI缓存配置解决我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。