c/c源代码到可执行程序“四级跳”作为c/c开发者理解编译的过程至关重要理解c/c从代码一步步编译成可执行程序的过程是我们学习的必经之路。从.c/.cpp源代码到可执行程序需经历预处理、编译、汇编、链接四个阶段每一步都决定了程序的最终形态1.预处理“文本替换” 的预处理处理#include展开头文件、#define宏替换、条件编译指令等生成.i文件。示例命令gcc -E code.c -o code.i执行完成后生成一个.i文件。2. 编译“高级→汇编” 的翻译将预处理后的代码转换为汇编语言.s文件。示例命令gcc -S code.i -o code.s编译先将代码编译为了汇编语言为什么不直接编制成机器码呢我们的每一步都是基于前人走出来来的最开始的编程就是纯二进制纸带打孔(孔洞能否被光透过代表0和1)但是这样操作繁杂效率低下且人类不容易理解。在此之上二十世纪四五十年代汇编语言被发明出来汇编相比二进制更容易被人理解。但是无法被机器理解。由此编译器产生了。汇编的第一代编译器必然是用机器语言二进制实现的因为汇编语言没有编译器就不能被机器识别所以用二进制写了一个解析汇编语言的程序叫编译器。直接将高级语言翻译成二进制机器码成本会非常高汇编语言可以作为一个中间的跳板但是现代语言中这已经不是必然选项。这其中还有很多细节本文不再赘述。编译器的自举有了二进制的第一代编译器之后就可以用汇编语言实现自己的编译器这一个过程叫做编译器的自举。3. 汇编“汇编→机器码” 的转化将汇编代码转换为机器码.o目标文件这是计算机能直接执行的二进制指令。示例命令gcc -c code.s -o code.o注意.o文件虽然是机器码但是默认不带可执行的属性。要想生成可执行程序要将.o文件转化为可执行程序。.o文件可以形成可执行文件多个.o文件可以链接形成一个可执行程序不同功能的代码分开编译最终形成一个可执行文件。4. 链接“目标文件→可执行程序” 的合并将多个.o文件、依赖的库文件 “合并” 成可执行程序。静态链接把静态库的代码直接拷贝到可执行程序中。静态链接在编译时就会完成链接大体分为以下七步1.收集目标文件解释编译器将文件编译成目标文件.o或.obj。2.解析符号链接器扫描所有目标文件构建一个全局符号表记录每个符号的定义位置。如果同一个符号被多次定义链接器会报错除非是弱符号。如果某个符号未定义链接器会从静态库中查找。3.提取库文件链接器按照命令行指定的顺序处理静态库。当遇到未解析的符号时链接器会在静态库中查找包含该符号定义的目标文件并将其加入到链接中。这个过程可能会重复因为库中的目标文件可能又引用了其他符号。4.合并段链接器将每个目标文件中的代码段如.text合并到可执行文件的代码段数据段如.data、.bss合并到数据段。同时链接器会为每个段分配运行时内存地址。5.重定位在目标文件中对于外部函数和变量的引用通常是暂时用相对地址或0地址表示。链接器根据符号的实际地址修改这些引用填上正确的地址。重定位信息存储在目标文件的重定位表中。6.生成可执行文件完成重定位后链接器生成可执行文件其中包含程序运行的所有代码和数据以及程序入口点信息。动态链接可执行程序仅记录动态库的 “引用”运行时才加载库。动态链接发生在运行时但链接过程实际上分为两个阶段编译时链接和运行时链接。编译时链接生成可执行文件时符号解析与静态链接类似链接器解析程序中的符号引用。但是对于动态库中的符号链接器不会将代码复制到可执行文件中而是记录这些符号的名称和它们所在的动态库信息。
【linux】基础开发工具(3)gcc/g++,动静态库
发布时间:2026/5/15 22:59:42
c/c源代码到可执行程序“四级跳”作为c/c开发者理解编译的过程至关重要理解c/c从代码一步步编译成可执行程序的过程是我们学习的必经之路。从.c/.cpp源代码到可执行程序需经历预处理、编译、汇编、链接四个阶段每一步都决定了程序的最终形态1.预处理“文本替换” 的预处理处理#include展开头文件、#define宏替换、条件编译指令等生成.i文件。示例命令gcc -E code.c -o code.i执行完成后生成一个.i文件。2. 编译“高级→汇编” 的翻译将预处理后的代码转换为汇编语言.s文件。示例命令gcc -S code.i -o code.s编译先将代码编译为了汇编语言为什么不直接编制成机器码呢我们的每一步都是基于前人走出来来的最开始的编程就是纯二进制纸带打孔(孔洞能否被光透过代表0和1)但是这样操作繁杂效率低下且人类不容易理解。在此之上二十世纪四五十年代汇编语言被发明出来汇编相比二进制更容易被人理解。但是无法被机器理解。由此编译器产生了。汇编的第一代编译器必然是用机器语言二进制实现的因为汇编语言没有编译器就不能被机器识别所以用二进制写了一个解析汇编语言的程序叫编译器。直接将高级语言翻译成二进制机器码成本会非常高汇编语言可以作为一个中间的跳板但是现代语言中这已经不是必然选项。这其中还有很多细节本文不再赘述。编译器的自举有了二进制的第一代编译器之后就可以用汇编语言实现自己的编译器这一个过程叫做编译器的自举。3. 汇编“汇编→机器码” 的转化将汇编代码转换为机器码.o目标文件这是计算机能直接执行的二进制指令。示例命令gcc -c code.s -o code.o注意.o文件虽然是机器码但是默认不带可执行的属性。要想生成可执行程序要将.o文件转化为可执行程序。.o文件可以形成可执行文件多个.o文件可以链接形成一个可执行程序不同功能的代码分开编译最终形成一个可执行文件。4. 链接“目标文件→可执行程序” 的合并将多个.o文件、依赖的库文件 “合并” 成可执行程序。静态链接把静态库的代码直接拷贝到可执行程序中。静态链接在编译时就会完成链接大体分为以下七步1.收集目标文件解释编译器将文件编译成目标文件.o或.obj。2.解析符号链接器扫描所有目标文件构建一个全局符号表记录每个符号的定义位置。如果同一个符号被多次定义链接器会报错除非是弱符号。如果某个符号未定义链接器会从静态库中查找。3.提取库文件链接器按照命令行指定的顺序处理静态库。当遇到未解析的符号时链接器会在静态库中查找包含该符号定义的目标文件并将其加入到链接中。这个过程可能会重复因为库中的目标文件可能又引用了其他符号。4.合并段链接器将每个目标文件中的代码段如.text合并到可执行文件的代码段数据段如.data、.bss合并到数据段。同时链接器会为每个段分配运行时内存地址。5.重定位在目标文件中对于外部函数和变量的引用通常是暂时用相对地址或0地址表示。链接器根据符号的实际地址修改这些引用填上正确的地址。重定位信息存储在目标文件的重定位表中。6.生成可执行文件完成重定位后链接器生成可执行文件其中包含程序运行的所有代码和数据以及程序入口点信息。动态链接可执行程序仅记录动态库的 “引用”运行时才加载库。动态链接发生在运行时但链接过程实际上分为两个阶段编译时链接和运行时链接。编译时链接生成可执行文件时符号解析与静态链接类似链接器解析程序中的符号引用。但是对于动态库中的符号链接器不会将代码复制到可执行文件中而是记录这些符号的名称和它们所在的动态库信息。