简体   繁体   English

如何在 Rust 的 cargo build 中指定 GLIBC 版本?

[英]How can I specify the GLIBC version in cargo build for Rust?

I use rust 1.34 and 1.35.我使用 rust 1.34 和 1.35。 Currently it links to GLIBC_2.18 .目前它链接到GLIBC_2.18

How can I limit cargo build to link GLIBC up to version 2.14 ?我如何限制cargo build以将GLIBC链接到2.14版?

Unfortunately, you can't.不幸的是,你不能。 Not really, and not consistently.不是真的,也不是一贯的。 This is a problem with any binary that dynamically links to GLIBC.这是任何动态链接到 GLIBC 的二进制文件的问题。 You can try setting up multiple GLIBC versions and linking to one, or you can try patching the resulting binary , but it's inconsistent and impractical.您可以尝试设置多个 GLIBC 版本并链接到一个版本,或者您可以尝试修补生成的二进制文件,但这是不一致且不切实际的。

So what are some practical options?那么有哪些实用的选择呢?

  1. Compile Statically静态编译

By using MUSL instead of GLIBC we can compile statically.通过使用 MUSL 而不是 GLIBC,我们可以进行静态编译。

To install the MUSL target with rustup (assuming x86_64 architecture):使用rustup安装 MUSL 目标(假设 x86_64 架构):

$ rustup component add rust-std-x86_64-unknown-linux-musl

And to use it when compiling:并在编译时使用它:

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

This is the easiest method by far, but won't always work, especially when using native libraries, unless they can also be compiled statically.这是迄今为止最简单的方法,但并不总是有效,尤其是在使用本机库时,除非它们也可以静态编译。

  1. Make a VM That Has an Older Version制作具有旧版本的 VM

This is a common approach.这是一种常见的方法。 By using an OS with an outdated, GLIBC the binary will have GLIBC symbols that are compatible with it.通过使用具有过时 GLIBC 的操作系统,二进制文件将具有与其兼容的 GLIBC 符号。

  1. Use a Docker Container使用 Docker 容器

This is probably the most convenient method, in my opinion.在我看来,这可能是最方便的方法。 If you have Docker, you can just compile your project with a container that contains an old GLIBC.如果你有 Docker,你可以只用一个包含旧 GLIBC 的容器编译你的项目。 View the Rust contianer's README for compilation instructions.查看 Rust contianer 的自述文件以获取编译说明。 The command below will compile a project using Rust 1.67 and GLIBC 2.28 (which comes with buster):下面的命令将使用 Rust 1.67 和 GLIBC 2.28(带有 buster)编译一个项目:

$ docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/usr/src/myapp -w /usr/src/myapp rust:1.67-buster cargo build --release

I compiled this on Ubuntu 22.04 and tested it on Ubuntu 20.04.我在 Ubuntu 22.04 上编译了它,并在 Ubuntu 20.04 上测试了它。

To test further, I made sure the binary relied on another dynamic library (OpenSSL) and here's the result of ldd./mybinary after compiling with the Docker container:为了进一步测试,我确保二进制文件依赖于另一个动态库 (OpenSSL),这是使用 Docker 容器编译后ldd./mybinary的结果:

$ ldd ./mybinary 
    linux-vdso.so.1 (0x00007ffd98fdf000)
    libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007fe49e248000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe49e22d000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fe49e223000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe49e200000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe49e0b1000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe49e0ab000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe49deb7000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe49ea30000)

And this is what it looks like without the container:这是没有容器的样子:

$ ldd ./mybinary
    linux-vdso.so.1 (0x00007ffd5d7b7000)
    libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007fe85564c000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe85562c000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe855545000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe85531d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe855f98000)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM