Only because people aren't putting in the effort to build their binaries properly. You need to link against the oldest glibc version that has all the symbols you need, and then your binary will actually work everywhere(*).
* Except for non-glibc distributions of course.
If it requires effort to be correct, that's a bad design.
Why doesn't the glibc use the version tag to do the appropriate mapping?
I don’t understand why this is the case, and would like to understand. If I want only functions f1 and f2 which were introduced in glibc versions v1 and v2, why do I have to build with v2 rather than v3? Shouldn’t the symbols be named something like glibc_v1_f1 and glibc_v2_f2 regardless of whether you’re compiling against glibc v2 or glibc v3? If it is instead something like “compiling against vN uses symbols glibc_vN_f1 and glibc_vN_f2” combined with glibc v3 providing glibc_v1_f1, glibc_v2_f1, glibc_v3_f1, glibc_v2_f2 and glbc_v3_f2… why would it be that way?
> Only because people aren't putting in the effort to build their binaries properly.
Because Linux userland is an unmitigated clusterfuck of bad design that makes this really really really hard.
GCC/Clang and Glibc make it effectively impossible almost impossible to do this on their own. The only way you can actually do this is:
1. create a userland container from the past 2. use Zig which moved oceans and mountains to make it somewhat tractable
It's awful.
> You need to link against the oldest glibc version that has all the symbols you need
Or at least the oldest one made before glibc's latest backwards incompatible ABI break.
But to link against an old glibc version, you need to compile on an old distro, on a VM. And you'll have a rough time if some part of the build depends on a tool too new for your VM. It would be infinitely simpler if one could simply 'cross-compile' down to older symbol versions, but the tooling does not make this easy at all.