update: content update

This commit is contained in:
Unix_Kernel
2024-11-13 14:47:32 +08:00
parent dae10db9d4
commit aca020701b
14 changed files with 285 additions and 78 deletions

View File

@@ -2425,7 +2425,7 @@ import 举个例子吧。在 `Person.m`
### 编写工具生成 hmap 文件
#### 为什么要编写 hmap 文件
#### 为什么要生成 hmap 文件
如果2个 `.m` 文件有相同的头文件代码,造成编译浪费。
@@ -2458,7 +2458,7 @@ Xcode 会主动生成 `.hmap` 文件,那为什么还需要研究生成 `hmap`
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/StaticLibUseHeaderMapOnlyQuoteMethod.png" style="zoom:30%" />
分析:在 App 使用 Static Library 的情况下,假设开启了 `Use Header Map`,静态库中所有头文件类型为 `Project`(只有 Project、Private、Public 3种类型public 就是字面意思的公开p r)的情况,最终生成的 `.hmap` 文件中只会包含类似 `#import "Student.h"` 的键值引用。也就是说使用的地方,只有 `#import "Student.h"` 的这种方式才会走 hmap 策略,否则还是走 `Header Search Path` 来寻找头文件路径。
分析:在 App 使用 Static Library 的情况下,假设开启了 `Use Header Map`,静态库中所有头文件类型为 `Project`(只有 Project、Private、Public 3种类型public 就是字面意思的公开private 则代表 In Progress project 才是通常意义上的 Private 含义)的情况,最终生成的 `.hmap` 文件中只会包含类似 `#import "Student.h"` 的键值引用。也就是说使用的地方,只有 `#import "Student.h"` 的这种方式才会走 hmap 策略,否则还是走 `Header Search Path` 来寻找头文件路径。
组件、库使用 `#import <SomeFramework/SomeFrameworkExportedHeader.h>` 是访问的标准做法。好处有3点
1. 明确头文件的由来,避免歧义
@@ -2505,7 +2505,7 @@ LLVM 真是好东西,把 Xcode 编译、链接等一些幕后的事情变成
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/StaticLibUseHeaderMapEffect.png" style="zoom:30%" />
可以看到静态库使用了自定义的 Header Maps 文件后,使用静态的 App 前后,编译耗时减少了0.1s。
可以看到静态库使用了自定义的 Header Maps 文件后,使用静态的 App 前后,编译耗时减少了1.1s节省了57%
@@ -2696,6 +2696,37 @@ objdump --macho --private-headers DSYMDemo
### main 函数
实验一:
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/MainFuncHasNoDifferenceWithOthers.png" style="zoom:30%" />
编写2个函数main 函数和 test 函数,除了方法名不同,在汇编侧是一样的。
实验二:
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/CanNotLinkWithoutMainFunc.png" style="zoom:30%" />
可以看到创建的 `test.c` 文件中,只有一个 `test` 方法。没有 `main` 方法,然后用 gcc 发现链接报错。
然后利用 gcc 指令 ` gcc -nostartfiles -e_test test.c` 发现可以编译通过,运行也没问题。
当然除了 gcc很多嵌入式平台可以在代码中指定 c 程序的起点。
比如 STM32专门有个汇编文件用于系统的初始化。
总结一下:
- main 函数和其他普通函数并无区别
- main 函数是很多程序的默认起点,但绝不是非它不可,任何函数都可以被设置成程序起点。
iOS 侧dyld 默认以 main 函数作为函数起点。
### dyld 加载过程
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/dyldFullProcess.png" style="zoom:40%" />