写点什么

关于编译的重要概念总结

作者:timerring
  • 2023-04-03
    山东
  • 本文字数:3010 字

    阅读完需:约 10 分钟

回想初学编程的时候,大部分人都是从 C 语言开始学起的,除了一些常见的语法和思想,一些基础知识常常被人们忽略,如果没有及时地进行梳理,可能短时间内没有太大的影响,但是在日后碰到这些问题时仍旧一头雾水。例如 C 语言是一门编译型语言,编译型语言首先将源代码编译生成机器语言,再由机器运行机器码(二进制)。对于编译型语言,绕不过的就是编译器。


下面提出几个问题,不妨思考一下:


  • 什么是 GNU

  • 什么是 GCC / G++

  • 什么是 MinGW-w64

  • C++ 标准有哪些?主要区别是什么?

  • Makefile 是什么?cmake 是什么?


如果脑海中没有一个整体的概念框架的话,正如那张图,一个全副武装的骑士,虽然防护的很好,但是对于编译器的基础知识掌握的不牢,就像头盔上的一个缝隙,可能下一箭正中缝隙,败下阵来。


下面具体介绍这几个概念:

什么是 GNU

GNU 是一个计划或者叫运动。在这个旗帜下成立了 FSF,起草了 GPL 等。


GNU 操作系统是一种由自由软件构成的类 Unix 操作系统,该系统基于 Linux 内核,目标在于建立一个完全相容于 UNIX 的自由软件环境。


当时 Unix 系统开始收费和商业闭源了。针对这一现象,Richard Stallman 发起了 GNU 计划,模仿 Unix 的界面和使用方式,从头做一个开源的版本。他自己做了编辑器 Emacs 和编译器 GCC。接下来开发者实现了包括核心的 gcc 和 glibc。但是 GNU 系统缺少操作系统内核。原定的内核叫 HURD,一直完不成。同时 BSD(一种 UNIX 发行版)陷入版权纠纷,x86 平台开发暂停。这时 Linus 为了在 PC 上运行 Unix,在 Minix 的启发下,开发了 Linux。当然 Linux 只是一个系统内核,系统启动之后使用的仍然是 gcc 和 bash 等软件。Linus 在发布 Linux 的时候选择了 GPL,因此符合 GNU 的宗旨。也弥补了 GNU 在这方面的缺少,于是合在一起打包发布叫 GNU / Linux。然后省掉了前面部分,变成了 Linux 系统。实际上 Debian,RedHat 等 Linux 发行版中内核只占了很小一部分容量。


参考:https://www.gnu.org/gnu/gnu-linux-faq.html

什么是 GCC / G++

GCC(GNU 编译器套件):GNU Compiler Collection。可以编译 C、C++、JAVA、Fortran、Pascal、Object-C、Ada 等语言。

gcc / g++

gcc 是 GCC 中的 GNU C Compiler(C 编译器


g++是 GCC 中的 GNU C++ Compiler(C++编译器

编译的四个阶段

在具体的编译过程中,主要分为四个阶段:


  1. cpp(预处理器):c 语言 pre-proccessor。头文件展开,宏替换,注释去掉。hello.c 变成 hello.i

  2. ccl(编译器):c 语言 compile。C 文件变成汇编文件:hello.i 变成 hello.s

  3. as(汇编器):assembler。汇编文件变成可执行的二进制文件:hello.s 变成 hello.o

  4. ld(链接器):GNU Linker,loader。将函数库中相应的代码组合到目标文件中,汇编文件和系统库文件链接起来,生成在特定平台可执行的程序。


最早的操作系统中,是没有链接器的,由加载器 loader 进行工作,所以 ld 的命名由此而来。



gcc 调用了 C compiler,而 g++调用了 C++ compiler

gcc 和 g++的主要区别

  1. 对于 .c 和.cpp 文件,gcc 分别当做 c 和 cpp 文件编译(c 和 cpp 的语法强度是不一样的)

  2. 对于 .c 和.cpp 文件,g++则统一当做 cpp 文件编译

  3. 使用 g++编译文件时,g++会自动链接标准库 STL,而 gcc 不会自动链接 STL

  4. gcc 在编译 C 文件时,可使用的预定义宏是比较少的

  5. gcc 在编译 cpp 文件时/g++在编译 c 文件和 cpp 文件时(这时候 gcc 和 g++调用的都是 cpp 文件的编译器),会加入一些额外的宏。

  6. 在用 gcc 编译 c++文件时,为了能够使用 STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个


这里强推《深入理解计算机系统》,CSAPP 这本书上讲解的非常详细。

参考:GCC的gcc和g++区别 - samewang - 博客园

MinGW-w64

MinGW 的全称是:Minimalist GNU on Windows 。它实际上是将经典的开源 C 语言 编译器 GCC 移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。简单来说,MinGW 就是 GCC 的 Windows 版本。


MinGW-w64 与 MinGW 的区别在于 MinGW 只能编译生成 32 位可执行程序,而 MinGW-w64 则可以编译生成 64 位 或 32 位 可执行程序。目前,MinGW 现已被 MinGW-w64 所取代,且 MinGW 也早已停止了更新。


MinGW-w64 是开源软件,可以免费使用。使用 Windows 的 C 语言运行库,因此编译出的程序不需要第三方 DLL ,可以直接在 Windows 下运行。 那些著名的开源 IDE 实际只是将 MinGW-w64 封装了起来,使它拥有友好的图形化界面,简化了操作,但内部核心仍然是 MinGW-w64。

C++语言版本

C++是一门以 C 为基础发展而来的一门面向对象的高级程序设计语言,从 1983 年由 Bjarne Stroustrup 教授在贝尔实验室创立开始至今,已有 30 多个年头。C++从最初的 C with class,经历了从 C++98、C++ 03、C++ 11、C++ 14、C++17 再到 C++ 20 多次标准化改造,功能得到了极大的丰富,已经演变为一门集面向过程、面向对象、函数式、泛型和元编程等多种编程范式的复杂编程语言。


C++ 98

C++从最初的 C with Classes 新增了很多其他的特性,比如异常处理、模板、标准模板库(STL)、运行时异常处理(RTTI)与名字空间(Namespace)等。C++ 03 通常被认为是 98 的补丁。

C++ 11

C++引入了对象移动右值引用lamba 表达式(函数式编程)、编译时类型识别(auto)、别名模板以及很多新型关键词(如 nullptr、decltype、constexpr)等现代编程语言常具备的能力,让 C++与时俱进,开发效率得到了很大的提升。这些新的特性随着 C++11 标准的发布而被正式确立下来。C++ 11 版本也被称为现代 C++,而 C++ 98/03 版本也被称为传统 C++。此外还有 long long 的基本类型。新增容器 std::unordered_map/std::unordered_multimap、std::unordered_set/std::unordered_multiset 等。

C++ 14

C++14 引入了二进制文字常量、将类型推导从 Lambda 函数扩展到所有函数、变量模板以及数字分位符等。进一步补充优化 C++11。

C++ 17

到了 2017 年,C++迎来了 C++17 标准。此次对 C++的改进和扩增,让 C++变得更加容易接受和便于使用了。C++17 引入了许多新的特性,比如类模板参数推导、UTF-8 文字常量、fold 表达式、新类型以及新的库函数等。

C++ 20

C++20 的 Big Four(四大新特性:概念、范围、协程和模块)以及核心语言(包括一些新的运算符和指示符)。


参考文章:C++版本发展史_c++历史版本_蓬莱道人的博客-CSDN博客

Makefile

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile 定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile 就像一个 Shell 脚本一样,也可以执行操作系统的命令。


make 是一个命令工具,它解释 Makefile 中的指令。在 Makefile 文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像 C 语言有自己的格式、关键字和函数一样。而且在 Makefile 中可以使用系统 shell 所提供的任何命令来完成想要的工作。Makefile 在绝大多数的 IDE 开发环境中都在使用,譬如 Visual C++的 nmake、linux 下的 GNU make、Qt 的 qmake 等等。

cmake

不同的 IDE 所集成的 make 工具所遵循的规范和标准都不同,也就导致其语法、格式不同,也就不能很好的跨平台编译,会使得工作繁琐。那么 cmake 为了解决这个问题而诞生了,其允许开发者指定整个工程的编译流程,在根据编译平台,生成本地化的 Makefile 和工程文件,最后用户只需 make 编译即可。简而言之,可以把 cmake 看成一款自动生成 Makefile 的工具,所以编译流程就变成了:cmake—>make–>用户代码–>可执行文件



发布于: 刚刚阅读数: 3
用户头像

timerring

关注

公众号【AIShareLab】 2022-07-14 加入

他日若遂凌云志

评论

发布
暂无评论
关于编译的重要概念总结_编译器_timerring_InfoQ写作社区