Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I use rust 1.34 and 1.35. Currently it links to GLIBC_2.18.

How can I limit cargo build to link GLIBC up to version 2.14?

like image 980
Yixing Liu Avatar asked Sep 06 '25 09:09

Yixing Liu


1 Answers

Unfortunately, you can't. Not really, and not consistently. This is a problem with any binary that dynamically links to 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.

So what are some practical options?

  1. Compile Statically

By using MUSL instead of GLIBC we can compile statically.

To install the MUSL target with rustup (assuming x86_64 architecture):

$ 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

This is a common approach. By using an OS with an outdated, GLIBC the binary will have GLIBC symbols that are compatible with it.

  1. Use a Docker Container

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. View the Rust contianer's README for compilation instructions. The command below will compile a project using Rust 1.67 and GLIBC 2.28 (which comes with 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.

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:

$ 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)
like image 99
rburmorrison Avatar answered Sep 09 '25 04:09

rburmorrison