首页 > 代码库 > gcc的使用

gcc的使用

    gcc是Linux下常用的C/C++编译驱动器。本文首先介绍了gcc整个编译连接过程,然后讨论gcc常用的选项,最后说明了gcc与g++的关系。

gcc编译连接过程

    gcc编程连接过程如下图:


这里的cpp是C预处理程序(比如可以直接调用cpp hello.c -o hello.i把预处理结果输出到hello.i);cc是C编译器,它将hello.i编译成一个ASCII汇编语言文件hello.S;as是汇编编译器,它将hello.S翻译成一个可重位目标文件hello.o;ld是连接程序,把所有的可重位目标文件组合起来,生成一个可执行文件。也就说gcc是一个编译驱动程序,它通过调用上面的程序(比如cpp,cc等)来生成可执行文件。我们可以使用gcc的选项生成这些中间文件,方法如下:

    gcc -E hello.c -o preprocess_hello.i执行这个命令后,preprocess_hello.i 保存的就是预处理后的C程序。
    gcc -S hello.c -o assemble_hello.s执行这个命令后,assemble_hello.s保存的就是对于程序的汇编代码。相当于直接执行了预处理和编译两步。
    gcc -c hello.c -o object_hello.o执行这个命令后,object_hello.o保存的就是对于程序的机器代码,还不能执行,因为还没有连接。想当与一次执行了前面三步。

    我们可以使用选项-save-temps在生成可执行文件时保留所有的中间文件。比如gcc -save-temps -o hello hello.c可以保留中间文件,即一次性会生成文件hello.i,hello.o,hello.s和可执行文件hello。

gcc的常用选项

    gcc可以使用gcc --help命令查看选项,gcc的选项用法,可以概括如下:


常用的选项概括如下:


下面对这些常用选项简单说明:

     -x用于指定的程序的语言,如果用改选项,gcc就不再使用文件的后缀判断语言类型。
     -v选项可以输出gcc整个编译连接过程的输出信息,包括查找路径等信息。比如gcc -v hello.c(当然可以用gcc -v hello.c >& temp输出文件),除了生成a.out可执行文件外,还会输出大量额外信息,比如#include "..."和#include <...> 的搜索路径,LIBRARY_PATH(连接程序将在这些目录中寻找特殊的连接文件)的值。
    -D选项可以用来预定义宏,比如在命令行定义宏:gcc -Dmacro hello.c这个等同于在文件的开头定义宏,即#define maco,但是在命令行定义更灵活。例如,在源代码中有这些语句。

  #ifdef DEBUG 
  printf("this code is for debugging\n");
  #endif

如果编译时加上-DDEBUG选项,那么编译器就会把printf所在的行编译进目标代码,从而方便地跟踪该位置的某些程序状态。这样-DDEBUG就可以当作一个调试开关,编译时加上它就可以用来打印调试信息,发布时则可以通过去掉该编译选项把调试信息去掉。并且还可以定义值,比如gcc -DDEBUG=42 hello.c,这样在代码使用这个值,比如printf("this code is for debugging,%d\n",DEBUG);默认预定义的值为1。

    -Wall会打开有用的警告选项,检测编译的是加此选项。
    gcc默认的选项-o是不优化的,使用-O2,-Os可根据不同的运行平台分别对代码的执行速度和大小进行优化。
    -std=c99 指明使用标准 ISO C99 作为标准来编译程序。比如gcc -std=c99 hello.c。
    -Xlinker可用于静态库链接顺序问题。若gcc选项中有多个路径时,都是按指定路径的搜索顺序。

gcc与g++的关系

    gcc和g++都是GNU的一个编译驱动器,但两者有一些区别:
    后缀为.c的文件gcc把它当做c程序,g++当做c++程序,后缀为c++的两者都当做c++程序(即此时gcc也相当于预定义了宏__cplusplus)。对于cpp程序,无论gcc或者是g++编译阶段都是相同的,都是用的gcc进行编译,但是在链接阶段gcc不能自动和c++程序常使用库连接,而g++会自动连接这些库。比如用g++编译:g++ hello.cpp -o cpphello,而用gcc编译需要连接C++常用的标准库:gcc hello.cpp -lstdc++ -o cpphello,注意生成的可执行文件并不是完全相同的。

参考资料

http://wangcong.org/articles/learning-gcc.cn.html
http://www.yolinux.com/cgi-bin/man2html?cgi_command=gcc