gcc编译过程包括预处理,编译,汇编,链接。
(1)预处理
预处理就是对文件中带#内容的处理,包括宏定义,条件编译和头文件。
可以通过gcc -E <file> -o xxx.i 来进行预处理
查看.i 文件可发现对头文件的处理就是把所引用的头文件的内容拷贝过来,对宏定义展开,根据条件编译进行处理相应的代码 。
(2)编译
编译就是将预处理后的xxx.i文件翻译为汇编代码
gcc -S xxx.i -o xxx.s .s文件一般表示汇编代码
(3)汇编
汇编就是将汇编文件翻译成具有一定格式的机器码(反汇编就是将机器码翻译为汇编代码)
gcc -c xxx.s -o xxx.o .o文件就是OBJ文件
也可以直接 gcc -c xxx.c -o xxx.o ,gcc会对.c文件默认进行预处理,-c选项可同时进行编译和汇编操作
(4)链接
链接就是将上述生成的OBJ文件和系统库的OBJ文件、库文件链接在一起,最终形成一个可以在特定平台下运行的可执行文件
gcc xxx.o -o xxx xxx是可执行文件
如果在链接时指定了-nostdlib选项时,在系统上编译会出错,因为这个选项无法链接启动文件和libc库,通常在编译裸机代码、bootloader、内核文件时添加该选项,因为这些文件的运行是完全不需要依赖系统的。
在linux下可以使用 ldd <file>来查看依赖的库文件。
(1)动态链接: 动态链接是链接动态库,在程序执行时才去找这些库中的内容,编译出来的可执行文件体积小,但是在运行可执行程序时,在该环境下必须要有相应的动态库。
gcc xxx.o -o xxx 默认动态链接
(2)静态链接:就是链接静态库,生成的可执行程序就包含了所需要的静态库,所以编译出来的可执行文件体积会大。
gcc -static xxx.o -o xxx