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

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

这将 fine 导入到 Xcode 11.0和11.1中,从来没有出现过任何问题

今天,在苹果发布 Xcode 11.2之后,我升级了一下,然后出现了一个错误:

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

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

我的印象是,既然我们已经具备了模块的稳定性,框架就不需要在每个新的 Xcode 版本中不断地重新编译,但显然情况并非如此。

如果有人能解释一下这里发生了什么,我将不胜感激。Xcode 11.2有 bug 吗?或者当我最初使用 Xcode 11.0编译时,我是否需要告诉它我需要模块的稳定性?

142312 次浏览

好吧,原来如果你看了 WWDC 的视频,他们会解释说: Https://developer.apple.com/videos/play/wwdc2019/416/

你需要在框架的构建设置中将 生成设置 > 生成选项 > 生成分发库选项设置为 是的,否则快速编译器不会生成必要的 .swiftinterface文件,而这些文件是未来编译器能够加载旧库的关键。

这将以如下方式在 project.pbxproj 文件中结束:

BUILD_LIBRARY_FOR_DISTRIBUTION = YES;

在设置了这个标志之后,我用 Xcode 11.0编译的一个框架能够被 Xcode 11.2(swift 5.1.2)使用,而且一切似乎都正常工作。

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

如果错误仍然存在,再次转到 产品 > 清除生成文件夹建造

我在导入第三方库时也犯了同样的错误。 我在 Xcode 使用工具链修复了这个问题,并在2019年9月19日发布了这个版本。 在那之后,我不得不重新导入我的库,它起作用了。

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

基本上,迦太基给你一个类似的 传统的 RxSwift.Framework 样式包

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

这消除了我的编译器错误。

  1. carthage bootstrap --platform ios
  2. brew bundle
  3. pod repo update

我遇到了同样的问题,我只是换了一个分支。我删除了派生数据 + 干净的建立了几次。直到我重新启动 Xcode 它才起作用

封闭源模块稳定性与库演化支持

[ 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 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

* 如果使用没有 @objc< sup > [ About ] dynamic,可能会出现下一个错误

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

XCFramework< sup > [ About ] 强制您使用它

Apple 推荐使用 .swiftinterface作为封闭源代码,使用 Swift Package Manager< sup > [ About ] 作为开放源代码

在从 Xcode 12.3转回到 Xcode 11.3.1之后,我在回购时经历了这种情况。我已经简要地更新了我的命令行工具,并且需要将它们恢复到早期版本,以获得依赖构建。

分发(BUILD _ LIBRARY _ FOR _ DISTRIBUTION)-> Yes & Pod update-对我来说错误消失了。

如果甚至在尝试了上面提到的所有步骤之后,它仍然没有解决,那么尝试查看所有的预构建文件夹在您的回购中都存在哪些与您的项目没有直接关系的文件夹。删除它们,删除 pods 文件夹和 podfile.lock,清除派生数据,然后尝试构建。

这对我很有效: D

我设法解决这个问题的另一种方法是重复检查您正在使用的模块,看看是否有更新。我使用 ViewControllerPresentationSpy 来测试项目中的警报控制器。我做了一个 pod 重新整合,然后 pod 安装,更新版本从5.1到6.0,因为该模块的作者已经发布了更新。我删除了项目中前一个模块的文件夹。然后,对于新版本,我能够拖放项目,只是在我的所有测试后,清理构建和项目导航器,并将其添加到复制文件部分的 VC 演示间谍项目。

长话短说,仔细检查您的模块是从哪里获得的,并检查更新,然后再次将其添加到您的 Xcode 项目中。

有时可以帮助在苹果 M1上运行应用程序

Change building settings by adding this for debug

也在终端尝试:

arch -x86_64 pod install

当我从 Xcode 13.4转移到 Xcode 14.1时,我遇到了类似的问题。解决方案是在 Xcode 设置合适的编译器——参数设置——命令行工具