rust是自举语言,为什么还需要GNU 和 MSVC?
1.什么是自举?
自举是指一种语言的编译器是由该语言本身编写的。
我们说Rust自举,意思是Rust 的编译器是用 Rust 本身编写的。
2.什么是GNU和MSVC?
GNU 和 MSVC 都是编译器工具链,它们提供一套工具和库,这些工具和库被用来构建、链接和调试应用程序。
GNU
:GNU 是一个自由软件项目,旨在开发一套完全自由的 Unix-like 操作系统,也就是 GNU 操作系统。GNU 编译器工具链主要包括 GCC(GNU Compiler Collection),其中包含了处理各种编程语言(如 C、C++、Java 等)的编译器。这个工具链主要用于 Unix-like 系统(如 Linux、macOS)的软件开发。
MSVC
:MSVC(Microsoft Visual C++)是 Microsoft 提供的一个编译器工具链,它是 Visual Studio IDE 的一部分。MSVC 提供了处理 C、C++ 和 C++/CLI 的编译器,并且包含了一套完整的 Windows 开发库。MSVC 主要用于在 Windows 系统下的软件开发。
3.Rust的编译过程
Rust 的编译过程是相当复杂的,涉及多个阶段和子系统。以下是一个简化的概述:
1.词法分析
:首先,Rust 源代码会被分解成一系列的标记,或称为 “tokens”(例如关键字、标识符、字面量、符号等)。这个阶段也被称为 “词法分析” 或 “tokenizing”。
2.语法分析
:接着,这些标记会被解析成一棵抽象语法树(AST)。在这个阶段,编译器会检查代码的语法,并确定如何将代码组织为表达式和语句。
3.语义分析
:然后,编译器会进行语义分析,包括类型检查、借用检查等,确保代码满足 Rust 的语言规则。
4.中间表示(MIR)
:接下来,编译器将 AST 转换为中间表示(MIR)。这是一个更简洁、更低级的表示,它使得后续的优化和分析步骤更容易进行。
5.优化
:在 MIR 阶段,编译器会执行一系列的优化,如移除死代码、简化表达式等。
6.代码生成
:然后,编译器将 MIR 转换为 LLVM 中间表示(LLVM IR)。这是一个更接近于机器代码的表示,可以被 LLVM 的后端用来生成各种平台的机器代码。
7.链接
:最后,编译器使用链接器将生成的所有机器代码以及相关的库链接成一个可执行文件。
4.为什么Rust需要GNU或MSVC?
1-6阶段
编译过程都是Rustc 实现,Rustc 将Rust 源代码编译成机器代码,但是生成的这些机器代码通常是分散在多个对象文件中的。为了将这些对象文件以及所依赖的库文件合并成一个单一的可执行文件,我们需要一个链接器,也就是7阶段
。
7阶段
Rust选择调用外部的链接器,可能是 GNU 或 MSVC ,具体取决于目标平台和环境。在这个阶段,所有的机器代码和库文件会被链接到一起,生成一个可执行文件。
5.不要重复造轮子
看到这里应该有读者会问,rustc为什么不自己实现7阶段链接
过程呢?
因为Rust编译器团队贯彻了"不重复造轮子"(Don’t reinvent the wheel)这一编程理念。
链接是编译过程中的一个关键步骤,它将各个编译产生的对象文件与库文件链接成一个可执行文件。然而,链接并不是一个简单的任务,它涉及到许多复杂的操作,包括符号解析、重定位、处理目标平台的二进制格式等。此外,链接器还需要处理各种操作系统和硬件的特定细节。
现有的链接工具,如 GNU 的 ld 或 MSVC 的 link.exe,已经有几十年的发展历史,它们在性能、可靠性、兼容性等方面都经过了深入的优化。它们是由专门的开发者团队维护的,这些开发者专注于处理链接中的复杂问题。
相比之下,Rust 项目的主要目标是开发和改进 Rust 语言和编译器,而不是重新实现一套链接器。如果 Rustc 自己实现链接,这将需要投入大量的开发资源,并且可能会导致在性能、兼容性等方面不如现有的链接工具。
因此,Rustc 选择调用外部的链接工具,以便专注于 Rust 语言和编译器的开发,并利用现有链接工具的优点。这种分工和合作的方式是软件开发中常见的模式,可以让每个项目都专注于自己最擅长的领域。