【问题标题】:Build and bind against older libc version构建和绑定旧的 libc 版本
【发布时间】:2020-09-03 13:16:43
【问题描述】:

我的代码中有需要 libc 的依赖项。在 Ubuntu 20.04 (glibc 2.31) 上构建 (cargo build --release) 时,生成的可执行文件无法在 CentOS 7 (glibc 2.17) 上运行。它会抛出一个错误,说它需要 GLIBC 2.18。

在 CentOS 7 上构建相同代码时,生成的可执行文件可在 CentOS 7 和 Ubuntu 20.04 上运行。

有没有办法控制在 Ubuntu 20.04 上构建这个版本需要哪个 GLIBC 版本?

【问题讨论】:

标签: rust libc


【解决方案1】:

试试cross

全局安装:

cargo install cross

然后用它构建你的项目:

cross build --target x86_64-unknown-linux-gnu --release

cross 采用与cargo 相同的参数,但您必须明确指定目标。另外,构建目录总是target/{TARGET}/(debug|release),而不是target/(debug|release)

cross 使用为不同目标架构预构建的 docker 映像,但没有什么能阻止您对主机架构进行“交叉编译”。这些 docker 镜像中的 glibc 版本应该足够保守。如果不是,您可以随时将cross 配置为使用自定义图像。

【讨论】:

    【解决方案2】:

    如果您的项目不依赖任何本机库,那么最简单的方法可能是使用x86_64-unknown-linux-musl 目标。

    这个目标静态链接到MUSL Libc,而不是动态链接到系统的libc。因此,它会生成完全静态的二进制文件,可以在各种系统上运行。

    要安装这个目标:

    rustup target add x86_64-unknown-linux-musl
    

    使用此目标构建您的项目:

    cargo build --target x86_64-unknown-linux-musl
    

    更多详情请见the edition guide

    如果您使用任何非 rust 库,则变得更加困难,因为它们可能是动态链接的,并且可能又依赖于系统 libc。在这种情况下,您要么需要静态链接外部库(假设这是可能的,并且您使用的库将与 MUSL libc 一起使用),要么为您要定位的每个平台进行不同的构建。

    如果您最终不得不为每个平台进行不同的构建,那么 docker 容器将是实现这一目标的最简单方法。

    【讨论】:

    • 我想说这个答案缺少要使用的基本命令,但它导致了解决方案。它对我有用。
    • @Todd 这个答案是关于静态链接到 MUSL,即MIT licenced。 MUSL 不是 GLIBC。
    • @harmic 哦 - MUSL Libc 不同吗?这对我来说是个新闻。我得调查一下!
    【解决方案3】:

    通常,您需要在该操作系统上为给定操作系统构建二进制文件,或者至少在您打算支持的最旧操作系统上构建。

    glibc 使用符号版本控制来保留旧程序的行为,同时添加对新功能的支持。例如,较新版本的pthread_mutex_lock 可能支持锁省略,而旧版本则不支持。您看到此错误是因为当您链接 libc 时,如果未明确指定版本,则链接符号的默认版本,并且至少在一种情况下,您链接的版本来自 glibc 2.18。更改此设置需要重新编译 libstd(以及 libc crate,如果您正在使用它)并进行自定义更改以选择旧版本的符号,这是很多工作却收效甚微。

    如果您唯一的依赖项是 glibc,那么仅在 CentOS 7 上编译就足够了。但是,如果您依赖其他库,例如 OpenSSL,那么这些库就不能跨操作系统版本兼容,因为它们的 SONAME 不同,并且没有办法解决这个问题。这就是为什么您通常要为每个操作系统构建不同的二进制文件的原因。

    【讨论】:

    • 有趣。我认为 rust 构建独立于系统库。这不是我的依赖。一个简单的 hello world 应用程序仍然需要相同的 libc。好吧,我必须在旧操作系统上构建或使用 Andrey 提到的 build-anywhere。
    • 在大多数操作系统上,Rust 仍然使用标准的 C 工具(libc、pthread 等),并且可以与 C 库进行互操作(如果您选择使用它们)。
    猜你喜欢
    • 2015-07-22
    • 1970-01-01
    • 2021-06-03
    • 2012-07-09
    • 2021-05-22
    • 2018-12-19
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    相关资源
    最近更新 更多