本文将介绍如何从C/C++文本到二进制可执行文件的过程。该过程需要经过预处理->编译->链接三个步骤,文件内容从普通文本->汇编->二进制的变化。
预处理(Preprocessing) 编译(Compilation) 汇编(Assembly) 链接(Linking)
预处理概念: 预处理是在程序源代码被编译之前,由预处理器(Preprocessor)对程序源代码进行的处理。这个过程并不对程序的源代码语法进行解析,但它会把源代码分割或处理成为特定的符号为下一步的编译做准备工作。
详细讲解可见:https://www.cnblogs.com/zhjblogs/p/13646399.html
编译的概念: 这里的编译不是指程序从源文件到二进制程序的全部过程,而是指将经过预处理之后的程序转换成特定汇编代码(assembly code)的过程。
汇编的概念: 汇编过程将上一步的汇编代码转换成机器码(machine code),这一步产生的文件叫做目标文件,是二进制格式。
链接的概念: 链接过程将多个目标文以及所需的库文件(.so等)链接成最终的可执行文件(executable file)。
以下面的代码main.c为例,讲解整个编译流程
#include “stdio.h”
int main() {
printf("hello world!");
return 0;
}
-
使用 gcc -E -I./inc main.c -o main.i 命令编译main.c得到main.i,可以看到main.i远大于main.c的大小,这是因为预处理对原文件做了切割等处理。 -
使用 gcc -S -I./inc main.c -o main.s 可以编译原文件得到其汇编语言编写的程序,下面为其程序的内容。 -
使用 gcc -c main.s -o main.o 命令将汇编变为二进制表示 -
使用 下面命令行将程序链接为最后的可执行程序a.out ld -o a.out -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/ccjWjkjI.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. main.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
该命令是使用g++ -v main.o,在collector2后得到的
- 执行a.out得到结果如下
参考: [1] https://www.cnblogs.com/knife-king/p/11090029.html [2] https://cloud.tencent.com/developer/article/1401978 [3] How to link C++ object files with ld.stackoverflow
|