Carthage 旨在成为向 Cocoa 应用程序添加框架的最简单方法。
Carthage 构建您的依赖项并为您提供二进制框架,但您保留对项目结构和设置的完全控制。 Carthage 不会自动修改您的项目文件或构建设置。
通过运行brew install carthage
获取Carthage 或选择其他安装方法
在.xcodeproj
或.xcworkspace
所在的同一目录中创建一个 Cartfile
在 Cartfile 中列出所需的依赖项,例如:
github "Alamofire/Alamofire" ~> 5.5
运行carthage update --use-xcframeworks
Cartfile.resolved
文件和Carthage
目录将出现在.xcodeproj
或.xcworkspace
所在的同一目录中
将构建的.xcframework
包从Carthage/Build
拖到应用程序 Xcode 项目的“框架和库”部分。
如果您使用 Carthage 作为应用程序,请选择“嵌入并签名”,否则选择“不嵌入”。
如需深入指南,请阅读向应用程序添加框架
安装 Carthage 有多种选项:
安装程序:下载并运行最新版本的Carthage.pkg
文件,然后按照屏幕上的说明进行操作。如果您通过 CLI 安装 pkg,则可能需要先运行sudo chown -R $(whoami) /usr/local
。
Homebrew:您可以使用 Homebrew 并通过运行brew update
和brew install carthage
在您的系统上安装carthage
工具。 (注意:如果您之前安装了 Carthage 的二进制版本,则应删除/Library/Frameworks/CarthageKit.framework
)。
MacPorts:您只需运行sudo port selfupdate
和sudo port install carthage
即可使用 MacPorts 并在系统上安装carthage
工具。 (注意:如果您之前安装了 Carthage 的二进制版本,则应删除/Library/Frameworks/CarthageKit.framework
)。
来自源代码:如果您想运行最新的开发版本(可能非常不稳定或不兼容),只需克隆存储库的master
分支,然后运行make install
。需要 Xcode 10.0 (Swift 4.2)。
安装 Carthage 后,您就可以开始向项目添加框架。请注意,Carthage 仅支持动态框架,该框架仅在 iOS 8 或更高版本(或任何版本的 OS X)上可用。
carthage update --use-xcframeworks
。这会将依赖项获取到 Carthage/Checkouts 文件夹中并构建每个依赖项或下载预编译的 XCFramework。我们鼓励从版本 0.37.0(2021 年 1 月)开始使用 XCFrameworks,并且在 Apple Silicon Mac 上构建时需要 XCFrameworks。从离散框架包切换到 XCFrameworks 需要对您的项目进行一些更改:
Carthage/Build
文件夹以删除任何现有的框架包。carthage build --use-xcframeworks
构建新的 XCFrameworks 。您构建的任何其他参数都可以像平常一样提供。carthage copy-frameworks
构建阶段(如果存在)。Xcode 12+ 不兼容:在 Xcode 12 及更高版本中构建框架捆绑包时,不支持多架构平台。更喜欢使用 XCFrameworks 进行构建。如果您需要构建离散框架捆绑包,请使用解决方法 xcconfig 文件。
carthage update --platform macOS
。这会将依赖项获取到 Carthage/Checkouts 文件夹中并构建每个依赖项或下载预编译的框架。此外,您还需要复制调试符号以在 OS X 上进行调试和崩溃报告。
创建一个 Cartfile,其中列出您想要在项目中使用的框架。
运行carthage update
。这会将依赖项获取到 Carthage/Checkouts 文件夹中,然后构建每个依赖项或下载预编译的框架。
打开应用程序目标的常规设置选项卡。对于 Xcode 11.0 及更高版本,在“框架、库和嵌入式内容”部分中,从磁盘上的 Carthage/Build 文件夹中拖放要使用的每个框架。然后,在“嵌入”部分中,从下拉菜单中为添加的每个项目选择“不嵌入”。对于 Xcode 10.x 及更低版本,在“链接的框架和库”部分中,从磁盘上的 Carthage/Build 文件夹中拖放要使用的每个框架。
在应用程序目标的“构建阶段”设置选项卡上,单击+图标并选择“新建运行脚本阶段” 。创建一个运行脚本,在其中指定您的 shell(例如: /bin/sh
),将以下内容添加到 shell 下面的脚本区域:
/usr/local/bin/carthage copy-frameworks
创建名为input.xcfilelist
的文件和名为output.xcfilelist
的文件
将要使用的框架的路径添加到input.xcfilelist
。例如:
$(SRCROOT)/Carthage/Build/iOS/Result.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveSwift.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework
将复制的框架的路径添加到output.xcfilelist
。例如:
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Result.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ReactiveSwift.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ReactiveCocoa.framework
通过与输入文件一起指定输出文件,Xcode 仅需要在输入文件发生更改或输出文件丢失时运行脚本。这意味着当您没有使用 Carthage 重建框架时,脏构建会更快。
将input.xcfilelist
添加到 Carthage 运行脚本阶段的“输入文件列表”部分
将output.xcfilelist
添加到Carthage运行脚本阶段的“输出文件列表”部分
该脚本解决了由通用二进制文件触发的 App Store 提交错误,并确保在存档时复制必要的位码相关文件和 dSYM。
将调试信息复制到构建的产品目录中后,每当您在断点处停止时,Xcode 将能够对堆栈跟踪进行符号化。这还将使您能够在调试器中单步调试第三方代码。
当归档您的应用程序以提交到 App Store 或 TestFlight 时,Xcode 还会将这些文件复制到应用程序的.xcarchive
包的 dSYMs 子目录中。
在此过程中,迦太基将创建一些构建工件。其中最重要的是 Cartfile.resolved 文件,其中列出了为每个框架实际构建的版本。确保提交您的 Cartfile.resolved ,因为使用该项目的其他人都需要该文件来构建相同的框架版本。
您可以添加运行脚本阶段,以便在依赖项之一过期时自动向您发出警告。
Build Phases
设置选项卡上,单击+
图标并选择New Run Script Phase
。创建一个运行脚本,在其中指定您的 shell(例如: /bin/sh
),将以下内容添加到 shell 下面的脚本区域: /usr/local/bin/carthage outdated --xcode-warnings 2> /dev/null
Carthage 将检查以确保下载的 Swift(以及混合 Objective-C/Swift)框架是使用本地使用的相同版本的 Swift 构建的。如果版本不匹配,Carthage 将继续从源代码构建框架。如果框架不能从源代码构建,迦太基就会失败。
由于 Carthage 使用xcrun swift --version
的输出来确定本地 Swift 版本,因此请确保使用您打算使用的 Swift 工具链运行 Carthage 命令。对于许多用例来说,不需要任何额外的操作。但是,例如,如果您使用 Xcode 8.x 构建 Swift 2.3 项目,则为carthage bootstrap
指定默认swift
的一种方法是使用以下命令:
TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 carthage bootstrap
完成上述步骤并推送更改后,项目的其他用户只需获取存储库并运行carthage bootstrap
即可开始使用您添加的框架。
使用 Carthage 处理任意目标的依赖关系与使用 Carthage 处理应用程序非常相似。主要区别在于框架在 Xcode 中的实际设置和链接方式。
由于单元测试目标在其“常规”设置选项卡中缺少“链接的框架和库”部分,因此您必须将构建的框架拖到“将二进制文件与库链接”构建阶段。
在“构建设置”选项卡下的“测试目标”中,将@loader_path/Frameworks
添加到运行路径搜索路径(如果尚不存在)。
在极少数情况下,您可能还希望将每个依赖项复制到构建产品中(例如,将依赖项嵌入到外部框架中,或确保依赖项存在于测试包中)。为此,请使用框架目标创建一个新的复制文件构建阶段,然后在其中添加框架引用。您不应该使用carthage copy-frameworks
命令,因为测试包不需要剥离框架,并且不支持运行copy-frameworks
的并发实例(打开并行构建)。
如果您修改了 Cartfile,或者想要更新到每个框架的最新版本(根据您指定的要求),只需再次运行carthage update
命令即可。
如果您只想更新一个或特定的依赖项,请将它们作为空格分隔的列表传递给update
命令。例如
carthage update Box
或者
carthage update Box Result
重写了升级框架的逻辑,目的是提高速度并减少内存使用。目前它是一项可选功能。可以通过将--new-resolver
传递给更新命令来使用它,例如,
carthage update --new-resolver Box
如果您在更新过程中遇到性能问题,请尝试新的解析器
如果您要添加到项目中的框架具有 Cartfile 中明确列出的依赖项,Carthage 将自动为您检索它们。然后,您必须自己将它们从 Carthage/Build 文件夹拖到您的项目中。
如果项目中的嵌入式框架依赖于其他框架,则必须将它们链接到应用程序目标(即使应用程序目标不依赖于该框架并且从不使用它们)。
默认情况下,Carthage 会直接将依赖项的源文件检出到您的项目文件夹中,让您根据自己的选择提交或忽略它们。如果您希望将依赖项作为 Git 子模块使用(也许这样您可以提交并推送其中的更改),您可以使用--use-submodules
标志运行carthage update
或carthage checkout
。
以这种方式运行时,Carthage 将写入存储库的.gitmodules
和.git/config
文件,并在依赖项的版本更改时自动更新子模块。
如果您想在开发过程中处理依赖项,并希望在构建父项目时自动重建它们,您可以添加一个调用 Carthage 的运行脚本构建阶段,如下所示:
/usr/local/bin/carthage build --platform " $PLATFORM_NAME " --project-directory " $SRCROOT "
请注意,在执行此操作之前您应该使用子模块,因为不应直接修改普通的签出。
默认情况下,Carthage 将重建依赖项,无论它是否与以前的解析版本相同。如果可以的话,传递--cache-builds
将导致 carthage 避免重建依赖项。有关 Carthage 如何执行此缓存的详细信息,请参阅有关版本文件的信息。
注意:此时--cache-builds
与--use-submodules
不兼容。使用两者将导致工作副本和对子模块依赖项的提交更改无法正确重建。有关详细信息,请参阅#1785。
可自动完成 Carthage 命令和选项,如 Bash/Zsh/Fish Completion 中所述。
Carthage 仅官方支持动态框架。动态框架可以在任何版本的 OS X 上使用,但只能在iOS 8 或更高版本上使用。此外,从 0.30.0 版本开始,Carthage 支持静态框架。
由于 Carthage 没有集中的包列表,也没有项目规范格式,因此大多数框架应该自动构建。
下面列出了任何框架项目的具体要求。
Carthage 只会构建从.xcodeproj
共享的 Xcode 方案。您可以通过运行carthage build --no-skip-current
,然后检查 Carthage/Build 文件夹来查看所有预期方案是否都已成功构建。
如果运行该命令时未构建重要方案,请打开 Xcode 并确保该方案标记为Shared ,以便 Carthage 可以发现它。
如果在carthage build --no-skip-current
中遇到构建失败,请尝试运行xcodebuild -scheme SCHEME -workspace WORKSPACE build
或xcodebuild -scheme SCHEME -project PROJECT build
(使用实际值)并查看是否出现相同的失败。这应该会产生足够的信息来解决问题。
如果您安装了多个版本的 Apple 开发人员工具(例如 Xcode beta),请使用xcode-select
更改 Carthage 使用的版本。
如果您仍然无法使用 Carthage 构建框架,请提出问题,我们很乐意为您提供帮助!
Carthage 通过搜索存储库上发布的标签并尝试将每个标签名称解释为语义版本来确定可用的框架版本。例如,在标签v1.2
中,语义版本为 1.2.0。
目前不支持不带任何版本号或版本号后带有任何字符(例如1.2-alpha-1
)的标签,并将被忽略。
如果预构建框架附加到项目存储库上的 GitHub 版本或通过二进制项目定义文件附加到,Carthage 可以自动使用预构建框架,而不是从头开始构建。
要为特定标签提供预构建框架,所有受支持平台的二进制文件应一起压缩到一个存档中,并且该存档应附加到与该标签相对应的已发布版本。附件的名称中应包含.framework
(例如ReactiveCocoa.framework.zip
),以向 Carthage 表明它包含二进制文件。存档的目录结构是自由形式的,但是框架应该只在存档中出现一次,因为它们将根据其名称复制到Carthage/Build/<platform>
(例如ReactiveCocoa.framework
)。
要提供预构建的 XCFrameworks,请使用--use-xcframeworks
进行构建,并遵循相同的流程将所有 XCFrameworks 压缩到一个存档中。在附件名称中包含.xcframework
。从版本 0.38.0 开始,Carthage 更喜欢在传递--use-xcframeworks
时下载.xcframework
附件。
您可以使用 carthage 本身执行归档操作:
-carthage build --no-skip-current
-carthage archive YourFrameworkName
或者替代地
carthage build --archive
草稿版本将被自动忽略,即使它们对应于所需的标签。
可以使用 travis-ci 来构建和上传标记的版本。
使用gem install travis
avis 安装 travis CLI
为您的存储库设置 travis-ci(步骤 1 和 2)
根据该模板在存储库的根目录下创建.travis.yml
文件。将FRAMEWORK_NAME
设置为正确的值。
替换 PROJECT_PLACEHOLDER 和 SCHEME_PLACEHOLDER
如果您使用工作区而不是项目,请删除 xcode_project 行并取消注释 xcode_workspace 行。
该项目的格式应为:MyProject.xcodeproj
工作区的格式应为:MyWorkspace.xcworkspace
请随意将xcode_sdk
值更新为另一个 SDK,请注意,在 iphoneos SDK 上进行测试需要您上传代码签名身份
有关更多信息,您可以访问 Objective-C 项目的 travis 文档
language : objective-c
osx_image : xcode7.3
xcode_project : <PROJECT_PLACEHOLDER>
# xcode_workspace: <WORKSPACE_PLACEHOLDER>
xcode_scheme : <SCHEME_PLACEHOLDER>
xcode_sdk : iphonesimulator9.3
env :
global :
- FRAMEWORK_NAME=<THIS_IS_A_PLACEHOLDER_REPLACE_ME>
before_install :
- brew update
- brew outdated carthage || brew upgrade carthage
before_script :
# bootstrap the dependencies for the project
# you can remove if you don't have dependencies
- carthage bootstrap
before_deploy :
- carthage build --no-skip-current
- carthage archive $FRAMEWORK_NAME
运行travis setup releases
,按照此处的文档进行操作
此命令会将您的 GitHub 凭据编码到.travis.yml
文件中,以便 travis 将版本上传到 GitHub.com 当提示上传文件时,输入$FRAMEWORK_NAME.framework.zip
更新部署部分以在标签上运行:
在.travis.yml
中找到:
on :
repo : repo/repo
并添加tags: true
和skip_cleanup: true
:
skip_cleanup : true
on :
repo : repo/repo
tags : true
这将使 travis 知道在推送新标签时创建部署,并防止 travis 清理生成的 zip 文件
如果您将许多动态框架嵌入到您的应用程序中,则其预主启动时间可能会相当慢。 Carthage 能够通过将动态框架构建为静态框架来帮助缓解这种情况。静态框架可以直接链接到您的应用程序中,也可以通过对工作流程进行一些简单的修改来合并到更大的动态框架中,这可以显着减少主启动前的时间。
自版本 0.30.0 以来,Carthage 项目推出了对用 Swift 或 Objective-C 编写的静态链接框架的支持,对此的支持已在 Xcode 9.4 中引入。但请注意,它特别提到了“frameworks” ,因此 Darwin 捆绑了.framework扩展名和内部静态链接的对象档案。 Carthage 目前不支持静态库方案,也没有任何计划在未来引入它们的支持。
工作流程几乎没有区别:
然而:
有关详细信息,请参阅 StaticFrameworks 文档。
请注意,此方法有一些注意事项:
想要宣传您的项目可以与 Carthage 一起使用吗?您可以添加兼容性徽章:
...到你的README
中,只需插入以下 Markdown 即可:
[ ![ Carthage compatible ] ( https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat )] ( https://github.com/Carthage/Carthage )
无法在构建该框架的其他计算机上使用步骤执行来调试预构建的框架。只需carthage bootstrap/build/update --no-use-binaries
就可以解决此问题,但有关更自动化的解决方法,请参阅#924。如果您希望 Apple 解决此问题的根本原因,请欺骗 rdar://23551273。
carthage
命令行工具的大部分功能实际上封装在一个名为 CarthageKit 的框架中。
如果您有兴趣使用 Carthage 作为另一个工具的一部分,或者可能扩展 Carthage 的功能,请查看 CarthageKit 源代码,看看该 API 是否满足您的需求。
CocoaPods 是 Cocoa 的一个长期依赖管理器。那么为什么要建立迦太基呢?
首先,CocoaPods(默认情况下)会自动为您的应用程序和所有依赖项创建和更新 Xcode 工作区。 Carthage 使用xcodebuild
构建框架二进制文件,但将集成它们的责任留给了用户。 CocoaPods 的方法更易于使用,而 Carthage 的方法灵活且无干扰。
CocoaPods 的目标在其 README 中列出如下:
…通过创建更加集中的生态系统来提高第三方开源库的可发现性和参与度。
相比之下,Carthage 是作为一个去中心化的依赖管理器而创建的。没有集中的项目列表,这减少了维护工作并避免了任何中心故障点。然而,项目发现更加困难——用户必须求助于 GitHub 的趋势页面或类似页面。
CocoaPods 项目还必须具有所谓的 podspec 文件,其中包含有关项目的元数据并指定应如何构建它。 Carthage 使用xcodebuild
来构建依赖项,而不是将它们集成到单个工作区中,它没有类似的规范文件,但您的依赖项必须包含它们自己的 Xcode 项目,该项目描述了如何构建其产品。
最终,我们创建了 Carthage,因为我们想要尽可能简单的工具——一个依赖管理器,它可以完成工作,而无需接管 Xcode 的责任,也无需为框架作者创建额外的工作。 CocoaPods 提供了许多 Carthage 永远不会拥有的令人惊叹的功能,但代价是增加了复杂性。
Carthage 是根据 MIT 许可证发布的。
标题背景照片根据 CC BY-NC-SA 2.0 许可发布。理查德·莫特尔的原始照片。