没有找到目标的伞头,不会生成模块映射

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_macOSVersionNumberMyFrameworkVersionNumber 等)来修复伞形标题问题。【参考方案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 中的文件:

.modulemap umbrella 来自umbrella.h 的关键字 .modulemap header关键字。

模块化标头可以导入模块化标头

创建一个umbrella file - 任何.h 文件(或为框架目标自动生成&lt;product_name&gt;.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 文件:子模块中的伞头不匹配”

Xcode:LLVM 7.0:禁用警告“模块的伞头不包括头”

没有找到适合核心数据迁移的映射模型

Xcode 12 无法构建可可豆荚 - 生成伞头 [关闭]

Swift 框架伞头 - 在框架模块中包含非模块化头

从源映射到现有目标时,AutoMapper 不会忽略 List