美文网首页iOS学习
6、iOS强化 --- 编译与链接(详解)

6、iOS强化 --- 编译与链接(详解)

作者: Jax_YD | 来源:发表于2021-03-10 10:35 被阅读0次

    前面两篇文章都有讲到编译与链接,但是个人感觉不交散,这里总结一下:
    大家在探索整个流程的时候,尽量不要引入外界的库,这样编译起来会比较顺畅。
    另外可以通过clang -help来查看clang的相关指令。

    我们现在有一个命令行工程:

    
    int main(int argc, const char * argv[]) {
    
        return 0;
    }
    

    我们平时都会用cmd + B来编译工程;那么这么一步操作究竟做了些什么呢?

    • 这个工程中有四步隐藏的操作:
      预处理编译汇编链接

    预处理

    预处理也被称作预编译(Prepressing)
    是将main.m文件编译成mian.i文件,指令如下:

    clang -E main.m -o main.i
    

    处理源代码中以#开头的预编译指令。规则如下:
    1、#define 删除,并展开对应的宏定义。
    2、处理所有的条件预编译指令。如#if#ifdef#else#endif
    3、#include#import 包含的文件递归插入到此处。
    4、删除所有的注释 ///**/等。
    5、添加行号和文件名标识。如# 1 "main.m"(编译调试会用到)。

    image.png

    编译(Compilation)

    main.i文件编译成main.s文件,指令如下:

    clang -S main.i -o main.s
    

    这个过程就是把上面的main.i文件进行:词法分析语法分析静态分析,优化生成相应的汇编代码,最终生成main.s文件。

    名字 解释
    词法分析 把源代码的字符序列分割成一个个token(关键字、表示符、字面量、特殊符号),比如把标识符放到符号表里面。
    语法分析 生成抽象语法树AST,此时运算符号的优先级确定了;有些符号具有多重含义也确定了,比如:*是乘号还是对指针取内容;表达式不合法、括号不匹配等等,都会报错。
    静态分析 分析类型声明匹配问题。比如整型和字符串相加,肯定会报错。
    中间语法生成 CodeGen根据AST自上向下逐步翻译成LLVM IR,并且对在编译期就可以确定的表达式进行优化,比如代码里面的a=1+3,可以优化成a=4。(假如开启了bitcode
    目标代码生成与优化 根据中间语法生成依赖具体机器的汇编语言;并优化汇编语言。这个过程中,假如有变量且定义在同一个编译单元里,那么就给这个变量分配空间,确定变量的地址。假如变量或者函数不定义在这个编译单元里面,那就等到链接的时候才能确定地址。
    image.png

    汇编(Assembly)

    main.s文件编译成main.o文件(也就是我们常说的目标文件),指令如下

    clang -c main.s -o main.o
    

    这个过程就是把上面得到的main.s文件里面的汇编指令翻译成机器指令,最终生成等到main.o

    image.png

    链接(Linking)

    这个过程就是将main.o编译成对应的Mach-O文件,也就是我们常说的可执行文件,指令如下:

    clang main.o -o main
    
    image.png
    我们之前讲过:链接的本质就是把一个或多个目标文件和需要的库(静态库/动态库,如果需要的话)组合成一个文件(Mach-O可执行文件)

    那么以上就是编译与链接的整个过程。

    参考文档:https://juejin.cn/post/6844903912147795982

    相关文章

      网友评论

        本文标题:6、iOS强化 --- 编译与链接(详解)

        本文链接:https://www.haomeiwen.com/subject/dyrbqltx.html