IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> GCC介绍 -> 正文阅读

[C++知识库]GCC介绍

编译过程

编译系统(compilation system):预处理器(pre-processor)、编译器(compiler)、汇编器(assembler)、链接器(linker)
编译系统
预处理阶段:处理字符#开头的命令,即:1)将头文件的内容插入程序文本中。2)宏定义替换。3)条件编译(#if #ifdef),不被编译的部分变为空行。4)删除注释

编译阶段:通过编译器将源程序翻译成汇编程序(assembly-language program)

汇编阶段:将汇编程序翻译成机器语言指令,并将其打包成可重定位目标程序(relocatable object program)

链接阶段:链接器将各个.o文件合并成可执行文件。链接器使得分离编译成为可能。在编写大型程序时,可将模块分小,由此达到独立修改和编译不同模块的目的:未被修改的模块不用重新编译,而只需将修改后的模块编译,重新链接即可。e.g. hello.c中的printf函数存在printf.o(已经单独预编译了的目标文件)中,链接器将其合并后得到可执行文件

GCC介绍

  • GCC:GNU Compiler Collection(GNU 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C等语言。

  • gcc是GCC中的GUN C Compiler(C 编译器)

  • g++是GCC中的GUN C++ Compiler(C++编译器)

早期 GCC 的全拼为 GNU C Compiler,即 GUN 计划诞生的 C 语言编译器,显然最初 GCC 的定位确实只用于编译 C 语言。但经过这些年不断的迭代,GCC 的功能得到了很大的扩展,它不仅可以用来编译 C 语言程序,还可以处理 C++、Go、Objective -C 等多种编译语言编写的程序。与此同时,由于之前的 GNU C Compiler 已经无法完美诠释 GCC 的含义,所以其英文全称被重新定义为 GNU Compiler Collection,即 GNU 编译器套件

在已编辑好 C 语言或者 C++ 代码的前提下,如何才能调用 GCC 编译器为我们编译程序呢?很简单,GCC 编译器已经为我们提供了调用它的接口,对于 C 语言或者 C++ 程序,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器

无论是 gcc 还是 g++, 他们的定位都是 driver.

driver 负责调用编译器(狭义), 把源码编译到汇编代码. 比如 C 语言的编译器(狭义)是 cc1, 而 C++ 语言的编译器(狭义)是 cc1plus。driver 再调用 as, 把汇编代码变成二进制代码. 最后调用 ld, 负责把二进制代码拼在一起.

gcc 和 g++ 的区别无非就是调用的编译器不同, 并且传递给链接器的参数不同.

具体而言:

g++:

  • g++ 会把 .c 文件当做是 C++ 语言 (在 .c 文件前后分别加上 -xc++-xnone, 强行变成 C++), 从而调用 cc1plus 进行编译.

  • g++ 遇到 .cpp 文件也会当做是 C++, 调用 cc1plus 进行编译.

  • g++ 还会默认告诉链接器, 让它链接上 C++ 标准库.

gcc:

  • gcc 会把 .c 文件当做是 C 语言. 从而调用 cc1 进行编译.

  • gcc 遇到 .cpp 文件, 会处理成 C++ 语言. 调用 cc1plus 进行编译.

  • gcc 默认不会链接上 C++ 标准库.

只要是 GCC 支持编译的程序代码,都可以使用 gcc 命令完成编译。可以这样理解,gcc 是 GCC 编译器的通用编译指令,因为根据程序文件的后缀名,gcc 指令可以自行判断出当前程序所用编程语言的类别

但如果使用 g++ 指令,则无论目标文件的后缀名是什么,该指令都一律按照编译 C++ 代码的方式编译该文件。也就是说,对于 .c 文件来说,gcc 指令以 C 语言代码对待,而 g++ 指令会以 C++ 代码对待。但对于 .cpp 文件来说,gcc 和 g++ 都会以 C++ 代码的方式编译。

值得注意的是,Apple公司曾经一直使用GCC作为官方的编译器。 但是由于GCC开发社区对Apple所提的需求,给予的优先级始终不高,甚至很多Apple的重要需求基本不做考虑。 于是,财大气粗的Apple一怒之下,决定放弃GCC,基于LLVM重新开发了编译工具Clang,支持 C、C++、Objective-C等语言。 因此,目前macOS上自带的默认gcc命令,实际上调用的是clang。 希望在macOS上使用GCC,需要自行安装

gcc所遵循的部分约定规则

.c为后缀的文件,C语言源代码文件;

.a为后缀的文件,是由目标文件构成的档案库文件;
.C或.cc或.cxx为后缀的文件,是C++源代码文件;

.h为后缀的文件,是程序所包含的头文件;

.i为后缀的文件,是已经预处理过的C源代码文件;

.ii为后缀的文件,是已经预处理过的C++源代码文件;

.m为后缀的文件,是Objective-C源代码文件;

.o为后缀的文件,是编译后的目标文件;

.s为后缀的文件,是汇编语言源代码文件;

.S为后缀的文件,是经过预编译的汇编语言源代码文件。

gcc编译优化参数

gcc提供了4级优化参数,分别是-O0-O1-O2-O3。 一般来说,数字越大,所包含的编译优化策略就越多。

  • -O0参数表示不使用任何优化策略,是gcc默认的优化参数。 因为没有使用任何优化策略,编译得到的机器码与程序源码高度对应,两者之间基本可以建立一一对应的关系。所以,-O0优化非常适合用于程序调试,并且通常和生成调试信息的参数-ggenerate debug information)配合使用。-g参数会在编译时给生成的二进制文件附加一些用于代码调试的信息,比如符号表和程序源码。
  • -O1会尽量采用一些不影响编译速度的优化策略,降低生成的二进制文件的大小,以及提高程序执行的速度。
  • -O2使用-O1中的所有优化策划,还会采用一些会降低编译速度的优化策略,以提高程序的执行速度。

gcc编译流程

此部分来源于这篇文章:https://zhuanlan.zhihu.com/p/342151242

使用gcc编译C/C++程序时,主要的编译流程如下,包含预处理编译汇编链接等四个步骤。 以输入C语言程序源码文件b.c为例,直接调用命令gcc b.c,将会完整执行以下流程,并生成对应的可执行二进制文件a.out。 注意,这里gcc默认输出就是固定的a.out(通过使用参数-o(output),可以指定输出文件的名称。 例如gcc b.c -o b.bin,将生成可执行文件b.bin,而不是默认的a.out)。 在GCC工具链中,汇编由工具as完成,链接则由工具ld完成。

      -E          -S          -c          
b.c ------> b.i ------> b.s ------> b.o ------> a.out
      gcc         gcc         as          ld

gcc使用以下指令,将会使其编译流程停止在对应位置:

  • -E,(prEprocessing),执行到预处理步骤之后,即处理C/C++源码中#开头的指令,包括宏展开以及#include头文件引入等等。 该指令默认不输出文件,可以使用-o指令输出约定后缀为*.i的文件。
  • -S,(aSsembly),(?这一步是将预处理后的代码编译成汇编代码,为什么不叫compilation?)执行到编译步骤之后,生成汇编文件,但不生成二进制机器码。 该指令默认的输出文件后缀为*.s
  • -c,(compilation),(?这一步为什么不叫assembly?)执行到汇编步骤之后,调用工具as,从汇编码生成二进制机器码,但不进行链接。 该指令默认的输出文件后缀为*.oobject)。
  • 不带以上参数调用gcc将会完整执行以上流程,即执行到到链接(linking)步骤之后。 链接步骤实际上调用链接工具ld来执行,会将源码生成的二进制文件,库文件,以及程序的启动部分进行组合,从而形成一个完整的二进制可执行文件。

一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。

链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件

Makefile

makefile关系到了整个工程的编译规则,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,我们不可能用gcc命令对每所有文件一个个进行编译,这就必须要编写一个名为Makefile的文件来告诉make如何编译和链接程序,所以Makefile就相当于是一个工程文件的编译规则,它描述了工程中文件之间的关系并提供用于更新每个文件的命令。它规定了工程中哪些文件需要编译,哪些文件不需要编译,哪些文件需要先编译,哪些文件需要后编译,那些文件需要重建等等。编译整个工程需要涉及到的,在 Makefile 中都可以进行描述。换句话说Makefile 可以使得我们的项目工程的编译变得自动化,不需要每次都手动输入一堆源文件和参数。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具

在工程中,可执行文件是从目标文件更新的,而目标文件又是通过编译源文件制成的。一旦存在合适的Makefile,则每次更改一些源文件时,都会使用make来执行所有必要的重新编译。

make相关命令:

  • make:根据Makefile文件编译源代码、连接、生成目标文件、可执行文件。

  • make clean:清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。

  • make install:将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。

  • make dist:产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。


  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-11 16:27:42  更:2021-07-11 16:28:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 19:35:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码