Swift软件包和`#if canImport(…)`。它是如何工作的?

问题描述 投票:0回答:1

不好意思的标题。

[我正在尝试构建一个软件包以帮助我使用第三方云存储API(例如Firebase Storage),添加Combine支持等。此软件包对CloudKit的作用相同。一切都可以正常编译,但是当我将包模块导入我的一个单独项目中时,该模块显然缺少一些公共符号...

具体地说,是包裹在#if canImport(FirebaseStorage)条件中的那些。由于Firebase尚不支持SwiftPM,因此该包的这一部分在包项目本身中的行为与预期相同。它只是跳过了整个编译过程。我认为can导入此模块的客户端项目可以对其进行编译。

另外:我正在尝试做的事情看起来像可选的依赖项。我不需要导入Firebase即可使用此程序包的其他功能。我考虑过将程序包拆分为单独的子程序包,每个子程序包都取决于要使用的特定第三方库。无论如何,我可能会这样做。但是问题仍然是Firebase尚不支持SwiftPM(although I hear they're close)。

我的问题似乎类似于this one。我的客户项目似乎没有看到条件符号,尽管它can导入FirebaseFirebaseStorage很好!我的意思是,生成的模块头将完全丢失它们,从而阻止了我的客户端项目在使用它们时进行编译。

在我看来,编译条件永远不会离开程序包自己的依赖目标范围。是这样吗还是我缺少明显的东西?我一直认为Swift软件包只是将Swift源文件导入并编译到命名模块中,但现在我认为并非如此。

是否有一种方法可以将代码构建到仅在客户端可以导入尚不支持SwiftPM的第三方模块时才编译的Swift软件包中?还是条件编译不能那样工作?

swift conditional-compilation swift-package-manager
1个回答
0
投票
有人

请如果我错了,请纠正我,但看起来我只是误解了编译顺序。

当我导入打包的模块(我们称其为CloudStorage)时,即声明对该模块的依赖关系。在我的客户项目(例如FinanceApp)可以编译并混合其父项依赖项(例如FirebaseCloudKit等)之前,CloudStorage尝试在没有Firebase的情况下进行编译。由于对“ Firebase”一无所知,仅是在其依赖项列表中找不到该字符串,因此canImport的计算结果为false,并跳过所有这些符号。

一旦编译出混乱,只有

then

Swift会查看FinanceApp进行编译。我可能会尝试使用在Firebase中看到的以CloudStorage为中心的符号,但是由于该模块已经编译了[[sans这些符号,因此编译器不知道在哪里寻找它们,并且不知道。如果我是对的,这是一个非常烦人的事实,可能对某人有用(甚至可能是将来的我?)。>>如果没有...帮助!
© www.soinside.com 2019 - 2024. All rights reserved.