在框架模块中包含非模块化标头

Posted

技术标签:

【中文标题】在框架模块中包含非模块化标头【英文标题】:Include of non-modular header inside framework module 【发布时间】:2015-03-02 19:29:03 【问题描述】:

我正在使用 Xcode 6,

1) 首先我正在创建一个动态库 (CoreLibrary)。该库包含 RequestPoster.h 文件。

2)然后我创建了一个 Cocoa Touch Framework 并添加了这个动态库(CoreLibrary)。

3) 然后这个框架被添加到我的项目中,它在 RequestPoster.h 文件 (CoreLibrary) 中给出错误。

错误: 类:

ifaddrs.h、arpa/inet.h、sys/types.h>

在项目中找不到这些文件。

【问题讨论】:

【参考方案1】:

尝试进入“目标”下的构建设置并将“允许框架模块中的非模块化包含”设置为“是”。

真正的答案是库所有者需要更改导入的位置。这些文件 ifaddrs.h、arpa/inet.h、sys/types.h 被导入到框架中的 .h 文件中,而 Xcode 不喜欢这些文件。库维护者应将它们移动到 .m 文件中。例如,参见 GitHub 上的这个问题,AFNetworking 修复了同样的问题:https://github.com/AFNetworking/AFNetworking/issues/2205

【讨论】:

如果出错的标头使用了导入标头中的类型,有什么建议?例如,如果模块中的 header module.h 声明了一个采用ifaddrs 类型参数的函数,则它们必须导入 ifaddrs.h。 但是如果它们是系统包含的,比如/usr/include/libproc.h 您能否解释一下更改的影响:允许框架模块中的非模块化包含 我认为最好的答案可能是将其设为模块化标题,而不是基本上消除此错误。我可以很容易地想象 Apple 删除了允许在模块中使用非模块化标头的选项。【参考方案2】:

您可以在受影响目标的构建设置中将允许框架模块中的非模块化包含设置为“是”。这是您需要编辑的构建设置:

注意:您应该使用此功能来发现潜在的错误,我发现这经常是由具有某种依赖关系的文件中的尖括号全局包含重复引起的,即:

#import <Foo/Bar.h> // referred to in two or more dependent files

如果将 Allow Non-modular include in Frame Modules 设置为 YES 会导致一组“X is an ambiguous reference”错误或类似的错误,您应该能够追踪有问题的重复项并消除它们。清理代码后,将Allow Non-modular includes in Frame Modules 设置回NO

【讨论】:

好的,是尖括号导致了问题!我在 CocoaPods 导入时遇到了这个问题,并通过将导入更改为使用引号而不是尖括号来修复它。 糟糕,没有。清理项目后发现它坏了:-/ 我找不到任何“模糊参考”警告。将其设置为 YES 有什么缺点?【参考方案3】:

实际上更简单的解决方法是将#import 语句移动到.m 文件的顶部(而不是将其放在.h 头文件中)。这样它就不会抱怨它包含一个非模块化的头文件。我遇到了这个问题,其中Allow non-module includes 设置为YES NOT 对我有用,所以通过将它移动到实现文件,它停止了抱怨。这实际上是导入和包含头文件的首选方式。完成此操作后,将其设置回 NO 应该可以工作。

理想情况下,我们应该尝试将Allow non-module includes 设置为NO。在大多数情况下,将其设置为YES 意味着您做错了什么。该设置转换为“允许在磁盘上导入不属于模块的随机头文件”。这适用于实践中的极少数用例,因此此设置应始终为NO(即默认值)。

【讨论】:

【参考方案4】:

“在框架模块中包含非模块化标头”

当您收到此错误时,在某些情况下,解决方案可能是在文件检查器“目标成员资格”中简单地将您尝试导入的文件标记为“公共”。默认为“项目”,这样设置时可能会导致此错误。例如,我在尝试将 Google Analytic 的标头导入框架时就是这种情况。

【讨论】:

这个答案对我的类似问题帮助很大。我不知道框架头文件可以添加到目标中。在应用程序项目中,标头绝不是目标的一部分。 这里一样,解决了我的问题!【参考方案5】:

我遇到了同样的问题,上面没有任何帮助。所以我希望我的回答对某人有所帮助。就我而言,问题出在 ALWAYS_SEARCH_USER_PATHS 设置中。当它设置为 NO 项目构建和工作正常。但就其中一个 pod 要求将其设置为 YES 而言,我收到了一个错误

在框架模块中包含非模块化标头

在喝了几杯咖啡和一整天的研究之后,我发现根据Xcode 7.1 Beta 2 release notes的已知问题:

• 如果您收到一条错误消息,指出“Include of non-modular header inside 框架模块”用于先前编译的框架,请确保 “始终搜索用户路径”构建设置设置为“否”。这 仅出于遗留原因默认为“是”。 (22784786)

虽然我使用的是 XCode 7.3,但似乎这个错误尚未修复。

【讨论】:

【参考方案6】:

这对我来说是个烦人的问题。没有任何建议似乎对我的特殊情况有所帮助,因为我需要在我的个人文件头文件中包含“非模块化”头文件。我使用的解决方法是将导入调用粘贴在前缀头文件中。

【讨论】:

【参考方案7】:

确保头文件作为框架的公共头文件的一部分公开可用。

转到框架 -> 目标 -> 构建阶段并拖动以将相关头文件从项目移动到公共。希望对您有所帮助!

【讨论】:

这帮助我将 Objective C 代码包含到 Swift 框架中,谢谢! 您还可以使用 XCode 主屏幕右侧的 File Inspector 窗口,在文件中将 Target Membership 从 Project 更改为 Public。 如果将库导入到 swift/objc 的混合中,需要确保桥接头也是公共的。我犯的错误!【参考方案8】:

我遇到了同样的问题,只需将头文件公开即可解决。

如果您在项目中处理多个模块。然后你的头文件需要公开才能在项目的其他部分使用。您需要的是选择该头文件,并在项目实用程序视图中。将文件从 Project/Private 更改为 Public。见下图:

【讨论】:

当您复制现有的公共标头时,尤其会发生这种情况,复制的标头成员资格更改为“项目” 不,复制不是强制性的。它可能由于不同的情况而发生,例如,如果您将某个项目作为库完全导入到您的项目中,然后您尝试修改私有类。您知道头文件并编写它,但访问权限并非对所有项目都是公开的。【参考方案9】:

同样的问题让人抓狂。最后,我发现把'import xxx.h'放在实现中而不是接口可以解决问题。如果你使用Cocoapods来管理你的项目。你可以添加

s.user_target_xcconfig = 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'

在您的“xxx.podspec”文件中。

【讨论】:

【参考方案10】:

如果 CocoaPods 目标需要此功能,请在 Podfile 中添加此行:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      target.build_settings(config.name)['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
    end
  end
end

【讨论】:

【参考方案11】:

如果您在构建动态框架时在伞形标头中看到此错误,请确保将文件导入为:

#import "MyFile.h"

并且不是#import &lt;MyFramework/MyFile.h&gt;

【讨论】:

这有助于构建框架本身,但后来我在单元测试中遇到了同样的错误,因为自动生成的MyFramework-Swift.h 包含#import &lt;MyFramework/MyFramework.h&gt;。我通过重命名公共头目录 ***.com/a/67869384/10380092 解决了这个问题【参考方案12】:

我能够通过使用 Git clean 清除许多此类错误。这是命令:git clean -dffx &amp;&amp; git reset --hard

【讨论】:

这拯救了我的一天!【参考方案13】:

如果您正在开发自己的框架:

为什么会这样?

如果您在 module.modulemap 中提到的任何公共头文件具有在 modulemap 中 提及的导入语句,这会给您错误。由于它尝试导入一些未声明为模块化的标头(在 module.modulemap 中),因此它破坏了框架的模块化。

我该如何解决?

只需将导致错误的标头包含在您的 module.modulemap 中并重新构建!

为什么不直接将 allow non-modular 设置为 YES?

因为它在这里不是真正的解决方案,所以你告诉你的项目“这个框架应该是模块化的,但事实并非如此。以某种方式使用它,我不在乎。”这并不能解决您的库的模块化问题。

有关更多信息,请查看此archived blog post 或参考clang docs。

【讨论】:

你是如何使用可可项目框架设置 module.modulemap 的,我试图让我的库能够处理纯 Swift 项目,但是因为库的一个依赖项是模块。 modulemap 不工作,cocoapod 正在自动生成 modulemap,但它似乎不工作,你遇到过类似的事情吗?【参考方案14】:

在检查了上述解决方案后,我最终将 Umbrella Header 移动到了 Headers 列表的底部,这在 Xcode 9.3 中有效。

【讨论】:

【参考方案15】:

我解决了从框架中删除 Modules 文件夹的问题。

使用查找器浏览到应用程序项目中存在的框架位置

进入Test.framework 文件夹(在上述情况下为CoreLibrary.framework)并删除Modules 文件夹。

清理并重新构建应用程序,它将解决问题。

【讨论】:

【参考方案16】:

就我而言,我忘记在 .podspecs 文件的“s.source_files”部分添加 .h 和 .m 文件。

添加后就可以正常使用了。

【讨论】:

【参考方案17】:

我也遇到了这个问题,最初认为这是一个 CocoaPods 问题,但这是应用程序构建设置中的一个问题,其中有人(可能是我)在标题搜索路径中设置了 $PODS_ROOT 并将其设置为recursive 搜索。这允许它找到在构建应用程序时不打算使用的标头。一旦我将其设置为使用non-recursive,一切都很好。使用recursive 搜索是一个可怕的黑客尝试找到正确的标题。经验教训。

【讨论】:

我可以确认这也是我的问题。 我在 PersonalizedAdConsent 中遇到了这个问题,这解决了它。谢谢! 几乎也是这个。我的测试目标中有这个问题,奇怪的是,标题搜索路径包括 $(SRCROOT)/Pods,递归。导致问题的原因。【参考方案18】:

Allow Non-modular Includes in Framework Modules 仅适用于 objc 代码。不能迅速工作。

经过一段时间的研究,发现swift可以将warning参数传递给clang,所以设置OTHER_SWIFT_FLAGS-Xcc -Wno-error=non-modular-include-in-framework-module抑制swift导入错误。

只针对有同样问题的人

【讨论】:

非常感谢,这帮助我弄清楚了。我有一个导致这种情况的供应商框架,我没有机会获得它的更新版本。 -Wno-error=non-modular-include-in-framework-module 帮助修复了它。【参考方案19】:

尝试@import FrameworkName 而不是#import "FrameworkName.h"

【讨论】:

【参考方案20】:

我遇到了类似的问题!运行我的应用程序目标时,一切正常,但是当更改为测试目标并尝试运行测试时,出现“在框架模块中包含非模块化标头”错误。我尝试了此处发布的所有解决方案,但没有一个有效。最后,我滚动浏览了所有构建设置,对于与标题相关的每个设置,我都阅读了描述。

USE_HEADERMAP 切换为NO 成功了!

我希望任何人都能发现这对您有帮助!

【讨论】:

【参考方案21】:

当我将 Swift 源代码添加到现有的 ObjC 静态框架(具有 Mach-O 类型“静态库”的动态框架)时,我遇到了这个问题。

修复将CLANG_ENABLE_MODULES(构建设置中的“启用模块”)设置为YES

【讨论】:

【参考方案22】:

我在动态框架(Swift 和 Objective-C 的混合)的 umbrella header 中遇到了这个错误。公共标头目录与框架本身具有相同的名称。将其重命名为 PublicHeaders 即可解决问题(标题仍包含在 #import &lt;FrameworkName/Header.h&gt; 中)。

我对这个案例的检查清单:

设置Target Membership = Public 用于伞头和从它导入的所有头 设置Enable Modules (C and Objective-C) = YES 确保公共标头位于目录中名称与框架名称不同

【讨论】:

【参考方案23】:

在我的情况下,因为您公开公开的每个标题都会被您的伞形标题看到;

解决方法是仅使用名称,例如:

#import "my-public-file.h"

代替:

#import "my-path/added-to/header-search-paths/for/my-public-file.h"

【讨论】:

以上是关于在框架模块中包含非模块化标头的主要内容,如果未能解决你的问题,请参考以下文章

在框架模块错误中包含非模块化标头

具有依赖项的 CocoaPods 框架 - 在框架模块中包含非模块化标头

编译 pod 时“在框架模块中包含非模块化标头”

XCode6:收到错误“在框架模块中包含非模块化标头”

Flutter:在框架模块“firebase_core.FLTFirebasePlugin”中包含非模块化标头

xCode 7 错误:在 Google 地图的框架模块中包含非模块化标头