I don’t understand why a binaries built on 21.10 isn’t compatible with an older version of the OS.
The binary is linked against
libc.so.6 which is available on the 21.04 OS version as well.
We can find the same binary, on the 21.10 system:
$ ldd turboledzd linux-vdso.so.1 (0x00007ffdc2595000) libhidapi-hidraw.so.0 => /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0 (0x00007fdd64057000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdd63e2f000) libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007fdd63e06000) /lib64/ld-linux-x86-64.so.2 (0x00007fdd64085000)
And on the 21.04 system:
$ ldd turboledzd ./turboledzd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./turboledzd) linux-vdso.so.1 (0x00007fff9c570000) libhidapi-hidraw.so.0 => /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0 (0x00007f37ec402000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f37ec216000) libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007f37ec1ed000) /lib64/ld-linux-x86-64.so.2 (0x00007f37ec423000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f37ec1cb000)
libc.so.6 from 21.04 is not compatible with
libc.so.6 from 21.10, then why isn’t the libc on 21.10 called
Or, better, why is it not linked against something called
libglibc.so.2.34 – if that is a dependency?
Ubuntu is one of the most popular Linux distributions available today. It is known for its user-friendly interface and ease of use. Ubuntu 21.10 is the latest version of the operating system, and it comes with several new features and improvements. However, some users have reported that the binaries built on Ubuntu 21.10 are not compatible with the Ubuntu 21.04 install. In this blog post, we will explore why this is the case and what can be done to resolve the issue.
Understanding Binaries and Libraries
Before we dive into the issue, let’s first understand what binaries and libraries are. A binary file is an executable file that can be run on a specific operating system. It contains machine code that the processor can execute to perform a specific task. On the other hand, a library is a collection of precompiled code that can be used by other programs. Libraries contain functions and procedures that can be called by other programs to perform specific tasks.
Why Binaries Built on Ubuntu 21.10 are not Compatible with Ubuntu 21.04 Install?
The reason why binaries built on Ubuntu 21.10 are not compatible with Ubuntu 21.04 install is due to the version of the C library used in both operating systems. The C library, also known as libc, is a fundamental component of the operating system that provides essential functions required by other programs. When a binary is built, it is linked with the version of the C library available on the system during the build process.
Ubuntu 21.10 comes with a newer version of the C library (libc.so.6) than Ubuntu 21.04. The newer version of the C library contains additional features and bug fixes that are not available in the older version. When a binary is built on Ubuntu 21.10, it is linked with the newer version of the C library. However, when this binary is run on Ubuntu 21.04, it cannot find the newer version of the C library and fails to run.
Why isn’t the libc on Ubuntu 21.10 called libc.so.7 instead?
This is a common question that arises when discussing the issue of compatibility between different versions of the C library. The reason why the libc on Ubuntu 21.10 is not called libc.so.7 instead is that the version number of the C library is not related to the compatibility between different versions. The version number of the C library is used to indicate the level of compatibility between different releases of the same distribution.
For example, Ubuntu 21.10 comes with libc.so.6, and Ubuntu 21.04 comes with libc.so.6. The fact that both versions have the same version number indicates that they are compatible with each other. However, if Ubuntu 21.10 came with a new version of the C library with a different version number, it would not be compatible with Ubuntu 21.04.
Why is it not linked against something called libglibc.so.2.34?
Another common question that arises is why the binary is not linked against something called libglibc.so.2.34. The reason for this is that libglibc.so.2.34 does not exist as a separate library. libglibc.so is the actual name of the C library, and the version number is appended to the end of the name. Therefore, the C library on Ubuntu 21.10 is called libc.so.6, and the version number is 2.34.
When a binary is built, it is linked against the actual name of the C library, which is libc.so.6. The version number is appended to the end of the name, indicating the version of the C library that the binary is linked against. Therefore, when a binary is built on Ubuntu 21.10, it is linked against libc.so.6, and the version number is 2.34.
Resolving the Compatibility Issue
Now that we understand why binaries built on Ubuntu 21.10 are not compatible with Ubuntu 21.04 install let’s discuss how to resolve the issue. The easiest way to resolve the compatibility issue is to rebuild the binary on Ubuntu 21.04. When the binary is rebuilt on Ubuntu 21.04, it is linked against the version of the C library available on Ubuntu 21.04, making it compatible with the operating system.
Another way to resolve the compatibility issue is to install the newer version of the C library on Ubuntu 21.04. This can be done by installing the libc6 package from the Ubuntu 21.10 repository. However, this method is not recommended, as it can cause compatibility issues with other programs that are linked with the older version of the C library.
In conclusion, the reason why binaries built on Ubuntu 21.10 are not compatible with Ubuntu 21.04 install is due to the version of the C library used in both operating systems. The newer version of the C library on Ubuntu 21.10 is not available on Ubuntu 21.04, causing the binary to fail. To resolve the compatibility issue, the binary can be rebuilt on Ubuntu 21.04 or the newer version of the C library can be installed on Ubuntu 21.04. It is essential to ensure that the version of the C library used by the binary is compatible with the operating system on which it is running to avoid compatibility issues.
It is possible that the binary you are trying to run was built on a system with a newer version of glibc (the GNU C Library) and is therefore linked against newer versions of glibc functions. When you try to run the binary on a system with an older version of glibc, the functions it is linked against are not found because they do not exist in the older version of the library.
The version number of glibc (such as 2.34 in this case) is used to identify the specific version of the library that a binary was built against. When a binary is built, it is linked against specific versions of functions in the glibc library. If a binary is built on a system with a newer version of glibc, it will be linked against newer versions of those functions. When you try to run the binary on a system with an older version of glibc, the older version of the library does not contain the newer versions of the functions that the binary is linked against, so the binary cannot be run.
It is not uncommon for binaries built on one version of an operating system to be incompatible with older versions of the same operating system. This can occur when the binary is built on a system with a newer version of a library or other dependency that is not available on the older system. In such cases, it is usually necessary to either upgrade the operating system to a newer version that has the required dependencies, or to build the binary on an older system that has the necessary dependencies.
The term I should google for is “glibc symbol versioning”. As I learned from this introduction, glibc has multiple versions of each symbol that has changed over time and so
libc.so.6 contains all glibc versions from 2.0 through to whatever version it says. When I link a new library or binary against it, I’m using the
.h files and exported symbols for the newest versions of the symbols.
To access the older symbols, there’s a question over on StackOverflow named “How can I link to a specific glibc version”, but because all my other dependencies are likely to be linking against the newest symbols too, it’s much easier to just use Docker or a chroot to target older system versions because I’ll probably wind up building one from scratch if I don’t. The Python devs actually maintain Docker containers named
manylinux... specifically for establishing a reliable baseline for building wheels (redistributable binary packages) for Python packages with compiled components.
As for the Windows approach, it is closer to bundling multiple clearly defined profiles and urging all authors of precompiled libraries to offer builds targeting older profiles. However, with the caveat that I have to assume that stuff must be
freed by the same compilation unit that
malloc‘d it because PE doesn’t have global symbols and different libraries may depend on different versions of the allocator with their own
static variables and semantic differences.