musl 的 GCC 包装器与 musl 的 cross-compiler 有何不同?

How does musl's GCC wrapper differ from musl's cross-compiler?

我正在尝试使用 musl 工具链编译各种程序,例如 MariaDB。也就是说,我不想在编译完成后对 glibc 或 GNU 的链接器有任何依赖。

到目前为止,我一直在使用 musl 的 GCC 包装器 musl-gcc 来编译东西。但是,对于像 MariaDB 这样的大型程序,我很难获得所有必要的库和 headers 以及符号链接或添加编译环境变量 .

我看到提到 building a cross-compiler targeting musl libc with additional documentation and code at this GitHub repo。来自 cross-compiler 的文档:

This gives you a full, relocatable musl-targeting toolchain, with C++ support and its own library paths you can install third-party libraries into.

听起来这对我有帮助,但我不确定这与 musl 的 GCC 包装器有何不同,据我所知,它只是改变了 GCC 查找库和 headers 等的位置

最终,我不确定这个 cross-compiler 与 GCC 包装器到底有何不同,以及它是否对我有用。当我可以符号链接到现有库并使用 GCC 包装器时,为什么我需要自己的库路径来安装 third-party 库? cross-compiler 是我应该编译东西的方式,尤其是更大的代码库吗?

包装器所做的只是删除默认库并包含路径并添加替换路径。否则,它依赖于 编译器对 ABI 的看法是否充分匹配认为它以 glibc (*-linux-gnu) 为目标的 GCC 与 musl (*-linux-musl) 一起工作目标。

一个完整的 GCC 工具链有许多“目标库”- linked 到输出程序中以提供编译器提供的一些功能的库。这包括 libgcc(软件乘法或除法、软件浮点等,根据目标架构是否需要这些东西,以及对异常处理的展开支持),libstd++(C++ 标准库),以及许多其他的东西,比如 libgomp(与 #pragma OMP ... 一起使用的 GNU OpenMP 运行时实现)。理论上,所有这些都可能依赖于 specific 目标 ABI,包括 libc,并且可能 link 来自 libc 的符号。实际上,在大多数情况下 libgcc 不会,只要基本类型定义和其他一些 ABI 匹配,就可以“安全地”重用不同的 libc。

对于对 libc 具有更复杂依赖性的其他库,通常不希望针对一个 libc 的构建可以与另一个不同的库一起工作。 musl libc 为使用 glibc-linked 库提供了某种程度的 ABI-compat,所以无论如何它们都可以工作,但您需要将它们复制到新的库路径。然而,GCC 的 C++ 标准库头文件似乎也对目标的 (libc) 系统头文件有一些严重的依赖性,并且当 glibc 的设置似乎不适用于 musl 时。可能有一些方法可以完成这项工作(即向包装器添加 C++ 支持),但究竟如何做到这一点是一个悬而未决的问题。

即使这可以奏效,但是,你越深入,就越有可能发现你宁愿拥有一个合适的 cross-compiler 工具链 知道 它的目标是 musl。现在这些很容易建造。但是如果你发现你也需要额外的第三方库,并且不想自己构建它们,那么使用 Docker 图像(或其他容器)和提供库的发行版可能更有意义二进制文件给你。