使用 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 stability
和 Library 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 binary
或 Compiled 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 编译器导入”