169

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

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

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

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

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

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

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

4

9 回答 9

200

好的,如果您观看 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 视频的人提供有用的参考

如果错误仍然存​​在,请转到产品>清理构建文件夹并再次构建

于 2019-11-01T08:44:13.037 回答
9

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

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

*如果不使用 [About] 会出现下dynamic一个@objc错误

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

XCFramework[关于]强迫你使用它

Apple 建议使用.swiftinterface封闭源代码和Swift Package Manager[About]用于开源

于 2020-08-07T15:52:36.570 回答
1

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

于 2019-11-12T10:50:58.693 回答
0

如果即使在尝试了上述所有步骤之后,它仍然没有解决,那么请尝试查看您的存储库中存在哪些与您的项目没有直接关系的所有预构建文件夹。删除所有这些,删除 pods 文件夹和 podfile.lock 并清理派生数据,然后尝试构建。

它对我有用:D

于 2022-01-11T12:22:48.680 回答
0

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

  1. carthage bootstrap --platform ios
  2. brew bundle
  3. pod repo update
于 2020-04-07T21:14:19.207 回答
0

Distribution (BUILD_LIBRARY_FOR_DISTRIBUTION) -> Yes & Pod update - 这个错误对我来说消失了。

于 2021-11-22T02:24:17.073 回答
0

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

于 2021-01-07T23:24:00.110 回答
-3

我遇到了同样的问题,我只切换了分支。我删除了派生数据+清理构建几次。在我重新启动 Xcode 之前它没有工作

于 2020-06-16T16:22:45.067 回答
-4

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

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

然后尝试carthage update --no-use-binaries

于 2019-11-27T03:44:08.340 回答