使用 Carthage 嵌套我自己的框架

Nesting My Own Frameworks with Carthage

我在尝试实现两个框架和一个应用程序之间的以下依赖设置时遇到问题,这些都是我开发的:

  1. Util 包含一堆低级实用程序和 Foundation 类型的扩展,例如 StringDate,等等

  2. UI 包含一堆自定义 UIViewUIViewController subclasses, class UIColorUIImage 等的扩展..

应用程序和每个框架在 GitHub 上都有自己的存储库。


UI框架设置为依赖Util框架,使用Carthage:

  1. 项目的 Cartfile 包含对 Util 存储库的引用:

    github "MyOrganization/Util.git"

  2. Util 在"Linked Frameworks and Libraries"中列出,但未嵌入(因为UI是一个框架项目,不是应用程序)。

  3. 框架搜索路径构建设置包含$(PROJECT_DIR)/Carthage/Build/iOS以及$(inherited)

  4. .gitignore 文件配置为忽略整个 Carthage 目录(不仅仅是 /Build

  5. 使用git子模块,我也不打算(我已经够头疼了)。


如果我克隆 UI 框架和 运行 carthage update,Carthage fetches/builds Util,我可以手动嵌入它来构建 UI 框架。

到目前为止一切顺利。


但是如果我克隆 App 框架和 运行 carthage update,Carthage 获取 UI 回购协议,但无法构建:

  1. 目录 App/Carthage/Checkouts 包含 UI 项目的签出副本,正如预期的那样。但是,嵌套框架没有进一步的 Carthage 目录(我假设它应该是 App/Carthage/Checkouts/UI/Carhage/Checkout/Util)。

  2. 导航到 App/Carthage/Checkouts/UI 使用 Xcode 打开那里的工作区并构建它也失败了,显然。对 Util.framework 的引用已损坏。

根据我的阅读,迦太基应该获取递归依赖;我在这里错过了什么?

我尝试将两个框架 URL 添加到 App Cartfile,但是 xcode 仍然无法构建 UI 框架。

carthage 输出指向的日志的底部说:

/Users/me/Projects/App/code/App/Carthage/Checkouts/UI/code/UI/UI/MyClass.swift:10:8: error: no such module 'Util'

import Util
       ^

** ARCHIVE FAILED **


The following build commands failed:
    CompileSwift normal arm64
    CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
(2 failures)

更新

我在 GitHub 上整理了一个 minimal reproducible example。应用程序和框架构成此依赖关系图:

A -> B -> C
// (and also A -> C, but that's not relevant now)

(C 是应用程序,B 和 C 是框架)。

当 运行ning carthage updateA 项目上时,它获取两个框架 repos,检查两个,开始构建 B 首先失败,就像上面一样(import 指令)。

B 的签出副本具有正确的 Cartfile 以及所有源文件,但没有嵌套的 Carthage/ 目录,更不用说必要的副本了其中的 C

我想我需要以某种方式使构建过程引用 A/Carthage/Builds/C.framework 而不是 A/Carthage/Checkouts/B/Carthage/Builds/C.framework,但不知道如何设置 B 项目才能解决...

TL, DR: 我的 UI 框架在存储库的根目录下没有它的 Cartfile,所以迦太基无法 "see" 它在构建(即使文件本身已被提取,并存储在更深的几个目录中)。


作为 Github 用户 Sho Ikeda(迦太基存储库的 @ikesyo) kindly pointed out on this thread/issue,我的 中级 框架(UI,在本例中)没有它的 Cartfile 在根目录。相反,它更像这样:

.git
.gitignore
docs/
code/
    UI.workspace
    UI/
        UI.xcodeproj
        Cartfile
        Carthage/
            Build/
            Checkouts/

等等,需要的时候更像这样:

.git
.gitignore
Cartfile
docs/
code/
    UI.workspace
    UI/
        UI.xcodeproj

Carthage/
    Build/
    Checkouts/

我假设 Cartfile 必须与 Xcode 项目处于同一级别;事实并非如此。将 Cartfile 移动到根目录后,将我的框架项目的构建设置 "Framework Search Paths" 更改为:

$(PROJECT_DIR)/Carthage/Build/iOS

至:

$(PROJECT_DIR)/../../Carthage/Build/iOS

...为了解释移动,以便在从其工作区构建 UI.framework 时针对 Util 的链接不会失败。

最后,我 运行 carthage update 形成我的 App 目录,链接框架等,如 Carthage GitHub 页面中所述,它就像一个魅力。我可以从应用程序的源代码(最外层)成功实例化在我的 Util(最内层)框架中定义的 类。