GCC编译器常见选项解释

一、简介

        GCC(GNU Compiler Collection,GNU编译器套件)是由GNU开发的编程语言译器。GNU编译器套件包括C、C++、 Objective-C、 Fortran、Java、Ada和Go语言前端,也包括了这些语言的库(如libstdc++,libgcj等。)下面直奔主题介绍gcc编译重要选项定义。
        GCC编译具有一条完整的编译链。gcc编译特殊指令:file 指令,显示文件的信息。ELF表示文件是linux里可执行文件,LSB表示小端模式。

二、编译过程

1 -Preprocessing预编译:扩展宏MACRO

2.-Compilation编译:从源文件到汇编语句

3.-Assembly汇编:从汇编语句到机器码

4.-Linking链接:从机器码到可执行文件

三、常见配置参数

1 -Wall和-W 警告信息

        一般在编译程序的时候会加上-Wall,表示所有警告都检测并输出警告信息;
-Wall 包含了下面其他选项内容;
-Wcomment:注释内容嵌套错误警告检测问题,例如:/*noused1, …/*noused2*/ …*/;
-Wformat:使用scanf和printf等函数的格式化字符与实际变量的类型不一致警告;
-Wunused:声明的变量未使用警告;
-Wimplicit :使用了未声明的函数警告;使用其他文件定义变量但是未include头文件;
-Wreturn-type:函数定义需要返回值,但是未return或者return后面未写数据;
        隐藏警告信息,即不一定有问题只是可能存在的警告信息;属于高阶用法,一般大型项目或者OPEN代码需要检测。
-W , -Wconversion , -Wshadow , -Wcast-qual ,-Write-strings, -Wtraditional

2.-D 宏定义

        GCC宏定义功能;-DTEST_MACRO,下面语句解释案例;
test.c文件

#include <stdio.h>
int main(void)
{
printf("Hello world!\r\n");
#ifdef TEST_MACRO
printf("TEST_MACRO\r\n");
#endif
return 0;
}

gcc编译:gcc -Wall test.c -o test
这样运行的结果:Hello world!
gcc编译:gcc -Wall -DTEST_MACRO test.c -o test
这样运行结果:Hello world! TEST_MACRO

gcc编译器自带的宏定义有很多,可以通过指令查看:gcc -dM /dev/null;
扩展,类似于在C和H文件夹中宏定义,gcc也可以定义带参数的宏定义,

        GCC宏定义功能;-DNUM=123,下面语句解释案例;

#include <stdio.h>
int main(void)
{
printf("Hello world!\r\n");
#ifdef TEST_MACRO
printf("NUM is =%d\r\n", NUM);
#endif
return 0;
}

gcc编译:gcc -Wall test.c -o test
这样运行的结果:编译报错,NUM未定义;
gcc编译:gcc -Wall -NUM=123 test.c -o test
这样运行结果:Hello world!
NUM is = 123

3.-save-temps 过程文件

        GCC编译过程中保存过程文件,包括:.i 预处理文件,-s 汇编处理问题, -o二进制机器码等。
例子:gcc -Wall -c -save-temps test.c
产生文件:test.i test.s test.o文件

4.-g 调试功能

        在目标文件生成的过程中添加可调试信息,类似于VS的DEBUG模式。机器码对应的源码位置(行号信息)合并到生成的可执行文件,在DEBUG模式下可以方便找到问题。GNU Debugger gdb是专门的调试工具,不仅能指示出问题代码行号,还能在在线调试过程中看到每一步的信息。
        保存方式是符号表(symbol table),可执行文件运行过程中可以找到符号表的信息,输出代码执行的行号和其他信息。
        如果程序意外退出,文件会产生core文件,即软件挂了后产生的遗留文件。
例子:gcc -Wall -g test.c

#include <stdio.h>
int function(int *p)
{
int y = *p;
return y;
}

int main(void)
{
int *p = 0;
return function(p);
return 0;
}

函数调用执行BUG,在function输入参数p是一个空指针,main调用返回值有错误。
编译:gcc -Wall -g test.c 编译通过生成test文件;
执行:segmentation fault 故障,这里没有产生care dumped文件因为没有对linux系统配置每个程序允许的core dumped文件,查看默认大小指令:ulimit -c 结果是0,表示不允许程序产生core dumped文件;配置linux的core dumped文件权限,输入:ulimit -c unlimited,表示产生core 文件不受限,可以正常使用该功能;
然后再次执行:segmentation fault (core dumped),报错并产生了core dumped文件。
该功能产生的core dumped文件可以帮组开发人员找到程序崩溃的位置,使用方法如下例子;core.2297是产生的core文件
gdb test.out core.2297
显示程序运行过程总崩溃的具体信息,gbd调试工具不在此介绍。

5.-o 编译优化

常见优化方式,-oLEVEL ,DEBUG模式下建议关闭代码优化。
-o0:表示不优化,DEBUG模式下的优化选择;
-o1:1级
-o2:2级 ,投产前优化方式;
-os:2.5级
-o3:3级最高优化 非常自信开发人员;
执行时间在linux中可以对比,使用:time shell指令;如下,
gcc -Wall -o0 test.c -o test1
gcc -Wall -o1 test.c -o test2
对比时间:time ./test1 , time ./test2

6.-funroll-loops 循环优化

GCC针对源代码中的循环语句进行优化,通过增加代码量来换取CPU执行时间,如果对代码存储控制不敏感但是对CPU执行效率要求很高的代码,可以使用该选项。

7.-lNAME 添加标准库

GCC支持许多通用标准库文件,使用-lNAME类似方式可以添加各类库用于编译过程。比如-lm是-libm.a库的简写方式。新版本的GCC里面自带了-lm库,不需要单独链接。GCC支持
库链接方法集:
gcc -Wall main.c /usr/lib/libm.a -o calc
等价于下面:
gcc -Wall main.c -lm -o calc

8.-v 冗长编译

GCC编译过程中,Verbose开关模式是关闭的,该功能主要显示编译过程中的详细信息。例子:gcc -v -Wall hello.c 。在定位编译错误的过程中非常有用。

9.-c 编译不生成只可执行文件

例子:gcc -Wall -c test.c ,产生.o文件名称与源文件相同,缺省规则。c表示comple。

10.-o 编译生成可执行文件

例子:gcc -Wall test.o main.o -o test ,产生可执行文件,gcc使用ld链接工具产生可执行文件。

11.-I 、-L 缺省文件搜索路径

GCC编译执行路径。C代码包含H文件不需要指定绝对路径,指定绝对路径对代码的移植比较困难,属于问题代码。使用编译器的指定路径选项,编译过程中只需要指定搜索头文件路径。
gcc -I(这里是大写字母I):表示指定头文件搜索路径
gcc -L(这里是大写字母L):表示指定库文件搜索路径

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章