GCC详解-gcc

1、背景

1.1 gcc介绍

如上一篇介绍的,gcc执行编译程序和连接程序以产生需要的输出;而g++是gcc 的一个版木,默认语言设置为 C++,而且在连接的时候自动包含标准 C++ 库。

所以,简单来讲,我们可以使用gcc将代码,编译成可以执行的程序。以C/C++为例,我们可以总结下gcc能做如下的事情:

  • 输出预处理后的C/C++源程序(展开头文件和替换宏)
  • 输出C/C++源程序的汇编代码
  • 输出二进制目标文件
  • 生成静态库
  • 生成可执行程序
  • 转换文件格式

1.2 gcc编译过程

如图所示,gcc的编译过程可以分为4个阶段:
预处理(Pre-Processing)
编译(Compiling)
汇编(Assembling)
链接(Linking)

 2、gcc的各个参数选项总结

gcc的基本语法是:

gcc [options] [filenames]

具体选项有很多,可以详细查看其官方文档。我们总结一下常用的选项用法。官方文档路径:https://gcc.gnu.org/onlinedocs/gcc/index.html#SEC_Contents

选项 介绍
-E 预编译后停下来,生成后缀为 .i 的预编译文件。
-S 汇编后停下来,生成后缀为 .s 的汇编源文件。
-c 编译后停下来,生成后缀为 .o 的目标文件。
-o filename     输出文件的名称为filename,默认a.out
-g 产生符号调试工具(GNU的 gdb)所必要的符号信息。想要对源代码进行调试,就必须加入这个选项。

-O

-O1

-O2

-O3

-O4

对程序进行优化编译、链接。采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是编译、链接的速度就相应地要慢一些,而且对执行文件的调试会产生一定的影响,造成一些执行效果与对应源文件代码不一致等一些令人“困惑”的情况。因此,一般在编译输出软件发行版时使用此选项。

编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高。

-Idirname 将 dirname 所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。(这里是大写的i)
-Ldirname 将dirname所指出的目录加入到程序函数库文件的目录列表中,是在链接过程中使用的参数。在默认状态下,链接程序 ld 在系统默认路径中(如 /usr/lib)寻找所需要的库文件。这个选项告诉链接程序,首先到 -L 指定的目录中去寻找,然后到系统默认路径中寻找;如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。
-lname 链接时装载名为 libname.a 的函数库。该函数库位于系统默认的目录或者由 -L 选项确定的目录下。(这里是小写的L)
-v 输出 gcc 工作的详细过程,打印编译过程中执行的命令
-w 禁止所有警告消息
-Wall

1) -Wall 使用它能够使 gcc 产生尽可能多的警告信息

2)-Wxxx指定某种错误的时候,产生警告

3)-Wno-xxx指定某种错误的时候,不产生警告

-Wextra 这会启用一些未由-Wall启用的额外警告标志。 (此选项过去称为-W ,旧名称仍然受支持,但更新的名称更具描述性。)
-Werror

 gcc 会在所有产生警告的地方停止编译,只有当相应的警告信息消除时,才可能将编译过程继续朝前推进。

1)-Werror 它要求 gcc 将所有的警告当成错误进行处理。

1)-Werror=xxx,指定某种警告出现时,报error

2)-Wno-error=xxx,指定某种警告出现时,不报error

-std= 指定c/c++的标准,具体可以参考下面的C、C++标准的表
-include 在编译时直接向目标代码中添加头文件,而不需要在代码中加入include语句
-D

-Dxxx    定义宏xxx

-Dxxx=aaa    定义宏xxx为aaa

-shared

进行动态库编译,链接动态库

1)生成动态库

gcc -shared -fPIC -o libtxxx.so xxx.c

2)链接动态库

gcc main.c libxxx.so -o a.out

或者

gcc main.c -lxxx -o a.out

-static

链接静态库,禁止使用动态库

1)生成静态库,用ar命令

2)使用静态库

gcc main.c -static -lxxx -o a.out

-fPIC(或fpic)

生成使用相对地址无关的目标代码

 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

--target-help 显示目前所用的gcc支持CPU类型
-Q 显示编译过程的统计数据和每一个函数名
-pedantic 当gcc在编译不符合ANSI/ISO C 语言标准的源代码时,将产生相应的警告信息。比如main函数返回值不是int,main函数实现没有返回值等。

2.1 C标准总结

标准 说明
-std=c90 or -std=iso9899:1990 C89或C90
-std=iso9899:199409 C94或C95
-std=c99 or -std=iso9899:1999. 1999年发布的 ISO/IEC 9899:1999,称为C99
-std=c11 or -std=iso9899:2011 C11
-std=gnu90 C90和GNU扩展
-std=gnu99 C99和GNU扩展
-std=gnu11 C11和GNU扩展

2.2 C++标准

标准 说明
-std=c++98, or -std=c++03 C++98
-std=c++11 C++11
-std=c++14 C++14
-std=c++17 or -std=c++1z C++17
-std=gnu++98 C++98和GNU扩展
-std=gnu++11 C++11和GNU扩展
-std=gnu++14 C++14和GNU扩展
-std=gnu++1z C++17和GNU扩展

3、参考

gcc官方说明文档:

https://gcc.gnu.org/onlinedocs/gcc/index.html#SEC_Contents

警告相关:

https://blog.csdn.net/qq_17308321/article/details/79979514

其他介绍:

https://blog.csdn.net/bit_clearoff/article/details/53965514

https://www.jianshu.com/p/1bab86143f1c

猜你喜欢

转载自blog.csdn.net/sjwangjinbao/article/details/118872969
gcc