On Fri, 05 Dec 2014 16:26:46 +0000
Richard Kettlewell <
r...@greenend.org.uk> wrote:
> No problem!
:-)
> >> myprog: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not
> >> found
> >
> > is incomprehensible because it's produced at too low a level.
>
> I don?t think that?s the case. The version numbers of the package are
> 2.13, 2.14, etc. So the error message quoted does actually tell you
> what to look for in the version column of a package manager
"It's easy if you know how". The message doesn't mention the package
manager. What it says is that the existing library -- valid in every
way from external inspection -- lacks a required symbol. The first
time I encountered it, I thought the system was misconfigured. (I
suppose I still do!) The OP didn't recognize it as a versioning issue,
either.
> Software distributors who want to ship object code have to build for
> the oldest platform they want to support.
Agreed, but that's not the same as saying they must link against the
oldest libraries they want to support when building. There is no
reason, fundamentally, that if I link against version N of a library
that you can't use N-1 instead at runtime.
http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
As they say over there at libtool, "programs using the new version can
also work with the previous one".
(IMO libtool's version-number algorithm is too strict. Adding a new
function ("interface", step #4) shouldn't result in a new major
version.)
> But the same would be true whatever approach was taken to shared
> library versioning: if they build against a hypothetical libc.so.25
> and the customer only has libc.so.24, the customer is likely to be
> disappointed.
Yes, because in your example you're using different *major* version
numbers. By definition, they are not binary compatible. Because in
2014 our symbols bear no semantics, the linker cannot know what
function X means; it depends on the major version's claim that it is
or isn't the same.
In the OP's case, both libraries are version 6.
> As such I must be missing what your alternative proposal is, given
> that the only one I?ve so far imagined doesn?t solve any of today?s
> unsolved problems, and has serious drawbacks of its own. Nineteen
> copies of libc? (Twenty next year?)
Actually, no, I'm not proposing anything, except to use the major
version number for its intended purpose.
Let's go back to 2.13 and 2.14 again. If 2.14 has all the same
functions and structures and semantics as 2.13, and my application
relies on none of the additions offered in 2.14, then I can link
against 2.14, ship it to you, and you can use 2.13 with no problem at
all. The soname will be libfoo.so.2. As long as that remains true, as
long as I continue to rely on the 2.13 interface, I can keep upgrading
-- 2.15, 2.16, 2.17 -- and you have no need to upgrade. You may start
to feel a need for pipe an slippers, but my software will run on your
machine.
The day may come when a new feature of 2.19 is irresistable. If I use
it, I can continue make my application compatible by checking that
dependency at runtime and falling back to the 2.13 behavior if that's
what the runtime environment supplies. Or, if I'm a meanie, I can link
to it and require you do, too. I can post a little item in the News
section of my website saying New & Improved version 10.5 of Zeebob
requires version 2.19 of the library. Change or be changed!
If you fail to take proper note of my scintillating announcment -- Yo!
Richard! Aren't you paying attention? -- then you'll get a linker
error and call my helpdesk, whose phone no one answers because it's
2014. But a little searching will uncover the requirement, and you'll
know what to do.
Note that the requirement to upgrade is under the developer's control,
and affects only one application. And the user is left mostly
unmolested.
What's going on with glibc is very different, so I've learned here.
Every release bumps a symbol inside the library that the linker
conspires to examine and throw you out on your ear if it's not recent
enough. I doubt very much the OP really, really needed whatever is
uniquely associated with GLIBC_2.14. I'm absolutely sure that the
linker cannot know, nor can the glibc authors. But they took the
*entire* interface and said "Oh, no, 2.13 is sooo last week. You need
to upgrade, dude, because memcpy might have changed again."
(That's my impression. I haven't found any documentation at all on the
glib website or man page indicating the significance of
GLIBC_2.14 symbol or the policy. The FAQ has a whole paragraph on
symbol versioning, and nary a word on the project's idiosyncratic
library versioning policy. I would venture to say that's part of the
problem.)
In such an regime, the developer has to maintain a build environment
flash-frozen in time of the oldest version he supports. He may build
daily against N, but for releasing he has to schroot to N-9 and build
there. No wonder virtual environments are so popular.
This is not a service to users. It's careless engineering, and
costly besides. Although, granted, the costs are borne by the users.
> Finally, and this may be a bit tangential but: the choice of 6 is a
> historical accident following from the early years of x86 Linux. The
> jump from 5 to 6 was completely incompatible in both directions - a
> program compiled against libc.so.5 will not work with libc.so.6.
It's not tangental at all; it illustrates what I've been saying all
along. The bump from 5 to 6 would have signified a change in binary
compatibility. You can't use 6 if you linked against 5 and you can't
use 5 if you linked against 6. That's what binary compatibility means,
and that fact *is* reflected in the soname of the library and the NEEDS
section of the elf headers.
However, there's no reason /lib can't have two versions of libc.
Currently I have:
$ pwd && file libc.so*
/lib/x86_64-linux-gnu
libc.so.6: symbolic link to `
libc-2.15.so'
and the library declares itself as "libc.so.6":
$ readelf -d libc.so.6 | sed -Ene 's/0{9}/0/; /SONAME/p'
0x0000000e (SONAME) Library soname: [libc.so.6]
and applications indicate that's the libc they need:
$ readelf -d $(which ls) | sed -Ene 's/0{9}/0/; /libc/p'
0x00000001 (NEEDED) Shared library: [libc.so.6]
When the 5->6 move happened, old utilities would have been linked
to 5. Installing version 6 wouldn't upset any applecarts. No reason
they can't be co-resident, and no reason for a wholesale upgrade.
Linking some things to 5 and others to 6 causes no problems. Linking
something to both 5 and 6 (Hi, Rainer!) can cause problems. Simple
answer: don't do that.
Does it cause a headache for package management? It does. As
was pointed out upthread, if the application is linked against 5 and
also against a library that was linked against 6, it's a problem. So
the major version ripples thoughout the packaging system, even though
the packages and libraries themselves are unchanged. But, again,
there's no reason you can't have a whole set of libraries side by side,
one reliant on 5 and the other 6.
My NetBSD machine looks like this:
$ ls /usr/lib/libc.* | xargs file
/usr/lib/libc.a: current ar archive
/usr/lib/libc.so: symbolic link to `../../lib/libc.so.12.164'
/usr/lib/libc.so.12: symbolic link to `../../lib/libc.so.12.164'
/usr/lib/libc.so.12.164: symbolic link to `../../lib/libc.so.12.164'
In 2002, according to CVS, the major version was 7: that's 5
binary-incompatible changes in 12 years. It's normal, and it works.
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/shlib_version
I don't know the history of the 5->6 migration on Linux (and I don't
consider c.u.p a Linux-only forum). I have the impression the X11R7
migration was poorly handled; what I read showed misunderstandings up
and down the line. So it wouldn't suprise if me if bumping the major
libc version in that environment led to something of a cacophony.
The resulting policy -- to freeze the major version -- has effects that
are beyone dispute. It put users on the same upgrade treadmill that
Microsoft & Apple have their users on. Instead of carefully avoiding
incompatibility and leaving upgrade choices to users and developers,
the effect is to require everyone to "stay up to date", whether or not
that makes economic or technical sense. Instead of human intelligence,
we put the linker in charge. I'm sure the fact that that's convenient
for the developers is just a coincidence.
--jkl