Linux中的GCC


GCC是GNU C Compiler的简写,但是经过了这么多年的发展,GCC已经不仅能够支持C语言,他还可以支持Ada、CPP、Java、Objective C、Pascal、COBOL等语言,而且还支持函数式变成和逻辑编程的Mercury等语言。也就是他现在应该是GNU Compiler Collection的简写了,也就是GNU 编译器家族。

不过GCC的使用还是基本可以分为四个步骤的,也就是:预处理也叫做预编译,也就是Preprocessing,编译也就是Compilation,汇编也就是Assembly,连接也就是Linking。

对于预处理,我们可以使用gcc -E test.c输出到屏幕上,也可以用gcc -E test.c -o test.i输出到test.i文件中。对于-E选项,可以让编译器在预处理后停止,并且输出预处理结果。

对于编译,我们可以使用对.i文件生成.s文件,比如我们使用gcc -S test.i -o test.o,其中gcc的-S选项,表示程序编译期间,在生成汇编代码后停止,-o输出汇编代码文件。

对于汇编,可以产生目标文件,比如gcc -c test.c -o test.o这种命令格式。

对于连接,他负责将程序的目标文件与所需要的所有附加的目标文件连接起来,最终生成可执行文件,复杂的目标文件包括静态链接库和动态链接库。我们可以使用gcc test.o -o test这种格式。

对于检测,我们可以使用-pedantic编译选项,比如我们使用gcc -pedantic hello.c -o hello这种格式,他并不能保证程序与ANSI C完全兼容,我们可以使用-Wall来产生更多的警告信息。

 

 

虽然Linux下的大多数函数都默认将头文件放到/usr/include/目录下,库文件放到/usr/lib/目录下,但是如果我们需要其他的头文件的时候,需要-I参数,我们需要其他的库文件的时候,使用-L参数。

Linux下的库文件通常分为动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾),两者的区别仅仅是在于程序执行时所需要的代码是在运行时动态加载的,还是在编译时静态加载的。

在默认情况下,GCC在连接时优先使用动态链接库,我们可以在编译时加上-static参数来强制使用静态链接库。

 

静态连接时的搜索路径顺序:

(1)ld会去找gcc命令中的参数-L

(2)gcc的环境变量LIBRARY_PATH

(3)内定目录,也就是/lib、/usr/lib、/usr/local/lib,也是gcc时写在程序内的

动态连接时的搜索路径顺序:

(1)编译目标代码时指定的动态搜索路径

(2)环境变量LD_LIBRARY_PATH指定的动态搜索路径

(3)配置文件/etc/ld.so.conf中指定的动态搜索路径

(4)默认的动态库搜索路径/lib

(5)默认的动态搜索路径/usr/lib

相关内容