- 预编译: 对每一个文件的头文件展开, 宏定义的替换等操作
- 编译:
2.1. 前端
- 词法分析: 主要是生成一个一个的token
- 语法分析: 生成抽象语法树, 简称AST, 生成中间代码IR
2.2. 中间代码:
- 生成.ll后缀的文件, 作为后端的输入. 并且由优化器做相应等级优化
2.3. 后端:
- .ll转化为汇编.s
- .s文件转化为一个个.o的可执行文件
- 生成一个macho的可执行文件
- 链接:
-
exex()程序函数入口, 开启进程空间
-
加载编译好的macho文件到内存
-
dyld链接器进行链接
-
dyld从共享缓存空间递归加载依赖库, 比如libsystem, libdispatch, libobjc, Foundation框架等系统动态库, 使用imagelist命令可以查看到按照顺序加载进的image镜像
-
rebase操作, 由于alsr的原因, 对macho的DATA段的数据进行重定向
-
binding操作, 对于调用的外部符号, 进行绑定操作.
- dyld_stub_binder和objc_msgSend符号进行绑定, 属于非懒加载符号.
- 比如pirnt符号在Foundation库中, 在第一次调用到的时候, 会通过dyld_stub_binder进行一个地址的绑定操作获取到真实的符号地址进行加载.
-
Objc Setup操作, 注册类到全局表中, category加载, 保证sel唯一性修复验证等.
-
加载load方法, C++构造函数, 静态变量初始化等.
-
调用main函数, RunLoop跑起项目启动
参考:
资料
网友评论