GCC之旅(2)- 常用编译选项详解

来源:互联网 发布:2010人口普查全国数据 编辑:程序博客网 时间:2024/06/13 11:26

参考http://www.cublog.cn/u3/109488/showart_2138960.html

常用编译选项:

-o filename 把输出文件输出到 filename

-E只进行预编译,不做其他处理

-S 只是编译不汇编,生成汇编代码

-c 只是编译不链接,生成目标文件“.o”

-g 在可执行程序中包含标准调试信息,可以由GDB调用来调试

-v 打印出编译器内部编译各过程的命令行信息和编译器的版本

-I dir 在头文件的搜索路径列表中添加 dir 目录

-L dir 在库文件的搜索路径列表中添加 dir 目录

-static 链接静态库

-lname通过这个参数连接名为 libname.so 或者libname.a的库文件

-Dmarco 在编译时加入名为marco的宏

 

GCC常用格式

gcc [参数选项] 编译文件 [选项] [输出文件]

 

-E: 只进行预编译,不做其他处理

[root@localhost gccinfo]# gcc -E test.c -o test.i

 

-S: 只是编译不汇编,生成汇编代码

[root@localhost gccinfo]# gcc -S test.i -o test.s

 

-c:只是编译不链接,生成目标文件“.o”

[root@localhost gccinfo]# gcc -c test.s -o test.o

 

-g:在可执行程序中包含标准调试信息,可以由GDB调用来调试。

[root@localhost gccinfo]# gcc -g test.c -o test

那么可执行文件test将包含了标准的调试信息,可以由GDB调用来调试。

 

-v:打印出编译器内部编译各过程的命令行信息和编译器的版本

[root@localhost gccinfo]# gcc -v test.c -o test

 

-I dir:在头文件的搜索路径列表中添加 dir 目录

头文件路径:一般在编译文件的当前目录下寻找,如果没有则在/usr/include/下寻找。

在当前目录下查找的头文件一般用双引号引起,而用<>的头文件则在默认目录下查找。

  1 #include <stdio.h>     // 在标准路径中查找

  2 #include "myfun.h"    // 在本文件当前目录中查找,或者在-I指定的目录中查找

  3 int main(void)

  4 {      

  5         printf("Hello World!/n");

  6         return 0;

  7 }

通过-I+路径来指定,-I/usr/local/include/

[root@localhost gccinfo]# gcc test.c -I/usr/local/ -o test

 

-L dir: 在库文件的搜索路径列表中添加 dir 目录

-lname: 通过这个参数连接名为libname.so 或者libname.a的库文件。Linux下库的命名有一个规定,则必须要用lib开头,那么-l选项后的参数name则是函数库libxxxx去掉xxxx的名字,不包括后缀.so或者.a

函数库路径:一般在/usr/lib/,/lib/, /usr/local/lib下寻找。需要特别指定的可以用-L dir选项来制定路径。

假设有个名为libfoo.so文件在/tmp下,那么编译时应该:

[root@localhost gccinfo]# gcc test.c -L/tmp -lfoo -o test

库文件的后缀:.so 表示的动态库文件; .a表示的是静态库文件。GCC在默认情况下优先选择.so的动态库文件来连接。意思是如果有两个文件:libfoo.solibfoo.a/tmp目录下,当执行下面命令时:

[root@localhost gccinfo]# gcc test.c -L/tmp -lfoo -o test

编译器会自动连接libfoo.so这个文件。

 

-Dmarco:在编译时加入名为marco的宏

以文件ma.c来说明:

  1 #include <stdio.h>

  2

  3 int main(void)

  4 {

  5         #ifdef __DEBUG__

  6         printf("DEBUG/n");

  7         #endif

  8         printf("Hello World!/n");

  9         return 0;

 10 }

首先执行下面命令并观察结果:

[root@localhost gccinfo]# gcc ma.c -o ma

[root@localhost gccinfo]# ./ma

Hello World!

在观察带有-D选项的编译结果:

[root@localhost gccinfo]# gcc -D__DEBUG__ ma.c -o ma

[root@localhost gccinfo]# ./ma

DEBUG

Hello World!

对比可以知道-Dmarco相当于在编译的源文件中加上了一句#define marco

 

 

告警和出错选项:

-ansi 支持符合 ANSI 标准的 C 程序

-pedantic 允许发出 ANSI C 标准所列的全部警告信息

-pedantic-error 允许发出 ANSI C 标准所列的全部错误信息

-w 闭所有告警

-Wall 允许发出 Gcc 提供的所有有用的报警信息

-werror 把所有的告警信息转化为错误信息,并在告警发生时终止编译过程

 

现在已文件warning.c来说明

  1 #include <stdio.h>

  2 void main(void)

  3 {

  4         long long a=1;

  5         return 0;

  6 }

 

-ansi:该选项强制 GCC 生成标准语法所要求的告警信息,尽管这还并不能保证所有没有警告的程序都是符合 ANSI C 标准的。运行结果如下所示:

[root@localhost gccinfo]# gcc -ansi warning.c -o waring

warning.c: In function `main':

warning.c:5: warning: `return' with a value, in function returning void

warning.c:3: warning: return type of `main' is not `int'

可以看出,该选项并没有发现“long long”这个无效数据类型的错误。

 

-pedantic:允许发出ANSI C 标准所列的全部警告信息,同样也保证所有没有警告的程序都是符合ANSI C 标准的。其运行结果如下所示:

[root@localhost gccinfo]# gcc -pedantic warning.c -o waring

warning.c: In function `main':

warning.c:4: warning: ISO C90 does not support `long long'

warning.c:5: warning: `return' with a value, in function returning void

warning.c:3: warning: return type of `main' is not `int'

可以看出,使用该选项查看出了“long long”这个无效数据类型的错误。

 

-Wall 允许发出 Gcc 提供的所有有用的报警信息

[root@localhost gccinfo]# gcc -Wall warning.c -o waring

warning.c:2: warning: return type of `main' is not `int'

warning.c: In function `main':

warning.c:5: warning: `return' with a value, in function returning void

warning.c:4: warning: unused variable `a'

 

GCC编译器优化选项:

GCC 可以对代码进行优化,它通过编译选项“-On”来控制优化代码的生成,其中 n 是一个代表优化级别的整数。对于不同版本的 Gcc 来讲,n 的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从 0 变化到 2 3。不同的优化级别对应不同的优化处理工作。如使用优化选项“-O”主要进行线程跳转(Thread Jump)延迟退栈(Deferred Stack Pops)两种优化。使用优化选项“-O2”除了完成所有“-O1”级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项“-O3”则还包括循环展开和其他一些与处理器特性相关的优化工作。虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。所以笔者建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。

 

GCC体系结构相关选项:

-mcpu=type 针对不同的 CPU 使用相应的 CPU 指令。可选择的 type i386i486pentium i686

-mieee-fp 使用 IEEE 标准进行浮点数的比较

-mno-ieee-fp 不使用 IEEE 标准进行浮点数的比较

-msoft-float 输出包含浮点库调用的目标代码

-mshort int 类型作为 16 位处理,相当于 short int

-mrtd 强行将函数参数个数固定的函数用 ret NUM 返回,节省调用函数的一条指令