C/C++之Gcc常用参数

gcc是GNU旗舰产品,目前基本上就是和Unix捆绑在一起分发的。这个东西功能强大,有多达上千个选项,其用户手册也有将近一万行。虽然其中的多数选项平时很少用到,但是不管装软件还是写程序,往往都会用到gcc。下面我就gcc最最常用的几个选项做一个简要的说明。

Gcc指令的一般格式为: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... 指定所用的平台。

C/C++之Gcc常用参数_第1张图片

Linux下常见文件扩展名

1、没有任何选项:gcc hello.c

结果会在与hello.c相同的目录下产生一个a.out的可执行文件。

2、-o选项,指定输出文件名:gcc -o hello hello.c

-o意思是Output即需要指定输出的可执行文件的名称。这里的名称为helloworld。

3、-c选项,只编译,不汇编连接:gcc -c hello.c

-c意思就是Compile,产生一个叫hello.o的目标文件

4、-S选项,产生汇编源文件:gcc -S hello.c

-S意思就是aSsemble,产生一个叫hello.s的汇编源文件

5、-E选项,预处理C源文件:gcc -E hello.c

-E意思就是prEprocess。输出不是送到一个文件而是标准输出。当然可以对它进行重定向:gcc -E hello.c > helloworld.txt或者gcc –E hello.c –o hello.i

6.1、-O选项,基本优化:gcc -O hello.c

-O意思就是Optimize,产生一个经过优化的叫作a.out的可执行文件。也可以同时使用-o选项,以指定输出文件名。如:gcc -O -o test hello.c

6.2、-O2选项,最大优化:gcc -O2 hello.c

产生一个经过最大优化的叫作a.out的可执行文件。

7、-g选项,产生供gdb调试用的可执行文件:gcc -g helloworld.c

产生一个叫作a.out的可执行文件,大小明显比只用-o选项编译汇编连接后的文件大。

8、-pg选项,产生供gprof剖析用的可执行文件:gcc -pg helloworld.c

产生一个叫作a.out的执行文件,大小明显比用-g选项后产生的文件还大。

gcc编译器的工作过程

Gcc的编译流程分为了4个步骤,分别为:

  • 预处理(Pre-Processing)
  • 编译(Compiling)
  • 汇编(Assembling)
  • 链接(Linking)。

预处理:gcc -E hello.c -o hello.i

 

编译:gcc -S hello.i -o hello.s

gcc 编译阶段首先要检查代码的规范性,是否有语法错误等。以确定代码实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。用户可以使用-S 选项进行查看,该选项只进

汇编:gcc -c hello.s -o hello.o

gcc 汇编阶段:生成目标代码 *.o ;有两种方式:使用 gcc 直接从源代码生成目标代码 gcc -c *.s -o *.o 以及使用汇编器从汇编代码生成目标代码 as *.s -o *.o

链接:gcc hello.o -o hello

gcc 链接阶段:生成可执行文件

也可以直接使用as *.s, 将执行汇编、链接过程生成可执行文件a.out, 可以像上面使用-o 选项指定输出文件的格式。

 

Gcc的错误类型及对策

Gcc编译器如果发现源程序中有错误,就无法继续进行,也无法生成最终的可执行文件。为了便于修改,gcc给出错误资讯,我们必须对这些错误资讯逐个进行分析、处理,并修改相应的语言,才能保证源代码的正确编译连接。gcc给出的错误资讯一般可以分为四大类,下面我们分别讨论其产生的原因和对策。

第一类∶C语法错误

error∶文件source.c中第n行有语法错误(syntex errror)。

这种类型的错误,一般都是C语言的语法错误,应该仔细检查源代码文件中第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。有些情况下,一个很简单的语法错误,gcc会给出一大堆错误。

第二类∶头文件错误

error∶找不到头文件head.h(Can not find include file head.h)。

这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。

第三类∶档案库错误

error∶连接程序找不到所需的函数库,例如∶ ld: -lm: No such file or directory

这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等,检查的方法是使用find命令在可能的目录中寻找相应的函数库名,确定档案库及目录的名称并修改程序中及编译选项中的名称。

第四类∶未定义符号

error∶有未定义的符号(Undefined symbol)。

这类错误是在连接过程中出现的,可能有两种原因∶一是使用者自己定义的函数或者全局变量所在源代码文件,没有被编译、连接,或者干脆还没有定义,这需要使用者根据实际情况修改源程序,给出全局变量或者函数的定义体;二是未定义的符号是一个标准的库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,或者是该档案库的目录名称有问题,这时需要使用档案库维护命令ar检查我们需要的库函数到底位于哪一个函数库中,确定之后,修改gcc连接选项中的-l和-L项。

 

你可能感兴趣的:(C/C++)