您的位置:首页 > 其它

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

2010-10-19 16:17 507 查看
参考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.so与libfoo.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 有 i386、i486、pentium 及 i686 等
-mieee-fp 使用 IEEE 标准进行浮点数的比较
-mno-ieee-fp 不使用 IEEE 标准进行浮点数的比较
-msoft-float 输出包含浮点库调用的目标代码
-mshort 把 int 类型作为 16 位处理,相当于 short int
-mrtd 强行将函数参数个数固定的函数用 ret NUM 返回,节省调用函数的一条指令
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: