xcode构建系统及编译优化(三)

643 阅读2分钟

头文件映射与模块映射

摘要: 自身target中头文件的检索使用hmap,对于库文件的头文件检索使用clang module,或许是在编译过程中的一个较优解。

头文件映射

4.png

Apple在头文件检索方面做了优化,在编译源文件之前,已经把头文件的路径写入hmap文件中;

Screen Shot 2022-06-07 at 4.46.18 PM.png

PS: 日志中复制源文件的编译指令到终端 + -v;可查看编译详情

定位非系统文件:

  • ""导入的头文件从hmap中查找
  • <>导入的头文件先去target-hmap中,如果没找到再去对应库文件路径中查找

image.png

定位系统头文件:

image.png

具体分析可查看美团团队的分享:从预编译的角度理解Swift与Objective-C及混编机制

我们常用cocoapod管理三方库; 但是对于依赖的第三方库头文件的检索并不会命中hmap,而是从Pods-xxx.debug.xcconfig配置的路径查找的,里面都列举了对应导入的第三方库,<>从framework/library 查找,“”从Header Search Paths查找;

截屏2022-06-02 下午9.31.04.png

截屏2022-06-02 下午9.32.46.png

另外对照分析主工程hmap文件,也可以发现没有对应的三方库头文件;
总结,主工程中hmap只能命中当前自身的.h头文件;

同样方式检查pod中的第三方库,可以命中自身的.h头文件,但是发现<>也没有命中其依赖的第三方库, ""反而可以;

在Pods_xxx-all-target-headers.hmap 里面其实已经包含了所有的路径,但是没有使用到,使用的反而是Pods_xxx-all-non-framework-target-headers.hmap,跟apple在wwdc上演示的不一致。
.a和.framework一样都是这种情况。

framework库:
主工程:

  1. “...”search starts here:
xxx-generated-files.hmap  
xxx-project-headers.hmap  

仅命中自身.h文件,没有第三方库的头文件;

  1. <...> search starts here:
xxx-own-target-headers.hmap  
xxx-all-non-framework-target-headers.hmap  

同样没有第三方库的头文件

pods:

  1. “...”search starts here:
xxx-generated-files.hmap  
xxx-project-headers.hmap  

能找到""引用的头文件的路径,如下所示;

UIView+WebCache.h -> SDWebImage/UIView+WebCache.h

UIView+WebCacheOperation.h -> SDWebImage/UIView+WebCacheOperation.h

YYClassInfo.h -> YYModel/YYClassInfo.h

YYModel-prefix.pch -> /Users/sunjiale583/Desktop/temp/tempCom/Pods/Target Support Files/YYModel/YYModel-prefix.pch

YYModel-umbrella.h -> YYModel/YYModel-umbrella.h

YYModel.h -> YYModel/YYModel.h
  1. <...> search starts here:指定的是
xxx-own-target-headers.hmap  
xxx-all-non-framework-target-headers.hmap

同样没有第三方库的头文件;

apple WWDC中分享的是下面2个:
xxx-own-target-headers.hmap
xxx-all-target-headers.hmap (包含pods所有)

image.png

模块映射 clang module

xcode工程对于依赖库头文件的检索不使用hmap或许正是出于clang module考虑;

.framework有clang module功能,.a静态库没有

clang module 的优点:

  • 一次加载和处理头文件
  • 缓存符号信息
  • 复用
  • 大型项目更快的构建实践

对于自己创建的framework,通过构建虚拟文件系统(VFS),方便clang创建模块,里面描述了文件结构信息(yaml文件),但是抽象框架只能映射到目录文件

在cocoapod中,所有的pods共用一个all-product-headers.yaml;

Screen Shot 2022-06-07 at 4.18.19 PM.png

使用framework静态库的module功能,在主工程中导入<>的时候,预编译情况如下:

Screen Shot 2022-06-07 at 4.30.42 PM.png

综上所述,在主工程中,使用hmap优化""头文件检索,使用framework的module优化三方库<>头文件导入,对于编译的优化,有较大的提升。