GCC(GNU Compiler Collection)是LINUX平台下最强大的编译器,它不仅能编译
C,C++,object c,它还可以通过不同的前端模块来支持各种语言,如 Java、Fortran、
Pascal、Modula-3 和 Ada 等。
- 编译过程
在使用 GCC 编译程序时,编译过程可以被细分为四个阶段:
◆ 预处理(Pre-Processing)
◆ 编译(Compiling)
◆ 汇编(Assembling)
◆ 链接(Linking)
下面我们来看一段简单的代码”:
1 2 3 4 5 6 |
#include int main(void) { printf ("Hello world !n"); return 0; } |
现在编译执行:
1 2 3 |
$ gcc hello.c -o hello $ ./hello Hello world ! |
为了弄清楚编译的过程,我们现在把编译分成几个单独的步骤:
第一步是进行预编译,使用-E 参数可以让 GCC 在预处理结束后停止编译过程:
1 |
$ gcc -E hello.c -o hello.i |
此时若查看 hello.cpp 文件中的内容,会发现 stdio.h 的内容确实都插到文件里去了,而其它应当被预处理的宏定义也都做了相应的处理。下一步是将 hello.i 编译为目标代码,这可以通过使用-c 参数来完成:
1 |
$ gcc -c hello.i -o hello.o |
GCC 默认将.i 文件看成是预处理后的 C 语言源代码,因此上述命令将自动跳过预处
理步骤而开始执行编译过程,也可以使用-x 参数让 GCC 从指定的步骤开始编译。最
后一步是将生成的目标文件链接成可执行文件:
1 |
$ gcc hello.o -o hello |
在采用模块化的设计思想进行软件开发时,通常整个程序是由多个源文件组成的,相
应地也就形成了多个编译单元,使用 GCC 能够很好地管理这些编译单元。假设有一
个由 foo1.c 和 foo2.c 两个源文件组成的程序,为了对它们进行编译,并最终生成可执
行程序 foo,可以使用下面这条命令:
1 |
$ gcc foo1.c foo2.c -o foo |
如果同时处理的文件不止一个,GCC 仍然会按照预处理、编译和链接的过程依次进
行。如果深究起来,上面这条命令大致相当于依次执行如下三条命令:
1 2 3 |
$ gcc -c foo1.c -o foo1.o $ gcc -c foo2.c -o foo2.o $ gcc foo1.o foo2.o -o foo |
- 警告提示功能
GCC 包含完整的出错检查和警告提示功能,它们可以帮助 Linux 程序员写出更加专
业和优美的代码。常用的警告选项有:
-pedantic :使用了扩展语法的地方将产生相应的警告信息。
-Wall :使用它能够使 GCC 产生尽可能多的警告信息。
-Werror:它要求 GCC 将所有的警告当成错误进行处理。
- 库依赖
GCC 采用搜索目录的办法来查找所需要的文件,-I 选项可以向 GCC 的头文件搜索路
径中添加新的目录。例如,如果在/home/xiaowp/include/目录下有编译时所需要的头
文件,为了让 GCC 能够顺利地找到它们,就可以使用-I 选项:
1 |
$ gcc foo.c -I /home/xiaowp/include -o foo |
同样,如果使用了不在标准位置的库文件,那么可以通过-L 选项向 GCC 的库文件搜索路径中添加新的目录。例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文
件 libfoo.so,为了让 GCC 能够顺利地找到它,可以使用下面的命令:
1 |
$ gcc foo.c -L /home/xiaowp/lib -lfoo -o foo |
值得好好解释一下的是-l 选项,它指示 GCC 去连接库文件 libfoo.so。Linux 下的库文
件在命名时有一个约定,那就是应该以 lib 三个字母开头,由于所有的库文件都遵循了
同样的规范,因此在用-l 选项指定链接的库文件名时可以省去 lib 三个字母,也就是说
GCC 在对-lfoo 进行处理时,会自动去链接名为libfoo.so 的文件。
Linux 下的库文件分为两大类分别是动态链接库(通常以.so 结尾)和静态链接库(通常
以.a 结尾),两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编
译时静态加载的。默认情况下,GCC 在链接时优先使用动态链接库,只有当动态链接
库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static 选项,强制
使用静态链接库。例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件
libfoo.so 和 libfoo.a,为了让 GCC 在链接时只用到静态链接库,可以使用下面的命令:
1 |
$ gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo |
后记:这篇文章是在我看了《开源》杂志第四期里的一篇文章改写的。作者是肖文鹏。
转载请注明:爱开源 » GCC的简单使用教程上