正常情况下,C代码写完后在Linux系统下直接通过gcc命令编译成可执行文件,即
#include <stdio.h>
int main()
{
printf("hello, world!\n");
return 0;
}
编译:
gcc hello.c -o hello
运行:
./hello
结果:
接下来讲述一下具体的编译过程
这个编译过程一共分为4步:预处理、编译、汇编、链接
# 预处理:
gcc -E hello.c -o hello.i
# 编译:
gcc -S hello.i -o hello.s
# 汇编:
gcc -c hello.s -o hello.o
# 链接:
gcc hello.o -o hello
1. 预处理
预处理就是处理所有以#开头的代码,比如头文件展开、宏定义替换、条件编译等,使用命令:gcc -E hello.c -o hello.i
。打开预处理文件后,发现代码多了很多,但是头文件没了。其实就是去指定目录下,比如 /usr/include/ 的目录找到 stdio.h 文件,复制粘贴到原文件中
2. 编译
编译做了两件事情,先是语法检查,然后把C文件变成了汇编文件,使用命令:gcc -S hello.i -o hello.s
。生成的新文件hello.s里面便是汇编代码
3. 汇编
汇编使用命令:gcc -c hello.s -o hello.o
。把汇编文件翻译成二进制文件hello.o (这个文件是无法直接看懂的)。
现在的hello.o文件虽然是二进制文件,但是还是不能直接运行,因为这个文件还缺少很多信息的支撑,比如这个文件并不知道printf函数在哪,所以需要最后一步:链接
4. 链接
链接主要是把工程里面所有的文件合并,然后找到依赖的库文件,比如printf属于C库,把库的信息放到最终的二进制文件中,其中还涉及了动态链接和静态链接,最终得到了二进制文件才是可执行文件,命令:gcc hello.o -o hello