为什么需要针对目标的标准库构建(主机)GCC?

Flo*_*Flo 8 c gcc gnu cross-compiling toolchain

我一直在研究构建跨工具链,并对 gcc 的编译和工作有一个一般性问题。

问题是关于官方 gcc 文档的摘录:

为了构建 GCC,将为其构建目标库的所有目标变体(而不仅仅是主机 C++ 编译器的变体)都必须存在 C 标准库和头文件。

为什么需要目标的标准库来构建(交叉)编译器本身?难道在主机上运行的(交叉)编译器不应该只需要构建主机的标准库,然后就能够编译目标的标准库吗?

我还在 crosstool-NG 的工具链构建方式上发现了这一点:

最终编译器需要 C 库,才能知道如何使用它,但是:构建 C 库需要编译器

这与上面所述一致,但我不明白为什么需要针对预构建的目标 C 库构建最终编译器,只是为了知道稍后如何使用它。主机编译器需要了解有关目标 C 库的哪些信息?在编译时将目标程序链接到目标的标准库不是链接器的工作吗?

And*_*nle -1

因为这是确保为目标平台创建工作编译器的唯一方法。创建一个不工作的编译器,将其分发到目标平台,然后发现毫无用处是没有意义的。

通常,只有在不存在未解析的符号的情况下,才能成功创建非共享对象可执行文件。

根据GCC 11.2“总体选项”文档

编译最多可以涉及四个阶段:预处理、正确编译、汇编和链接,始终按此顺序。GCC 能够预处理和编译多个文件,或者将其编译为多个汇编器输入文件,或者编译为一个汇编器输入文件;然后每个汇编器输入文件都会生成一个目标文件,链接将所有目标文件(新编译的目标文件和指定为输入的目标文件)组合成可执行文件。

所以最后一步是链接。GNU 链接器“ld”手册页指出:

通常,链接器将为每个报告的未解析符号生成一条错误消息,但该选项 --warn-unresolved-symbols可以将其更改为警告。

--error-unresolved-symbols 这将恢复链接器在报告未解析符号时生成错误的默认行为。

因此,默认情况下,当存在未解析的符号时链接会失败。

为什么?

因为如果存在未解析的符号,生成的可执行文件在运行时将无法工作。

确保没有未解析符号的唯一方法是在交叉编译时提供目标平台中所有必需的库,以便在链接新编译器可执行文件时可以解析所有符号。