二进制包如何与主机系统隔离?

二进制包如何与主机系统隔离?

如何为 binutils、gcc 和其他软件包创建二进制软件包(rpm、deb 等),这些软件包根据主机系统上存在的内容链接到不同的库?

在 LFS 项目中,为了将新系统与主机隔离,通过为新系统使用不同的目标三元组来伪造交叉编译(这里)。这可以防止包链接到仅存在于主机系统上的库。但是,如果使用类似的方法来构建二进制包,那么这些包肯定会有与它们所构建的系统不同的目标三元组。

我读讨论构建主机隔离的 gcc 的电子邮件通信。但得出的结论是,像 LFS 这样的伪造交叉编译是构建与主机系统隔离的 gcc 的唯一合理方法。

我尝试使用 --prefix 和 --with-sysroot 设置为空目录来构建 binutils,但生成的二进制文件链接到我的主机系统上的 libfl。

编辑:

我认为我原来的解释不清楚。请允许我举一个更具体的例子:

GNU 的 binutils不依赖于 GNU flex,我可以通过ldd /usr/bin/ar在我的 arch 系统上运行来验证这一点,我发现它没有链接到libfl.so.尽管如此,我的主机系统上仍然安装了 Flex。现在,我想编译一个 binutils 二进制文件,并将其复制到具有相同架构的另一个系统。这个新系统没有安装 GNU Flex,但这应该不重要,因为 binutils 不依赖于 GNU Flex。问题是,当我在主机系统上编译 binutils 时,它链接到libfl.so.2!我认为这是因为当我构建 binuitls 时,它“注意到”我安装了 flex,所以决定链接到它。我想知道如何编译软件(如 binutils)而不链接到主机系统上存在的可选依赖项(如 flex)。当二进制包维护者尝试编译他们的软件时,他们肯定会遇到同样的问题吗?

Binutils 只是这种情况下的一个例子,我真的在寻找一种更通用的方法,包维护者可以使用它来停止其软件链接到主机系统中的可选依赖项。

答案1

我可能是错的,但我认为答案(通常)是它们没有与主机系统隔离。

如何为 binutils、gcc 和其他软件包创建二进制软件包(rpm、deb 等),这些软件包根据主机系统上存在的内容链接到不同的库?

他们不这样做。 rpm、deb 等指定依赖关系,包括版本,并且针对不同的架构有不同的 RPM。换句话说,rpm 和 deb 是基于目标系统看起来都很相似的想法。

目标系统和构建系统看起来相同吗?我不是软件包维护者,所以可能有一些我不知道的魔法。我的理解是,这是通过构建与目标系统相同类型的系统来实现的。至少构建环境会是一些chroot就像目标环境一样布置。


LFS 有一个微妙之处,我认为当我读到它时(15 年前),他们并没有指出这一点。在 LFS 中,您一开始没有任何系统,因此您需要一些工具并开始构建系统的基本块。但你必须从外部向内看,否则就会遇到先有鸡还是先有蛋的问题。最初没有系统,您无法在系统内部进行构建。

我不认为他们在 LFS 中真正强调的是,一旦安装了系统,您就不需要从外部向内编译软件包。您可以使用该系统来构建自己的软件包。如果您打算使用它们来替换该系统本身的某些部分,或者如果您打算使用它们分发到其他类似的系统,那么这都有效。

最初,这是一个有点令人抓狂的概念。就像用 C 语言编写 C 编译器一样。首先用别人的 C 编译器编译你的 C 编译器,然后用你的 C 编译器重新编译你的 C 编译器。然后你可以扔掉从别人那里得到的。

答案2

在基于 rpm 的世界中,我们使用嘲笑构建工具。 Mock 使用 systemd-nspawn 容器创建一个隔离的环境。它仅安装最小的依赖项集,并且构建是在容器中完成的。因此它与宿主环境完全隔离。事实上,构建环境甚至可以有不同的架构

相关内容