首页 > 代码库 > 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