文档地址https://github.com/Carthage/Carthage release v0.20.0
2017-3-21
Carthage
Carthage的目的是使用最简单的方式给你的Cocoa应用添加frameworks
基本的工作流程如下:
- 创建一个Cartfile文件,里面包含你将要在你项目中使用的frameworks.
- 运行Carthage,这将获取和编译你列出来的framework.
- 将编译的
.framework
二进制文件拖进你的项目工程。
Carthage编译你的依赖,并提供给你frameworks的二进制文件,但你仍然保留对项目的结构和设置的完全控制。Carthage不会自动的修改你的项目文件或编译设置。
Carthage和我们常用的CocoaPods有什么不同呢?
CocoaPods是一个存在很久的Cocoa依赖管理器了,那我们为什么还要用Carthage呢?
首先,在默认情况下,CocoaPods会为你的项目和依赖自动创建和更新工作区间(Xcode workspace)。Carthage使用xcodebuild
编译framework的二进制文件,但将他们的集成留给用户来操作。因而,对于使用者来说,CocoaPods更为简单,而Carthage更为灵活并且对你的项目更少的入侵。
CocoaPods的目标就如它的文档中所说的:
…为提高第三方开源库的可见性和参与度,创建一个更中心化的生态系统。
相比之下,Carthage是一个分散的依赖管理器,它没有中心项目列表。这就减少了维护工作,并避免任何中心故障点(不需要维护中央服务器嘛,这很好理解)。这样做,随之而来的是一些缺点,就是项目的发现将更困难,用户将依赖于Github的趋势页面或者类似的代码库来寻找项目。
CocoaPods项目还必须具有podspec文件,它包含有关项目的元数据及明确项目的编译方法。Carthage使用xcodebuild
去编译依赖,而不是将依赖集成到一个单一的工作区间,它没有类似的规范文件(例如CocoaPods 的 podspec),但你的依赖必须包括它们自己的Xcode工程文件来描述是如何编译它们的项目。
最终,我们创建了Carthage,因为我们想要最简单的工具 - 一个依赖管理器,完成任务而不取代Xcode的部分功能,并且不为framework作者增加额外的工作。CocoaPods提供的那些神奇的特性Carthage永远不会有。因为我们不会用复杂度去换取那些特性。
安装Carthage
安装Carthage的方法多种多样:
Installer:下载并运行最新版的
Carthage.pkg
文件,然后按屏幕提示操作即可。Homebrew:你可以使用Homebrew并且在你的系统上安装carthage工具。只需要运行
brew update
和brew install carthage
命令就可以了(note:如果你以前安装过二进制版本的Carthage,你应该先删除掉/Library/Frameworks/CarthageKit.framework
).Form source:如果你想运行最新版的开发版(它可能是很不稳定或者不相容的),只需clone存储库的
master
分支,然后运行make install。 要求Xcode 8.2(Swift 3.0.2)
给应用添加frameworks
当你安装了Carthage后,你就可以给你的工程添加frameworks了。需要注意的是Carthage只支持动态frameworks.而动态framework只在IOS8及其以后支持(OS X是任意版本)
开始使用
如果你在OS X下使用
- 创建一个Cartfile文件,将你打算用的frameworks列在里面。
- 运行
carthage update
命令。通过这个命令将获取到的依赖放入Carthage/Checkouts
目录下,并且编译每个framework或者下载一个预编译的framework. - 在应用的targets--“General”设置下,在“Embeddel Binaries”组下,将你想使用的framework从
Carthage/Build
目录下拖拽进去。
另外,你需要去copy调试符号,以便在OS X上调试和生成崩溃报告。
如果你在 IOS, tvOS, watchOS下使用
- 创建一个Cartfile文件,将你打算用的frameworks列在里面。
- 运行
carthage update
命令。通过这个命令将获取到的依赖放入Carthage/Checkouts
目录下,并且编译每个framework或者下载一个预编译的framework. - 在项目的targets--“General”设置下,在“Linked Frameworks and Libraries”组下,将你想使用的framework从
Carthage/Build
目录下拖拽进去。 - 在项目的targets--"Build Phases"设置下,点击“+”并选择"New Run Script Phase",然后创建一个运行脚本,在其中指定shell(例如/bin/sh),将以下内容添加到shell下面的脚本区域:
/usr/local/bin/carthage copy-frameworks
并在“Input Files”下添加要使用的框架的路径,例如:
$(SRCROOT)/Carthage/Build/iOS/Box.framework
$(SRCROOT)/Carthage/Build/iOS/Result.framework
$(SRCROOT)/Carthage/Build/iOS/ ReactiveCocoa.framework
此脚本处理由通用二进制文件触发的App Store提交错误,并确保在归档时复制必需的bitcode-related文件和dSYM。
通过将调试信息复制到已经编译的工程的目录中,只要在断点处停止,Xcode就能够对堆栈跟踪进行符号化。它也使你在调试器中通过第三方代码。
当打包程序提交到App Store或TestFlight时,Xcode还会将这些文件复制到应用程序的.xcarchive
包的dSYMs子目录中。
对于上述的两个平台
在整个过程中,Carthage将会创建一些artifacts。其中最重要的是Cartfile.resolved
文件,它列出了为每个framework编译的实际版本。确保提交你的Cartfile.resolved
,因为任何使用该项目的人将通过该文件来编译相同的framework版本。
Swift二进制框架下载兼容性
Carthage将检查以确保下载的Swift(和混合的Objective-C / Swift)框架是使用本地使用的相同版本的Swift构建的。 如果有版本不匹配,Carthage将继续从源代码构建框架。 如果框架不能从源代码构建,Carthage将失败。
因为Carthage使用xcrun swift --version
的输出来确定本地Swift版本,所以请确保运行Carthage命令,使用你打算使用的Swift工具链。对于大多数情况,不需要额外的去注意整个问题。但是,举例来说,如果你使用Xcode8.x 去编译一个Swift2.3的项目,一种为carthage bootstrap
指定默认swift的方法是使用以下命令:
TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 carthage bootstrap
使用Carthage去运行项目
在你完成上述步骤并将你的改变推送后,项目的其他使用者只需要获取存储库,并且运行carthage bootstrap
来开始使用你添加的frameworks。
向单元测试或框架添加框架
对任何任意target的依赖性使用Carthage非常类似于前面提到的给应用添加frameworks。 主要的区别在于frameworks如何在Xcode中设置和链接。
因为单元测试target在其“General”设置选项卡中缺少“Linked Frameworks and Libraries”部分,所以必须将构建的frameworks拖动到“Link Binaries With Libraries”构建阶段。
在“Build Settings”选项卡下的测试目标中,将@ loader_path/Frameworks
添加到“Runpath Search Paths”(如果尚未存在)。
在极少数情况下,你可能想将每个依赖复制到你构建的产品中(例如,在外部框架中嵌入依赖项,或确保测试包中存在依赖性)。 为此,使用“Framework”目标创建一个新的“Copy Files”构建阶段,然后在那里添加框架引用。
升级框架
如果你已经修改了你的Cartfile,或者你想去更新每个框架到最新版本(在你指定要求在下进行),只需要简单的运行carthage update
命令。
如果你只想更新一个或特定的依赖项,只需要将它们作为以空格分隔的列表传递给update命令。例如
carthage update Box
如果想更新两个
carthage update Box Result
嵌套依赖关系
如果你想添加到项目中的框架的依赖已经出现在Cartfile中了,Carthage将会为你自动检索它们。然后,你必须从Carthage/Build 文件夹将它们自己拖动到你的项目中。
如果项目中的嵌入框架具有对其他框架的依赖性,则必须将它们链接到应用程序目标(即使应用程序目标对该框架没有依赖性,也从不使用它们)。
使用子模块的依赖关系
通常,Carthage将会直接到你项目的目录下检查依赖的源文件,让你在选择时提交或忽略它们。如果你想有依赖项作为Git子模块(或许这样你可以提交和推送改变),你可以运行carthage update
或者带有--use-submodules
标志的carthage checkout
。
当你运行上述命令后,Carthage将.gitmodules
和.git/config
文件写入你的存储库,并在依赖项的版本更改时自动更新子模块。
自动重建依赖关系
如果要在开发期间处理依赖项,并希望在构建你的父项目时自动重新构建它们,则可以添加调用Carthage的 Run Script构建阶段,如下所示:
/usr/local/bin/carthage build --platform "$PLATFORM_NAME" --project-directory "$SRCROOT"
需要注意的是,在执行此操作之前应该使用子模块,因为不应直接修改简单的检出。
缓存构建
默认地,Carthage将重建一个依赖关系,无论它与以前是否是一样的解析版本。通过--cache-bulids
将会使得carthage去避免重建依赖。有关如何执行此缓存的详细信息,请参阅有关版本文件的信息。
注意:此时--cache-builds
与--use-submodules
不兼容。 使用这两者将导致工作副本和对子模块依赖关系的更改提交不能正确重建。
使你的framework支持Carthage
Carthage 正式的只支持动态框架。动态框架在OS X的任何版本都可以使用,但IOS 只能是8或者8+。
因为Carthage没有集中的包列表,没有项目规范格式,大多数框架应该自动构建。
任何框架项目的具体要求如下。
分享你的Xcode schemes(方案)
Carthage将只构建从.xcodeproj共享的Xcode方案。你可以通过运行carthage build --no-skip-current
,然后检查 Carthage/Build 文件夹来查看是否成功创建了所有计划的方案。
当你运行那个命令的时候如果有一个重要的方案没有被编译,打开Xcdoe并确保该方案标记为“共享”,以便Carthage可以发现它。
解决build失败
如果你在运行Carthage build --no-skip-current
中遇到构建失败,请尝试运行xcodebuild -scheme SCHEME -workspace WORKSPACE build
或xcodebuild -scheme SCHEME -project PROJECT build
(使用实际值),并查看是否发生相同的故障。 这应该能产生足够的信息来解决问题。
如果你安装了多个版本的Apple开发者工具(例如Xcode beta版),请使用xcode-select
更改Carthage使用的版本。
标签稳定版本(Tag stable releases)
Carthage通过搜索在存储库上发布的标记并尝试将每个标记名解释为语义版本来确定您的框架的哪些版本可用。 例如,在标签v1.2中,语义版本是1.2.0。
没有任何版本号的标签,或版本号后面的任何字符(例如,1.2-alpha-1)目前不被支持,将被忽略。
将预编译的框架归档到一个zip文件中
如果它们附加到项目存储库上的GitHub发行版或通过二进制项目定义文件,Carthage可以自动使用预构建框架,而不是从头开始构建。
要为特定标记提供预构建框架,所有被支持的平台的二进制文件应该一起压缩到一个归档中,并且该归档应附加到与该标记相对应的已发布版本。 附件应在其名称中包括.framework
(例如ReactiveCocoa.framework.zip
),以向Carthage表明其包含二进制文件。
你可以像下面这样通过carthage archive
命令执行归档操作:
carthage bulid --no-skip-current
carthage archive YourFrameworkName
将自动忽略版本草稿,即便它们对应于所需的标签。
使用travis-ci上传你标记的预构建框架
通过使用travis-ci去编译和上传你标记的发行版是可行的。
通过
gem install travis
命令安装travis CLI为您的存储库设置travis-ci(步骤1和2)
-
根据该模板在存储库的根目录中,创建
.tarvis.yml
文件,将“FRAMEWORK_NAME”设置为正确的值。替换 PROJECT_PLACEHOLDER 和 SCHEME_PLACEHOLDER
如果使用工作区而不是项目,请删除xcode_project行,并取消注释xcode_workspace行。
项目的格式应该是:MyProject.xcodeproj
工作区间的格式应该是:MyWorkspace.xcworkspace
随时更新
xcode_sdk
值到另一个SDK,请注意,在iphoneos SDK上的测试将需要你上传代码签名身份。详情见travis docs for objective-c projects
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
4. 运行``travis setup releases``
此命令会将你的github凭据编码到.travis.yml文件中,以便让travis将发行版上传到github.com当提示您上传文件时,输入$ FRAMEWORK_NAME.framework.zip
5. 更新部署部分通过带标签的运行如下命令:
在 ``.travis.yml``中查找
on:
repo: repo/repo
添加``tags:true``和``skip_cleanup:true``:
skip_cleanup: true
on:
repo: repo/repo
tags: true
这将让travis知道在推送新标签时创建部署,并阻止travis清理生成的zip文件