没有找到目标的伞头,不会生成模块映射
Posted
技术标签:
【中文标题】没有找到目标的伞头,不会生成模块映射【英文标题】:no umbrella header found for target, module map will not be generated 【发布时间】:2015-06-08 08:21:41 【问题描述】:当我尝试在 Xcode 6.3 中将 CKCountdownButton 构建为框架时,它会抱怨
警告:找不到目标“CKCountdownButton”的伞头,不会生成模块映射
然后当我在其他项目中导入这个框架时,它失败了 No such module 'CKCountdownButton'
【问题讨论】:
【参考方案1】:我找到了另一个解决方案,Xcode提供了一种通过Module Map File配置来指定umbrella header的方法。
module.modulemap
的内容应该是:
framework module Foo
umbrella header "Bar.h"
header "other-header.h"
export *
module * export *
【讨论】:
modulemap 语法的完整参考:clang.llvm.org/docs/Modules.html#module-map-language【参考方案2】:在框架中添加CKCountdownButton.h
修复了这个问题。
我认为伞形头是指与Framework同名的头文件
【讨论】:
换句话说,确保框架标题与模块名称匹配。在我的例子中,我创建了一个名为“MyFramework macOS”的新框架目标(它生成了MyFramework_macOS.h
)。然后我将模块名称更改为“MyFramework”,但我没有更改标题。我通过将标题重命名为 MyFramework.h
并更新其中的导出以匹配新模块名称(MyFramework_macOSVersionNumber
到 MyFrameworkVersionNumber
等)来修复伞形标题问题。【参考方案3】:
该目标需要至少有 1 个 Swift 文件。检查您是否已将 Swift 文件添加到目标中
【讨论】:
【参考方案4】:自定义框架模块映射(.modulemap)和DEFINES_MODULE
[Module and .modulemap]
公共文件结构:
header_1
header_1_1
header_2
将所有应向消费者公开的标头标记为公共(标头_1.h、标头_2.h、标头1_1.h)。 Headers
public section[About] 否则你会得到下一个错误。
//For example in umbrella.h
Include of non-modular header inside framework module '<module_name>'
//or in upper .h file
'PBURLConnectionStub.h' file not found
modular headers
- .h
包含在.modulemap
中的文件:
umbrella
来自umbrella.h
的关键字
.modulemap header
关键字。
模块化标头可以仅导入模块化标头
创建一个umbrella file
- 任何.h
文件(或为框架目标自动生成<product_name>.h
)。我们就叫它Umbrella.h
将根.h
文件添加到umbrella file
(Umbrella.h
)。从此文件中的所有导入都将自动添加
//Umbrella.h file
#import "header_1.h"
#import "header_2.h"
使用或创建自定义.modulemap
文件。您可以随意调用.modulemap
文件,编译后将调用module.modulemap
。另外我不建议您将其称为module.modulemap
,因为它可能会导致此文件发生不可预知的变化
默认生成的module.modulemap
:
//the same for Objective-C and Swift framework
framework module SomeModule
//umbrella header "<umbrella_name>.h"
umbrella header "Umbrella.h"
export *
module * export *
//unique for Swift framework
module SomeModule.Swift
header "SomeModule-Swift.h"
requires objc
umbrella header
以递归方式公开所有 module headers
。生成下一个代码
//.modulemap
framework module SomeModule
//explicitly define all modular header
header "header_1.h"
header "header_2.h"
header "header_1_1.h"
//using
import SomeModule
header_1
header_2
header_1_1
多个模块
.modulemap 可以包含多个模块。其中之一必须与PRODUCT_MODULE_NAME
同名
//.modulemap
framework module SomeModule
framework module SomeModule2
//using
import SomeModule
import SomeModule2
子模块module
当您导入外部模块时,您可以使用子模块中的标头
//.modulemap
framework module SomeModule
module Submodule1
header "header_1.h"
//using
import SomeModuleSwift.Submodule1
//or even
import SomeModuleSwift
//availability
header_1
显式子模块explicit module
您不能将模块名称用于子模块标题(如上例所示默认情况下可以这样做)
//.modulemap
framework module SomeModule
explicit module Submodule1
header "header_1.h"
//using
//import SomeModuleSwift //Error: Cannot find 'header_1' in scope
import SomeModuleSwift.Submodule1
//availability
header_1
显式子模块之间的依赖关系export
//.modulemap
framework module SomeModule
explicit module Submodule1
header "header_1.h"
export Submodule2
explicit module Submodule2
header "header_2.h"
//using
import SomeModuleObjC.Submodule1
//availability
header_1
header_2
使用雨伞
module *
仅适用于 umbrella
,否则您会得到
Inferred submodules require a module with an umbrella
//.modulemap
framework module SomeModule
umbrella header "Umbrella.h"
module * export *
export *
生成下一个代码
framework module SomeModule
//module * export *
module header_1
header "header_1.h"
export header_2
export header_1_1
module header_2
header "header_2.h"
export header_1
export header_1_1
module header_1_1
header "header_1_1.h"
export header_1
export header_2
//export *
export header_1
export header_2
export header_1_1
//using one of them
import SomeModule.header_1
//or
import SomeModule.header_2
//or
import SomeModule.header_1_1
//or
SomeModule
//availability
header_1
header_2
header_1_1
当找不到某个文件时,会发生下一个错误
Error: Cannot find 'header_name' in scope
查看效果使用explicit module
module *
- 为umbrella
内的每个modular header
创建子模块
export *
- 将所有子模块导出到当前子/模块中
如果我们使用module *
而不是module * export *
和import SomeModule.header_1
没有任何改变,我们可以在导入单个子模块时使用所有modular headers
。这是安全的,因为父模块SomeModule
可以访问所有子模块
import SomeModule.header_1
header_1
header_2
header_1_1
如果我们使用explicit module *
而不是explicit module * export *
和import SomeModule.header_1
我们会得到错误
import SomeModule.header_1
header_1
//header_2 //Error: Cannot find 'header_2' in scope
制作人:
定义模块(DEFINES_MODULE)
Build Settings -> Defines Module
If YES - Xcode generates .modulemap. If `MODULEMAP_FILE` is not specified Xcode try to generate it automatically
模块映射文件(MODULEMAP_FILE)
Build Settings -> Module Map File
Path to custom `.modulemap` file
The result file `module.modulemap` will be generated and embedded into .framework
消费者:
导入路径(SWIFT_INCLUDE_PATHS)
Build Settings -> Import Paths
Path to custom `.modulemap` file
【讨论】:
【参考方案5】:我在使用“GoogleToolbox”时遇到了同样的问题。当我尝试更新我的 Pod 存储库并且发生了一些错误时发生了这种情况。刚刚在项目文件夹的终端上进行了“pod install”,一切正常。
【讨论】:
以上是关于没有找到目标的伞头,不会生成模块映射的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 5 错误:“格式错误或损坏的 AST 文件:子模块中的伞头不匹配”