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

Qua*_*ong 36 xcode ios

当我尝试在Xcode 6.3中构建CKCountdownButton作为框架时,它会抱怨

警告:找不到目标'CKCountdownButton'的伞头,将不会生成模块图

然后,当我在其他项目中导入此框架时,它失败了没有这样的模块'CKCountdownButton'

Qua*_*ong 31

我找到了另一个解决方案,Xcode提供了一种通过Module Map File配置指定unbrella头的方法.

快照

内容module.modulemap应该是:

framework module Foo {
    umbrella header "Bar.h"

    header "other-header.h"

    export *
    module * { export * }
}
Run Code Online (Sandbox Code Playgroud)

  • 此处模块映射语法的完整参考:http://clang.llvm.org/docs/Modules.html#module-map-language (2认同)

Qua*_*ong 29

添加一个CKCountdownButton.h框架修复了这个问题.

我认为伞标题意味着具有相同名称的头文件,如Framework

  • 换句话说,确保框架标头与模块名称匹配.在我的例子中,我创建了一个名为"MyFramework macOS"的新框架目标(生成了"MyFramework_macOS.h`").然后我将模块名称更改为"MyFramework",但我没有更改标题.我通过将标题重命名为"MyFramework.h"并更新其中的导出以匹配新模块名称(`MyFramework_macOSVersionNumber`到`MyFrameworkVersionNumber`等)来修复伞标题. (4认同)

onm*_*133 8

该目标需要至少有一个Swift文件.检查是否已将Swift文件添加到目标


yoA*_*ex5 5

自定义框架模块映射(.modulemap)和定义模块(DEFINES_MODULE)

[模块和.modulemap]

公共文件结构:

header_1
  header_1_1
header_2
Run Code Online (Sandbox Code Playgroud)

将应向消费者公开的所有标头标记为 public(header_1.h, header_2.h, header1_1.h)。Headers 公共部分[关于],否则您会收到下一个错误。

//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
Run Code Online (Sandbox Code Playgroud)

modular headers-.h包含在以下文件中的文件.modulemap

  • .modulemapumbrella关键字来自umbrella.h
  • .modulemapheader关键字。

模块化标头只能导入模块化标头

创建一个umbrella file- 任何.h文件(或<product_name>.h为框架目标自动生成)。我们就这样称呼它吧Umbrella.h

将根.h文件添加到umbrella file( Umbrella.h)中。所有从此文件导入的内容都会自动添加

//Umbrella.h file
#import "header_1.h"
#import "header_2.h"
Run Code Online (Sandbox Code Playgroud)

使用或创建自定义.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
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

多个模块

.modulemap 可以包含多个模块。其中之一必须与以下名称相同PRODUCT_MODULE_NAME

//.modulemap
framework module SomeModule
framework module SomeModule2

//using
import SomeModule
import SomeModule2
Run Code Online (Sandbox Code Playgroud)

子模块module

当您导入外部模块时,您可以使用子模块中的标头

//.modulemap
framework module SomeModule {
    module Submodule1 {
        header "header_1.h"
    }
}

//using
import SomeModuleSwift.Submodule1
//or even
import SomeModuleSwift

//availability
header_1

Run Code Online (Sandbox Code Playgroud)

显式子模块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
Run Code Online (Sandbox Code Playgroud)

显式子模块之间的依赖关系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
Run Code Online (Sandbox Code Playgroud)

与雨伞一起工作

module *仅适用于umbrella,如果没有,您会得到

Inferred submodules require a module with an umbrella
Run Code Online (Sandbox Code Playgroud)
//.modulemap
framework module SomeModule {
  umbrella header "Umbrella.h"

  module * { export * }
  export *
Run Code Online (Sandbox Code Playgroud)

生成下一个代码

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
Run Code Online (Sandbox Code Playgroud)

当找不到某些文件时,会发生下一个错误

Error: Cannot find 'header_name' in scope
Run Code Online (Sandbox Code Playgroud)

查看效果使用explicit module

module *- 为每个modular header内部创建子模块umbrella

export *- 将所有子模块导出到当前子/模块

如果我们使用module * { }代替module * { export * }并且import SomeModule.header_1没有任何改变,我们可以modular headers在导入单个子模块时使用所有内容。这是安全的,因为父模块SomeModule可以访问所有子模块

import SomeModule.header_1

header_1
header_2
header_1_1
Run Code Online (Sandbox Code Playgroud)

如果我们使用explicit module * { }代替explicit module * { export * }import SomeModule.header_1我们会得到错误

import SomeModule.header_1

header_1
//header_2 //Error: Cannot find 'header_2' in scope
Run Code Online (Sandbox Code Playgroud)

制作人:

定义模块(DEFINES_MODULE)

header_1
  header_1_1
header_2
Run Code Online (Sandbox Code Playgroud)

模块映射文件(MODULEMAP_FILE)

//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
Run Code Online (Sandbox Code Playgroud)

消费者:

导入路径(SWIFT_INCLUDE_PATHS)

//Umbrella.h file
#import "header_1.h"
#import "header_2.h"
Run Code Online (Sandbox Code Playgroud)