Why Glibc Binary Is Called Libc.So.6 Not a Libc.So.1 or Libc.So.4

Why glibc binary is called libc.so.6 not a libc.so.1 or libc.so.4?

Those SONAMEs have already been used. Since the new version of the library presents a break in the interface, a new major SONAME number must be used for it.

How to correlate glibc and libc versions?

glibc, although at version 2.x, was for many years referred to as "libc6" for compatibility with the versioning scheme of the old libc3/4/5. In any case, the man pages on a Linux system are very helpful, but not necessarily canonical. glibc uses the "info" system instead of man pages, thus for glibc functions, you may be better off looking at the glibc manual than the man pages. While the bugs category on the realpath function is interesting in a historical context, unless you're targeting libc5 systems (which, surely you're not) is not particularly helpful.

Why does libc have two version numbers (on Ubuntu)?

What confuses me is the existence of two numbering schemes.

Before the invention of GNU symbol versioning, any change to the ABI required that an entirely new version of the library was introduced, and two (or more) copies had to be present on the system.

External library versioning is described e.g. here.

With the introduction of per-symbol versioning (GNU symbol versioning), external library versioning became completely unnecessary: multiple ABIs could be supported in a single library.

This is why libc.so.6 stayed at version 6 since forever (late 1990s). There is no reason to have a symlink at all -- the library could simply be named libc.so.6. However, it is convenient to have the symlink and have it point to current library version, e.g. libc-2.27.so.

The libstdc++.so is also stuck at libstdc++.so.6, but it is different: maintaining multiple C++ ABIs is much more difficult. So the library keeps incrementing minor version with each GCC version (newer GCC requires newer versions of libstdc++.so).

But they don't change the .so.6 part because doing so would require having multiple libstdc++.so copies (which will share 99% of the code).

why /lib32/libc.so.6 has two fopen symbol in it?

Actually multiple definitions of the same symbol are fine and can happen in a number of ways. One of them (which isn't the case here) are weak symbols.

What happens here is that glibc dynamic linker supports symbol versioning and glibc uses that. It exports a version of fopen from glibc 2.1 and a backward compatible version from glibc 2.0 with difference interfaces.

At dynamic link time the application can chose a specific version or a default one.

What is the difference between /lib/i386-linux-gnu/libc.so.6, /lib/x86_64-linux-gnu/libc.so.6 and /usr/lib/x86_64-linux-gnu/libc.so?

/lib/i386-linux-gnu/libc.so.6

This is is 32-bit version of the library.

/lib/x86_64-linux-gnu/libc.so.6

This is the 64-bit version of the library.

Both are usually symbolic links to the actual library file, which will usually be named according to the glibc release number, for example libc-2.15.so

/usr/lib/x86_64-linux-gnu/libc.so

This is not a library, but a linker script file, which refers to the above symlinks.

Why do we need all these:

First, regardless of libc version installed, the linker will always search for libc.so, because the compiler driver will always pass to the linker the -lc options. The name libc stays the same and denotes to most recent version of the library.

The symlinks libc.so.6 are named after the soname of the library, which, more or less corresponds to the ABI version of the library. The executables, linked against libc.so in fact contain runtime dependencies on libc.so.6.

If we imagine the someday a grossly ABI incompatible libc is released, it's soname could be named libc.so.7, for example and this version coukld coexists with the older libc.so.6 version, thus executables linked against one or the other can coexist in the same system,

And finally, the name libc-2.15.so refers to the libc release, when you install a new libc package, the name will change to libc-2.16.so. Provided that it is binary compatible with the previous release, the libc.so.6 link will stay named that way and the existing executables will continue to work.

Deploying Yesod to Heroku, can't build statically

I have no idea what Yesod is, but I know exactly what each of your other errors means.

First, you should not try to link statically. The warning you get is exactly right: if you link statically, and use one of the routines for which you are getting the warning, then you must arrange to run on a system with exactly the same version of libc.so.6 as the one you used at build time.

Contrary to popular belief, static linking produces less, not more, portable executables on Linux.

Your other (static) link errors are caused by missing libopenssl.a at link time.

But let's assume that you are going to go the "sane" route, and use dynamic linking.

For dynamic linking, Linux (and most other UNIXes) support backward compatibility: an old binary continues to work on newer systems. But they don't support forward compatibility (a binary built on a newer system will generally not run on an older one).

But that's what you are trying to do: you built on a system with glibc-2.14 (or newer), and you are running on a system with glibc-2.13 (or older).

The other thing you need to know is that glibc is composed of some 200+ binaries that must all match exactly. Two key binaries are /lib/ld-linux.so and /lib/libc.so.6 (but there are many more: libpthread.so.0, libnsl.so.1, etc. etc). If some of these binaries came from different versions of glibc, you usually get a crash. And that is exactly what you got, when you tried to place your glibc-2.14 libc.so.6 on the LD_LIBRARY_PATH -- it no longer matches the system /lib/ld-linux.

So what are the solutions? There are several possibilities (in increasing difficulty):

  1. You could copy ld-2.14.so (the target of /lib/ld-linux symlink) to the target system, and invoke it explicitly:

    /path/to/ld-2.14.so --library-path <whatever> /path/to/your/executable

    This generally works, but can confuse an application that looks at argv[0], and breaks for applications that re-exec themselves.

  2. You could build on an older system.

  3. You could use appgcc (this option has disappeared, see this for description of what it used to be).

  4. You could set up a chroot environment matching the target system, and build inside that chroot.

  5. You could build yourself a Linux-to-olderLinux crosscompiler



Related Topics



Leave a reply



Submit