JHHK

欢迎来到我的个人网站
行者常至 为者常成

8.Hmap

目录

头文件查找

一、.m文件在编译的时候如何查找其使用的头文件?

第一轮:先在.m的同目录下查找
1、查找是否有modulemap文件,如果有就以module的形式引入(modulemap文件内配置了对应了.h文件)

2、编译选项是否配置了module文件,module的方式

3、然后看是不是framework(后边讲)

4、是否有headermap文件,headermap文件内若配置的是头文件的具体路径,copy的方式,
若配置的是module,那么就是module的方式
headermap是可以关掉的:USER_HEADERMAP

第二轮:再去其它目录下查找

二、modulemap也是需要header_search_path来配合使用的

module Zoo {
  // header 可以看做是一个目录 header_search_path
  // 也需要先找到 Zoo.h文件,找到Zoo.h文件
  // 能找到zoo.h在什么位置,才会对使用Zoo.h文件的地方转化成module的模式
  umbrella header "Zoo.h"

  export *

  module * { export * }
}

Swift和module

一、关于子module

1、cocoapods的podspec内配置module
不使用系统的modulemap,使用自己的modulemap

s.module_map

2、子module

module Zoo {
  umbrella header "Zoo.h"
  export *
  module * { export * }

  // 告诉你这是私有文件,不要使用,但是你就是要用也能用
  // 约定俗称 就跟头文件的public、private project 一样
  // 相当于buildSetting中的 private module mapfile 配置项
  explict module private {

  }
}

为什么有了伞文件,还要定义这样的子模块:

explicit module Private {}    

因为伞文件内不包括这些private文件

二、Swift和Module

1、定义子module的另外一种方式
SwiftLibrary.modulemap文件内容

// 主module
module SwiftLibrary {

}

// 使用时:SwiftLibrary.xxx
module SwiftLibray.Swift {
  header "SwiftLibrary-Swift.h"
  //编译的语言
  requires objc
}

2、组织swift的.a库需要的文件

.a库编译完成后,只有libSwiftLibrary.a 和 SwiftLibrary.swiftmodule
libSwiftLibrary.a:静态库的二进制文件
SwiftLibrary.swiftmodule:给swift用的module文件包含了多个平台,它也是二进制的

SwiftLibrary-Swift.h是从构建产物目录中拷贝到这个目录的
SwiftLibrary.modulemap文件是自己创建的,内容如上。这个文件是给OC使用的module文件

3、config文件如何写?

# OTHER_CFLAGS 是给OC配置module文件,-fmodule-map-file可以有多组  
OTHER_CFLAGS = -fmodules
    -fmodule-map-file="${SRCROOT}/LGApp/Zoo/zoo.modulemap"
    # OC使用swift库的代码
    -fmodule-map-file="${SRCROOT}../Product/SwiftLibrary.modulemap"

HEADER_SEAR_PATHS = "${SRCROOT}/LGApp/Zoo/"

# swift使用swift库的代码
SWIFT_INCLUDE_PATHS="${SRCROOT}../Product"

# swift使用oc??? 这个没弄明白呢
OTHER_SWIFT_FLAGS = -Xclang
    -fmodule-map-file="${SRCROOT}/LGApp/Zoo/zoo.modulemap"

.a –> cocoapods –> use module header

HeaderMap

一、hmap文件介绍

hmap是header map 的简称,头文件的映射关系,可以更快的定位头文件的位置

macho:header + 二进制

hmap也是二进制文件:header + 二进制value

hmap = header + [一堆bucket] + string table (string offset)

二、cocoapods-mapfile使用

1、安装

gem install cocoapods-mapfile

2、生成一个hmap

hmapfile writer --json-path=test.json

test.json

{
    "MM.h": [
        "/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
        "MM.h"
    ],
    "Dog.h": [
        "/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
        "MM.h"
    ],
    "Cat.h": [
        "/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
        "MM.h"
    ],
    "TestAndTestApp/MM.h": [
        "/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
        "MM.h"
    ],
    "TestAndTestApp/Dog.h": [
        "/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
        "Dog.h"
    ]
}

3、查看一个hmap

hmapfile reader --hmap-path=test.hmap   

hmap的结构如下:

$  hmapfile reader --hmap-path=test.hmap

[hmapfile] Reader start
  Header map path: /Users/lixiaoyi/Desktop/rubyDemo/test.hmap
        Hash bucket count: 8
        String table entry count: 5
        Max value length: 0
	- Bucket: 0        Key MM.h -> Prefix /Users/ws/Desktop/TestAndTestApp/TestAndTestApp/, Suffix MM.h
	- Bucket: 1        Key Dog.h -> Prefix /Users/ws/Desktop/TestAndTestApp/TestAndTestApp/, Suffix MM.h
	- Bucket: 2        Key TestAndTestApp/Dog.h -> Prefix /Users/ws/Desktop/TestAndTestApp/TestAndTestApp/, Suffix Dog.h
	- Bucket: 6        Key Cat.h -> Prefix /Users/ws/Desktop/TestAndTestApp/TestAndTestApp/, Suffix MM.h
	- Bucket: 7        Key TestAndTestApp/MM.h -> Prefix /Users/ws/Desktop/TestAndTestApp/TestAndTestApp/, Suffix MM.h

[hmapfile] Reader finish

三、在工程中使用

在工程的跟目录下执行

hmapfile gen

或者在podfile文件添加

plugin 'cocoapods-mapfile'

具体用法参考:https://github.com/Cat1237/cocoapods-hmap

vfs

如果要hmap实现 moudule的话,xcode的 hmap 配置项需要关掉,
关掉之后就不会生成vfs,就会造成头文件冲突(比如引入了源码里的头文件也引入了public目录内的头文件,vfs会帮我们映射成同一个头文件)
需要我们自己生成vfs

yaml文件


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.