使用 Swift 5.1 编译的模块不能被 Swift 5.1.2 编译器导入

Posted

技术标签:

【中文标题】使用 Swift 5.1 编译的模块不能被 Swift 5.1.2 编译器导入【英文标题】:Module compiled with Swift 5.1 cannot be imported by the Swift 5.1.2 compiler 【发布时间】:2020-02-27 11:37:29 【问题描述】:

我有一个框架(在本例中是 RxSwift),我使用 Xcode 11.0 将其编译到传统的 RxSwift.framework 样式包中

这很好导入到 Xcode 11.0 和 11.1 中从来没有任何问题

今天,Apple 发布 Xcode 11.2 后,我升级了,但出现错误:

我习惯了 swift 编译器不匹配,我知道我可以使用 Xcode 11.2 重新编译 RxSwift 并继续,但 Swift 5.1 的主要特性是模块稳定性

我的印象是,既然我们有了模块稳定性,框架就不需要随着每个新的 Xcode 版本而不断重新编译,但显然情况并非如此。

如果有人能解释这里发生了什么,我将不胜感激。 Xcode 11.2 是否存在错误?还是我最初使用 Xcode 11.0 编译时需要以某种方式告诉它我想要模块稳定性?

【问题讨论】:

相关:Module compiled with Swift 5.0.1 cannot be imported by the Swift 5.1 compiler 对我来说使用旧版 swift 的工具链有效:***.com/a/43142147/5846135 【参考方案1】:

好的,如果您观看 WWDC 视频,他们会解释: https://developer.apple.com/videos/play/wwdc2019/416/

您需要在框架的构建设置中将 Build Settings > Build Options > Build Libraries for Distribution 选项设置为 Yes,否则 swift 编译器不会生成必要的 .swiftinterface 文件,这些文件是未来编译器能够加载您的旧库的关键。

这最终在您的 project.pbxproj 文件中为:

BUILD_LIBRARY_FOR_DISTRIBUTION = YES;

设置此标志后,我使用 Xcode 11.0 (swift 5.1) 编译的框架能够被 Xcode 11.2 (swift 5.1.2) 使用,并且一切似乎都正常工作。

希望这个问题/答案能为所有没有看过所有 WWDC 视频的人提供有用的参考

如果错误仍然存​​在,请转到 Product > Clean Build Folder 并再次Build

【讨论】:

这对我没有帮助。我将其设置为“是”,但我仍然收到错误消息。有什么想法吗? 我正在使用 Carthage 和 10 个框架...ish。 carthage 是否足够聪明,可以从 my .pbxproj 文件中获取它,或者正如上面@MihaiFratu 所说,是否所有第三方框架开发人员都需要在他们的框架项目? @davidOhara 在我的情况下,它与 Xcode 11.2 中的这个已知问题有关:如果模块是使用 BUILD_LIBRARIES_FOR_DISTRIBUTION 构建的并且包含与模块本身同名的公共类型,客户端将无法导入模块。 (19481048) (FB5863238) 在 Xcode 11.2 发行说明中:developer.apple.com/documentation/xcode_release_notes/… @davidOhara 遗憾的是我还没有找到解决方法。对我们来说,重命名这个类也是不可能的,因为它是我们框架的主类,会破坏我们客户的代码。如果我使用 Xcode 11.2 构建框架,那么它会在 Xcode 11.2 上编译,但不会在 11.1 或更早版本上编译。今天的 Xcode 11.2.1 GM 版本没有解决这个问题。这是 swift issue tracker 上的票,如果您想密切关注它:bugs.swift.org/browse/SR-11704 它还附有一个雷达。 没有帮助 仍然出现同样的错误。即使我这样做,也很干净,但没有运气。! BUILD_LIBRARY_FOR_DISTRIBUTION = 是【参考方案2】:

我在导入第 3 方库时遇到了同样的错误。 我使用 Xcode 中的工具链修复了它,并从这里https://swift.org/download/#releases 于 2019 年 9 月 19 日发布。 之后,我不得不重新导入我的库并且它起作用了。

【讨论】:

我在框架上遇到问题 使用 Swift 5.1.2 编译的模块无法被 Swift 5.2.2 导入,我们该如何解决这个问题?【参考方案3】:

您可以使用 Carthage 添加 RxSwift 框架。

基本上,Carthage 为您提供了一个类似的传统 RxSwift.framework 样式包

那就试试carthage update --no-use-binaries

【讨论】:

投反对票,因为使用 carthage 您只是在新编译器上重建库。问题是关于加载由以前的编译器构建的二进制库【参考方案4】:

这使我的编译器错误消失了。

    carthage bootstrap --platform ios brew bundle pod repo update

【讨论】:

brew bundle?它有什么作用? 投反对票,因为使用 carthage 您正在新编译器上重建库。问题是关于加载由以前的编译器构建的二进制库 我运行了上述命令,但仍然遇到类似的构建错误:~"由于错误而跳过安装 RxSwift.framework 二进制文件:不兼容的 Swift 版本 - 框架是用 5.2.2 (swiftlang -1103.0.32.6 clang-1103.0.32.51) 本地版本为 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)。"【参考方案5】:

我遇到了同样的问题,我只切换了分支。我删除了派生数据+清理构建几次。直到我重新启动 Xcode 才起作用

【讨论】:

【参考方案6】:

对闭源的模块稳定性和库演化支持

[ABI]

Swift v5.0引入稳定的ABI

Swift v5.1 发货 Module stabilityLibrary evolution support 适用于闭源(二进制)框架(库)(框架与消费者分开构建)

检查 Swift 版本:

Swift Language Version(SWIFT_VERSION)

要启用它,您应该使用 v11 的 Xcode:

为分发构建库 (BUILD_LIBRARY_FOR_DISTRIBUTION)

Select framework target -> Build Settings -> Build Libraries for Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> Yes

swiftc 标志:

-enable-library-evolution
-emit-module-interface

此设置生成.swiftinterface

Swift 模块接口 (.swiftinterface)

Swift Module 使用与 Objective-C 模块相同的方法 - precompiled binaryCompiled Module

Swift Module Interfaces 是模块公共 API 的文本表示。它是 Swift 对 Objective-C 的标头 .h 文件的替代品。

//previously
consumer(app) -> import Module -> producer(framework) .swiftmodule

//using .swiftinterface
consumer(app) -> import Module -> .swiftinterface -> producer(framework) .swiftmodule

尽管.swiftmodule 是可以更改的,你可以在哪里获得

Module compiled with _ cannot be imported by the _ compiler

.swiftinterface 是稳定的,当有变化时不需要更新(例如 Swift 版本)

没有假设

它位于下一个文件夹中

<framework_name>.framework/Modules/<framework_name>.swiftmodule

看起来像:

// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
// swift-module-flags: -target x86_64-apple-ios12.2-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -Onone -module-name UtilsSwiftFramework
import Foundation
import Swift
@_exported import UtilsSwiftFramework
@_inheritsConvenienceInitializers @objc public class GFISClassA : ObjectiveC.NSObject 
  @objc public static var shared: UtilsSwiftFramework.GFISClassA
  @objc public func GFISprintHelloWorld()
  @objc public func GFISprintHelloWorld(arg1: Swift.String, arg2: Swift.String)
  @objc deinit
  @objc override dynamic public init()

如您所见,它还包含:

swift-interface-format-version
swift-compiler-version
swift-module-flags

*如果你使用dynamic而不使用@objc[About],你会得到下一个错误

Marking non-'@objc' Swift declaration 'dynamic' in library evolution mode is not supported

XCFramework[About] 强制你使用它

Apple 建议将 .swiftinterface 用于闭源,Swift Package Manager[About] 用于开源

【讨论】:

【参考方案7】:

从 Xcode 12.3 移回 Xcode 11.3.1 后,我在 repo 上遇到了这种情况。我已经快速更新了我的命令行工具,需要将它们恢复到早期版本才能构建我的依赖关系。

【讨论】:

【参考方案8】:

通过从项目的根文件夹运行命令修复了错误:

carthage update --use-xcframeworks --platform iOS --cache-builds

【讨论】:

【参考方案9】:

Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> 是 & Pod 更新 - 错误对我来说消失了。

【讨论】:

以上是关于使用 Swift 5.1 编译的模块不能被 Swift 5.1.2 编译器导入的主要内容,如果未能解决你的问题,请参考以下文章

安装 Xcode10.2.1 但仍然收到错误“使用 Swift 5.0.1 编译的模块无法由 Swift 5.1 编译器导入”

使用 Swift 4.0.3 编译的模块不能被 Swift 4.2.1 编译器导入

Swift 4 中的 AlamofireImage 问题

Swift编译慢?请看这里,全套开源

Swift 5.1 发布进程

通过Visual C ++编译器识别ARM软件中断(SWI)函数