【问题标题】: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'

【问题讨论】:

    标签: ios xcode


    【解决方案1】:

    我找到了另一个解决方案,Xcode提供了一种通过Module Map File配置来指定umbrella header的方法。

    module.modulemap的内容应该是:

    framework module Foo {
        umbrella header "Bar.h"
    
        header "other-header.h"
    
        export *
        module * { export * }
    }
    

    【讨论】:

    【解决方案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”,一切正常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-31
          • 2015-11-22
          • 2018-01-06
          • 1970-01-01
          • 1970-01-01
          • 2010-09-19
          • 2020-04-15
          • 2017-05-06
          相关资源
          最近更新 更多