我一直在一个古老的 Linux 发行版上尝试最新版本的 clang,使用系统提供的 gcc7 构建最新版本的 llvm 项目。这对我来说非常有用,并且我广泛使用生成的 clang 二进制文件来构建许多其他项目。
最近有人告诉我,这不是正确的过程 - 一旦使用 gcc 构建 clang,您就应该使用 clang 构建 clang 并将其用作编译器。
对于最终用户来说,以这种方式引导编译器有什么好处?引导版本与非引导版本有什么不同的工作方式吗?
一般来说,除了 速度,介于使用 GCC 编译的 Clang 和使用 Clang 编译的 Clang 之间。 只要两个编译器都正常工作,并且只要代码 正在编译(Clang的源代码)不依赖 未定义的行为 或者 实现定义的行为 两者之间是不同的,那么两者将以相同的方式运行 并产生相同的输出。 (实际上,编译器和 编译器有很多错误,但在实践中,这个练习是 极不可能透露其中任何一个,只要两者实际上 编译链接成功。)
可能存在速度差异,因为两个不同的代码生成器和 优化器正在使用中。如果其中一个编译器明显较旧, 那么它可能不知道更高版本的 CPU 型号,因此不会充分利用 充分利用所有可能的硬件功能。一个编译器可能 也只是有一个更好的优化器。显然,这取决于什么 开关被传递给编译器;特别是,如果
-O
(优化)开关仅传递给一个,那么可能会出现
巨大的速度差异。
有点有趣的是,幻灯片 高效构建 Clang/LLVM 作者:Tilmann Scheller 在 EuroLLVM 2015 上发表的关于编译时间的报告 (Clang 源代码)使用使用 Clang 或 GCC 构建的 Clang 时 以及各种优化开关。他报告(在幻灯片 11 上) 使用 GCC 编译 Clang 配置文件引导优化 比其他配置高出约 16%。与此同时,当铿锵 用普通的
-O3
与两者一起编译,结果的速度
编译器是无法区分的。但当然这是在测量时测量的
九年前编译一个程序,因此推断是微不足道的。
继续使用没有什么“不正确” 非引导编译器。例如,观察一下 Clang 的构建说明 不要提及使用输出再次重新编译它。
相比之下, GCC 的构建说明 do 说要这样做(事实上它的
make
默认情况下会这样做),但是
理由很弱:
建议使用bootstrapping,因为编译器将被更多地测试 完全并且还可以有更好的表现。
这个建议可以追溯到 GCC 开发的早期,当时 GCC 本身更值得怀疑(因此引导程序作为一种潜在的 对编译器的有价值的测试)和 Unix 供应商编译器相当 它们的优化质量各不相同。