分类: LINUX
2015-08-28 12:40:06
原文地址:gcc及其选项详解 作者:zhenhuaqin
1.简介:
gcc是gnu旗舰产品,目前基本上就是和unix捆绑在一起分发的。这个东西功能强大,但是有多达上千个选项,其用户手册也有将近一万行.虽然其中的多数选项平时很少用到.但是不管装软件还是写程序,往往都会用到gcc.下面我就gcc最最常用的几个选项做一个简要的说明,如果你想对gcc有一个全面的了解,比如你想知道在其他非x86平台上gcc是如何工作的话,你可以用命令:man gcc;
gcc [-c|-S|-E] [-std=standard]
[-g] [-pg] [-Olevel]
[-Wwarn...] [-pedantic]
[-Idir...] [-Ldir...]
[-Dmacro[=defn]...] [-Umacro]
[-foption...] [-mmachine-option...]
[-o outfile] infile...
-c 编译为目标文件,不连接库
-S 编译为汇编代码
-E 预处理.预处理之后的代码将送往标准输出
-Wwarn... 设置警告,可以设置的警告开关很多,通常用-Wall开启所有的警告
-Olevel 设置优化级别,level可以是0,1,2,3或者s,默认-O0,即不进行优化。.
-Dname=definition... 在命令行上定义宏,有两种方式,-Dname或者-Dname=definition.在命令行上设置宏定义的目的主要是为了在调试的时候设定一些开关, 而在发布的时候再关闭或者打开这些开关即可,当然宏定义也用来对代码进行有选择地编译.另外也还有其他的一些作用.
-Uname 取消宏定义name,作用和上面的正好相反.
-Idir... 把dir加到头文件的搜索路径中,而且gcc会在搜索标准头文件之前先搜索dir.
-llibrary 在连接的时候搜索library库,库是一些archieve文件--其成员是目标文件.如果有文件引用library,library在命令行的位置应该在那个文件之后,因此,越底层的库越要放在后面.比如如果你要连接pcap库,那么你就需要使用-lpcap对源文件进行编译.
-Ldir... 把dir加到库文件的搜索路径中,而且gcc会在搜索标准库文件之前先搜索dir.
-pthread 通过pthreads库加入对多线程的支持,这为预处理和连接设置了标志.pthread是POSIX指定的标准线程库.
-std=standard 设置采用的标准,该选项是针对C语言的,比如-std=c99表示编译器遵循C99标准.该选项较少使用.而且有时反而会把你搞糊涂.
-o outfile 指定输出文件的文件名,默认为a.out
-mmachine-option... 指定所用的平台.
---------------------------------------------------------------------------------------
2.gcc常用选项总结
2.1 常规选项
1、没有任何选项:gcc helloworld.c
结果会在与helloworld.c相同的目录下产生一个a.out的可执行文件。
2、-o选项,指定输出文件名:gcc -o helloworld helloworld.c
-o意思是Output即需要指定输出的可执行文件的名称。这里的名称为helloworld。
3、-c选项,只编译,不汇编连接:gcc -c helloworld.c
-c意思就是Compile,产生一个叫helloworld.o的目标文件
4、-S选项,产生汇编源文件:gcc -S helloworld.c
-S意思就是aSsemble,产生一个叫helloworld.s的汇编源文件
5、-E选项,预处理C源文件:gcc -E helloworld.c
-E意思就是prEprocess。输出不是送到一个文件而是标准输出。当然可以对它进行重定向:
gcc -E helloworld.c > helloworld.txt
2.2 优化选项
1) -O选项,基本优化:gcc -O helloworld.c
-O意思就是Optimize,产生一个经过优化的叫作a.out的可执行文件。也可以同时使用-o选项,以指定输出文件名。如:
gcc -O -o test helloworld.c
即会产生一个叫test的经过优化的可执行文件。
2) -O2选项,最大优化:gcc -O2 helloworld.c
产生一个经过最大优化的叫作a.out的可执行文件。
2.3 调试选项
1) -g选项,产生供gdb调试用的可执行文件:gcc -g helloworld.c
产生一个叫作a.out的可执行文件,大小明显比只用-o选项编译汇编连接后的文件大。
2) -pg选项,产生供gprof剖析用的可执行文件:gcc -pg helloworld.c
产生一个叫作a.out的执行文件,大小明显比用-g选项后产生的文件还大。
------------------------------------------------------------------------------------
3. Gcc的错误类型及对策
Gcc编译器如果发现源程序中有错误,就无法继续进行,也无法生成最终的可执行文件。为了便于修改,gcc给出错误资讯,我们必须对这些错误资讯逐个进行分析、处理,并修改相应的语言,才能保证源代码的正确编译连接。gcc给出的错误资讯一般可以分为四大类,下面我们分别讨论其产生的原因和对策。
第一类∶C语法错误
错误资讯∶文件source.c中第n行有语法错误(syntex errror)。这种类型的错误,一般都是C语言的语法错误,应该仔细检查源代码文件中第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。有些情况下,一个很简单的语法错误,gcc会给出一大堆错误,我们最主要的是要保持清醒的头脑,不要被其吓倒,必要的时候再参考一下C语言的基本教材。
第二类∶头文件错误
错误资讯∶找不到头文件head.h(Can not find include file head.h)。这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。
第三类∶档案库错误
错误资讯∶连接程序找不到所需的函数库,例如∶
ld: -lm: No such file or directory
这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等,检查的方法是使用find命令在可能的目录中寻找相应的函数库名,确定档案库及目录的名称并修改程序中及编译选项中的名称。
第四类∶未定义符号
错误资讯∶有未定义的符号(Undefined symbol)。这类错误是在连接过程中出现的,可能有两种原因∶一是使用者自己定义的函数或者全局变量所在源代码文件,没有被编译、连接,或者干脆还没有定义,这需要使用者根据实际情况修改源程序,给出全局变量或者函数的定义体;二是未定义的符号是一个标准的库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,或者是该档案库的目录名称有问题,这时需要使用档案库维护命令ar检查我们需要的库函数到底位于哪一个函数库中,确定之后,修改gcc连接选项中的-l和-L项。
排除编译、连接过程中的错误,应该说这只是程序设计中最简单、最基本的一个步骤,可以说只是开了个头。这个过程中的错误,只是我们在使用C语言描述一个算法中所产生的错误,是比较容易排除的。我们写一个程序,到编译、连接通过为止,应该说刚刚开始,程序在运行过程中所出现的问题,是算法设计有问题,说得更玄点是对问题的认识和理解不够,还需要更加深入地测试、调试和修改。一个程序,稍为复杂的程序,往往要经过多次的编译、连接和测试、修改。