gcc与g++
# 一、gcc
- GNU Compiler Collection(GCC),GNU编译器集合(GCC)是用于编程的编译器集合,如 C、C++、Objective-C、Java 和 Fortran;
- GCC版本是通过一个通过命令行操作的自由软件基础来实现的;
- gcc 是 GCC 编译器的通用编译指令,只要是 GCC 支持编译的程序代码,都可以使用 gcc 命令完成编译。根据程序文件的后缀名,gcc 指令可以自行判断出当前程序所用编程语言的类别:
- xxx.c:默认以编译 C 语言程序的方式编译此文件;
- xxx.cpp:默认以编译 C++ 程序的方式编译此文件;
- xxx.m:默认以编译 Objective-C 程序的方式编译此文件;
- xxx.go:默认以编译 Go 语言程序的方式编译此文件;
- gcc 指令也为用户提供了 “手动指定代表编译方式” 的接口,即使用
-x
选项;gcc -xc xxx
表示以编译C 语言
代码的方式编译 xxx 文件;gcc -xc++ xxx
则表示以编译C++
代码的方式编译 xxx 文件;
# 二、g++
- GNU C++ Compiler(G++),GNU提供的C++的优化编译器,也就是众所周知的G++;
- 可以在各种处理器上运行,与GCC一样,G++包含独立的程序;
- g++ 主要用于编译C++编程语言,是不同操作系统(如Linux、BSD和MAC OS x)中的主编译器;
- 在编译阶段,G++调用GCC,因此G++是完整的编译器,而不是任何其他编译器的预处理器。这个编译器从源代码构建目标代码,它不生成程序的任何中间C版本;
- 如果使用 g++ 指令,则无论目标文件的后缀名是什么,该指令都一律按照编译 C++ 代码的方式编译该文件;
- 很多 C++ 程序都会调用某些标准库中现有的函数或者类对象,而单纯的 gcc 命令是无法自动链接这些标准库文件的;
- 使用 gcc 指令来编译执行 C++ 程序,需要在使用 gcc 指令时,手动为其添加
-lstdc++ -shared-libgcc
选项,表示 gcc 在编译 C++ 程序时可以链接必要的 C++ 标准库; g++
指令就等同于gcc -xc++ -lstdc++ -shared-libgcc
指令;
# 三、常用的编译选项
# 1,基本选项
选项 | 功能 |
---|---|
-E(大写) | 只预处理指定的源文件,不进行编译 |
-S(大写) | 只编译指定的源文件,但是不进行汇编 |
-c | 编译、汇编指定的源文件,但是不进行链接 |
-v | 显示详细的编译、汇编、连接命令 |
-o | 指定生成文件的文件名 |
-save-temps | 顾名思义,就是保留编译产生的所有中间文件 |
-std= | 手动指令编程语言所遵循的标准,例如 c++11、c++14 等 |
gcc 或者 g++ 指令,其底层依据是按照 预处理、编译、汇编、链接 的过程将 C 、C++ 程序转变为可执行程序的;
在预处理、编译、汇编阶段生成的中间文件,此执行方式默认是不会生成的,只会生成最终的 a.out 可执行文件;
可以通过-E, -S -c 或 -save-temps
指令生成中间文件;
# 2,目录选项
选项 | 功能 |
---|---|
-Idir | 查找头文件时,先到指定的 dir 目录查找,再到系统的默认的头文件目录查找 |
-I- | 就是取消前一个参数的功能,一般在 -Idir 之后使用 |
-idirafter dir | 在 -I 的目录里面查找失败, 再到这个目录里面查找 |
-iprefix prefix 、-iwithprefix dir | 一般一起使用, 当 -I 的目录查找失败, 会到 prefix+dir 下查找 |
-Ldir | 指定编译时搜索库的路径,不然编译器将只在标准库的目录找 |
-M | 生成文件依赖的信息,包含目标文件所依赖的所有源文件 |
-MD | 将输出的结果保存到一个.d文件中 |
-MM , -MMD | 同上,不过只考虑 #include"head_file" 指令,不会考虑 #include<head_file> 指令 |
# 3,链接选项
选项 | 功能 |
---|---|
-llibrary | 其中 library 表示要搜索的库文件的名称,用于手动指定链接环节中程序可以调用的库文件,如 -lstdc++ |
-static | 此选项将禁止使用动态库,编译出来的目标文件一般较大,不需要什么动态连接库就可以运行 |
-share | 此选项将尽量使用动态库,编译出来的目标文件比较小,运行时由系统提供动态库 |
-Wl,-Bstatic | 告诉链接器ld只链接静态库,如果只存在动态链接库,则链接器报错 |
-Wl,-Bdynamic | 告诉链接器ld优先使用动态链接库,如果只存在静态链接库,则使用静态链接库。 |
-Wa,option | 此选项传递 option 给汇编程序; 如果 option 中间有逗号, 就将 option 分成多个选项, 然后传递给会汇编程序。 |
-Wl,option | 此选项传递 option 给连接程序; 如果 option 中间有逗号, 就将 option 分成多个选项, 然后传递给会连接程序。 |
# 4,宏定义选项
选项 | 功能 |
---|---|
-Dmacro | 相当于 #define macro |
-Dmacro=defn | 定义宏,相当于 #define macro defn |
-Umacro | 取消宏定义,相当于 #undef macro |
-undef | 取消任何非标准宏的定义,C++标准预定义的宏仍然有效 |
# 5,调试选项
选项 | 功能 |
---|---|
-g | 编译器在编译的时候,产生调试信息 |
-gstabs | 此选项以 stabs 格式生成调试信息, 但是不包括 gdb 调试信息 |
-gstabs+ | 此选项以 stabs 格式生成调试信息, 并且包含仅供 gdb 使用的额外调试信息 |
-ggdb | 此选项将尽可能的生成 gdb 的可以使用的调试信息 |
# 6,告警选项
选项 | 功能 |
---|---|
-w | 编译时,不显示任何警告消息 |
-Wall | 编译时,显示所有出现的警告消息 |
-Werror | 要求GCC将所有的警告当成错误进行处理,在警告发生时中止编译过程。 |
# 7,其他选项
选项 | 功能 |
---|---|
-fPIC(Full PIC) | (position-independent code)要求编译器生成完全位置无关的代码。生成的目标文件可以在任何内存位置加载并执行,以便可以将目标文件在不同的地址空间中加载,适用于静态库的编译,这种选项生成的代码较大,但具有更好的移植性和可重用性 |
-fpic(Partial PIC) | 类似于-fPIC,但生成的代码相对更小,对移植性和可重用性也稍微弱一些,但是只需要保证生成的代码在同一进程内可用,不需要支持跨进程共享,这个选项适用于动态共享库的编译,因为共享库的代码相对较小,并且在加载时可以使用更多可用的地址空间 |
-fno-strict-aliasing | 禁用严格别名规则优化。它告诉编译器不要依赖严格别名规则进行优化,可以避免因别名规则优化而引发的问题。 |
-fomit-frame-pointer | 忽略函数调用时的帧指针。这个选项用于告诉编译器,可以省略函数调用时保存和恢复栈帧指针的操作,以节省额外的指令和寄存器。 |
-finline-functions | 启用内联函数。编译器会尝试将函数调用处直接替换为函数体的代码,以减少函数调用的开销。 |
-fno-stack-protector | 禁用堆栈保护。这个选项用于禁用编译器在函数中自动生成的堆栈保护代码,以减少生成的代码大小和执行开销。 |
-fsanitize=address | 启用地址检测工具。这个选项用于在编译和运行时检测内存访问错误,例如使用未初始化的内存或越界访问。 |
-funsigned-char | 将程序中的char解析为unsigned char |
-fno-signed-char | 将程序中的char解析为非signed char |
-fsigned-char | 将程序中的char解析为signed char |
-fno-unsigned-char | 将程序中的char解析为非unsigned char |
-ansi | 使用ANSI 标准,禁止GNU 标准特性,如 asm inline typeof 关键字,以及UNIX、vax等预处理宏。 |
-O0,-O1,-O2,-O3 | 英文单词Optimize的第一个字母O(意为:优化),编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高,优化的是生成的程序的大小和程序的执行速度 |
编辑 (opens new window)
上次更新: 2023/09/03, 12:32:21