【问题标题】:Using Nix to package CentOS5 toolchain dependencies使用 Nix 打包 CentOS5 工具链依赖
【发布时间】:2019-03-20 23:43:12
【问题描述】:

我们目前正在调查 Nix 是否可以成为我们打包构建软件所需的第三方库和工具的合适工具。免责声明:我刚刚了解了 Nix,但仍在尝试将所有部分放在一起。

我们的产品需要 ABI 兼容 CentOS5 系统。这就是为什么我们在 CentOS5 Docker 容器中构建我们的软件,使用自定义构建的 GCC,以及许多其他第三方工具和库,它们都是从源代码构建的。

目前,我们有一个大的 Makefile 来构建所有这些依赖项,并使用 CI 作业来构建依赖项。每当其中一个依赖项发生变化,或者对 Makefile 进行一些更改时,我们都会重新构建所有依赖项,这需要很长时间。

我们没有改进 Makefile,而是寻找更容易维护的更简单的解决方案。我认为 Nix 可能能够通过将 Makefile 转换为具有每个派生指定的正确依赖项的单独派生来帮助我们处理这个问题。 Nix 是否适合这个用例?我看到的主要问题是 Nix 使用现代 glibc 库作为基础派生,我们不能依赖它。我们是否需要构建一个自定义的 glibc 版本,或者我们能否以某种方式依赖安装在主机系统(CentOS5 系统)上的 glibc?

【问题讨论】:

    标签: nix


    【解决方案1】:

    这看起来像是 Nix 可以帮助您的场景。

    我们的产品需要 ABI 兼容 CentOS5 系统。

    由 Nix(通过 Nixpkgs)构建的二进制文件和库不链接到系统库。实际上,这类似于静态链接,但通过不同的方式实现,例如rpath 和包装脚本。这应该使您的产品 ABI 与任何发行版兼容,除非您的程序明确需要某些操作系统功能而不是普通库。例如,如果您的程序依赖于 GPU 驱动程序,那可能仍然是一个挑战。

    使用定制的 GCC

    Nixpkgs 可以使用您的自定义 GCC 构建所有包或仅选择一个包。

    每个派生都指定正确的依赖关系。

    Nix 非常适合这项任务。我建议在启用沙盒功能的情况下进行构建。如果您没有运行 NixOS,则应将其安装在 multi-user mode 并启用沙盒。

    我看到的主要问题是 Nix 使用现代 glibc 库作为基础派生,我们不能依赖它。

    使用 Nix 构建时,您的产品将忽略系统 glibc。提供您自己的 glibc 是可行的,但我认为您并不真正需要它,因为您正在从源代码构建所有内容,并且与主机系统的兼容性不是问题。

    或者我们能否以某种方式依赖安装在主机系统(CentOS5 系统)上的 glibc?

    这是出于必要而在 Mac OS X 系统上采用的方法。这样做将被视为退后一步;您需要有充分的理由这样做。

    Nix 是否适合此用例?

    你应该试试。 Nix 至少可以为您提供以下保证:

    • 指定所有依赖项
    • 并行构建的推导同样正确
    • 每个构建都是干净的构建,即使重用早期构建的结果也是如此
    • 可重复性:如果它今天构建,它明天构建并且您可以在明天修改它
    • 完整的依赖关系:安装后不会遗漏任何依赖关系

    祝你好运,不要犹豫,提出问题。软件通常不喜欢被强迫做出正确的行为。


    并使用 CI 作业

    全面披露:我正在为 Nix 开发 CI 服务。

    【讨论】:

    • 您好罗伯特,感谢您的详尽回答。当您说“您的产品将忽略系统 glibc”时,这是否意味着我们需要将来自 Nix 的 glibc 与我们的产品一起打包? glibc 和其他库必须从 Nix 存储转移到单独的 lib 目录中,例如与该工具捆绑在一起。我认为这可能需要重写 ELF 标头?有一些规范的方法来解决这个问题吗?我很惊讶关于这个主题的文档很少。似乎大多数部署也包括 Nix 本身,在我们的例子中,这并不是一个真正的选择。
    • 我刚刚发现最新版本的 glibc 在运行时需要更新的内核。例如,来自 glibc 2.26 (sourceware.org/ml/libc-alpha/2017-08/msg00010.html) 的公告电子邮件:“在该内核支持的所有架构上,运行时都需要 Linux 内核 3.2 或更高版本。(这是对版本 2.25 的更改,仅适用于 x86-32 和 x86 -64.)”。由于 CentOS5 使用 2.6.18 IIRC,我认为将 Nix 附带的 glibc 与我们的应用程序捆绑在一起不是一个好主意...
    • 您好,我不知道 glibc 内核兼容性。下一个最佳选择是为 Nixpkgs 提供较旧的 glibc。我在以前的雇主那里写了一个派生,将 Nix 闭包变成了一个 RPM 包。当您没有依赖项与其他此类包冲突的风险时,这就足够了。如有必要,您可以为闭包中的每个派生构建一个 RPM 包,以使其超出单个已安装包的范围。
    • Robert,直接使用 RPM 的有趣想法,感谢您的建议。
    • 您可以以此技术为基础为每个派生生成 RPM 包:github.com/NixOS/nixpkgs/blob/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多