GCC 和 g++ 是如何被引导的?

这件事已经困扰我一段时间了。GCC 和 g++ 如何自行编译?

我猜每个修订都是用以前构建的修订编译的。这是真的吗?如果是的话,这是否意味着最古老的g++和GCC版本是用汇编编写的呢?

23122 次浏览

GCC最古老的版本是使用另一个C编译器编译的,因为在编写它的时候有其他的C编译器。第一个C编译器(约1973年,IIRC)是用)时汇编或之前的B编程语言实现的,但无论如何B编译器都是用汇编编写的。类似地,第一个c++编译器(CPre/Cfront, 1979-1983)可能首先是用C实现的,然后用c++重写。

当你编译GCC或任何其他自托管编译器时,编译的完整顺序是:

  1. 使用现有的C编译器构建新版本的GCC
  2. 用刚刚构建的GCC重新构建新版本
  3. (可选)重复步骤2进行验证。

这个进程被称为引导。它测试编译器编译自身的能力,并确保生成的编译器是使用它自己实现的所有优化构建的。

编辑: Drew Dormann在评论中指出Bjarne Stroustrup对c++最早的实现的描述。它是用c++实现的,但由Stroustrup称之为“预处理器”的东西翻译。从c++到C;根据他的定义,这不是一个完整的编译器,但c++仍然是用C引导的。

如果你想在现代环境(x86 Linux)中复制GCC的引导过程,你可以使用引导程序项目开发的工具:

    我们可以从hex0汇编开始(在x86上它是357字节二进制) 以下两个命令的作用大致如下
    sed 's/[;#].*$//g' hex0_x86.hex0 | xxd -r -p > hex0
    chmod +x hex0
    
    < p >。它把等价于ASCII码的二进制程序转换成二进制代码,但是它

    基本上,hex0有等价的源代码,是一对一对应的

  • hex0可以用来构建一个稍微强大一些的hex1汇编 支持更多的特性(一个字符标签和计算偏移量)。

  • hex1可用于构建hex2(甚至更高级的汇编程序,支持多字符标签)。

  • hex2则可用于构建宏汇编程序(其中程序使用宏而不是十六进制操作码)。

  • 然后你可以使用这个宏汇编器来构建cc_x86,这是一个“C编译器”;汇编写的cc_x86只支持C的一个小子集,但这是一个令人印象深刻的开始。

  • 你可以使用cc_x86来构建M2-Planet(宏平台中立转译器),这是一个用C编写的C编译器,M2-Planet是自托管的,可以自己构建。

  • 然后你可以使用M2-Planet构建GNU Mes,这是一个小型的方案解释器。

  • mes可以用来运行mescc,这是一个用scheme编写的C编译器,与mes位于同一个存储库中。

  • mescc可以用来重建mes,也可以构建mes C库。

  • 然后mescc可以用来构建一个稍微打了补丁的微型C编译器

  • 然后你可以使用它来构建TCC 0.9.27的新版本。

  • GCC 4.0.4和musl C库可以用TCC 0.9.27构建。

  • 然后可以使用旧的GCC构建新的GCC。 例如GCC 4.0.4 ->GCC 4.7.4 ->现代GCC。< / p >

TL;博士:

hex0→hex1→hex2→M0→M2-Planet→Mes→Mescc→移行细胞癌→GCC。