模块映射文件中是否需要 "link framework" 行?

Are "link framework" lines necessary in a modulemap file?

一些框架文件带有包含 "link framework" 行的 module.modulemap。例如,这里是Intercom's module.modulemap file的当前内容:

framework module Intercom {
  umbrella header "Intercom.h"

  [...]

  link framework "Foundation"
  link framework "UIKit"
  link framework "Accelerate"
  [...]
}

我想知道为什么需要 link framework 行,所以我尝试使用 Xcode 10.2 为框架目标创建一个新项目,但无论我做什么,它似乎 module.modulemap 文件将保持不变(这是可以理解的,似乎这个文件是要手动修改的)。

我想知道的是,为什么这首先是必要的? blame info + corresponding release notes 似乎表明添加上述行是为了解决 动态框架和重复符号 的问题,但仅此而已。

有两种方法可以使 Objective-C 框架在 swift 项目中可用:

1)让Xcode自动创建module.modulemap文件,这是启动新框架项目时的默认选项:

因此,当您编译项目时,将使用默认配置生成此文件:

framework module MODULE_NAME {
  umbrella header "MODULE_NAME-umbrella.h"

  export *
  module * { export * }
}

通常对于大多数项目来说已经足够了。

2)手动生成文件,就是你的项目案例

根据CLANG's modulemap documentation:

A link-declaration specifies a library or framework against which a program should be linked if the enclosing module is imported in any translation unit in that program.

Link 模块映射中的声明旨在提示工具链什么是包含模块代码的实际二进制文件。如果没有这个明确的定义,在主项目上导入框架可能会由于需要那些源框架而导致错误,主要是 .

因此,如果您有一个具有动态框架依赖项的 swift 项目,并且其中之一具有与您的示例框架相同的依赖项列表,如果您从 .modulemap 中删除显式声明文件,您可能会看到 duplicate symbols 错误。

更多信息,推荐this Apple thread回复。