Description
When rustc builds on a system with a recent glibc version, the binaries require a recent glibc version (2.18). When built on an old system however, they will only require glibc 2.3.
To reproduce we can use a simple hello world example, building e.g. on Ubuntu 18.04:
cargo new hello-world
cd hello-world
cargo build --release
Let's look at the required symbols, filtering out glibc 2.2 and 2.3:
$ readelf -Ws target/release/hello-world | grep GLIBC | grep -v GLIBC_2.[23]
11: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_thread_atexit_impl@GLIBC_2.18 (5)
47: 0000000000000000 0 FUNC GLOBAL DEFAULT UND memcpy@GLIBC_2.14 (12)
537: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_thread_atexit_impl@@GLIBC_2.18
644: 0000000000000000 0 FUNC GLOBAL DEFAULT UND memcpy@@GLIBC_2.14
We see that 2.14 and 2.18 seem to be used. We can confirm that those symbols are indeed required using a cent os 5 docker container:
$ docker run --rm -v $(pwd)/target:/root/target -it quay.io/pypa/manylinux1_x86_64 /root/target/release/hello-world
/root/target/release/hello-world: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /root/target/release/hello-world)
/root/target/release/hello-world: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /root/target/release/hello-world)
This happens even with cent os 7:
$ docker run --rm -it -v $(pwd):/io centos:7 /io/target/release/hello-world
/io/target/release/hello-world: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /io/target/release/hello-world)
When building inside the cent os 5 container on the other hand, none of the above symbols are used and the binary runs just fine in the container.
Why does this matter?
For my case, it's because I want to produce manylinux compliant libraries and binaries. manylinux is a policy defined by python designed to be compatible with virtual any used linux system, which requires that only symbols from glibc <= 2.5 are used. All packages in the python package index must follow that policy, even though the glibc part is currently not automatically enforced. This affects e.g. milksnake and pyo3. A newer requirement, called manylinux2010 is worked on, but it stills require glibc <= 2.12.
In general it means that you can't use any modern ci server to produce widely compatible linux-gnu binaries. You always have to build in some ancient docker container instead.
Versions
rustc -vV
:rustc 1.33.0-nightly (8e2063d02 2019-01-07)
cargo -V
:cargo 1.33.0-nightly (2cf1f5dda 2018-12-11)
- The quay.io/pypa/manylinux1_x86_64 docker container run cent os 5.11 (Final) with glibc 2.5
- The cent os 7 container is cent os 7.6.1810 with glibc 2.17
This issue a bit of a follow-up to #36826.