Avery Pennarun
2004-03-28 17:12:02 UTC
In http://www.townhall.com/columnists/alanreynolds/ar20040325.shtml,
this, it will get you into trouble. There are reasons you need XPLC, but
this isn't it.
Major sonames are for breakage in backward compatibility only; things that
are backward but not forward compatible do *not* generally change the
soname, unless the package maintainer is an idiot (and some are, of course).
Every library also has a "minor" soname (which is not actually an ELF
feature; it's just the filename) which changes with every change,
incompatible or otherwise, but people don't actually use this for anything
but keeping their sanity. ("Which version of libc is this? Oh, 2.2.6.")
Package maintainers make the following assumptions:
- the .h header files on the system will work perfectly with the library
version you get when linking.
- the library used at runtime will work perfectly with the API provided by
the header files used at compile time.
You can change the soname when adding an extra API function without breaking
these two assumptions. Note that you can also install header files from an
old library version, and link with a newer one, without breaking this
assumption - and you'll still be able to run with a library as old as the
one compatible with your header files!
So, when I use the new function supported only in version 1.1, but version
1.1 has the same soname (1) as version 1.0, how do I enforce that my binary
will only be used on systems with library 1.1 or higher? Package
dependencies. In Debian format, for example, I can say that my package
depends on:
libc6 (>= 2.2.6)
That is, libc with a soname libc.so.6, version 2.2.6 or greater.
In source-based systems like gentoo, I simply can't compile the program
unless I have a newer version of the headers, which means I need a newer
version of the library. Of course, they have source-level "build
dependencies" to make sure this is true.
libc's ELF tricks are not for forward compatibility - they're for backward
compatibility. The problem is that "statfs" in one version of libc has a
totally different API than "statfs" in the next version, so they play tricks
to make sure I get the one I got during link time. It would have been much
less evil to have the headers enforce this instead (#define statfs
statfs_2_2_6), but that would have required foresight, something programmers
are notoriously bad at.
Have fun,
Avery
But there is something very annoying with this.
If you add a function, like I previously said, this is not forward
compatible, so you have to rename the library.
This is not actually true, and since a lot of your later argument relies onIf you add a function, like I previously said, this is not forward
compatible, so you have to rename the library.
this, it will get you into trouble. There are reasons you need XPLC, but
this isn't it.
Major sonames are for breakage in backward compatibility only; things that
are backward but not forward compatible do *not* generally change the
soname, unless the package maintainer is an idiot (and some are, of course).
Every library also has a "minor" soname (which is not actually an ELF
feature; it's just the filename) which changes with every change,
incompatible or otherwise, but people don't actually use this for anything
but keeping their sanity. ("Which version of libc is this? Oh, 2.2.6.")
Package maintainers make the following assumptions:
- the .h header files on the system will work perfectly with the library
version you get when linking.
- the library used at runtime will work perfectly with the API provided by
the header files used at compile time.
You can change the soname when adding an extra API function without breaking
these two assumptions. Note that you can also install header files from an
old library version, and link with a newer one, without breaking this
assumption - and you'll still be able to run with a library as old as the
one compatible with your header files!
So, when I use the new function supported only in version 1.1, but version
1.1 has the same soname (1) as version 1.0, how do I enforce that my binary
will only be used on systems with library 1.1 or higher? Package
dependencies. In Debian format, for example, I can say that my package
depends on:
libc6 (>= 2.2.6)
That is, libc with a soname libc.so.6, version 2.2.6 or greater.
In source-based systems like gentoo, I simply can't compile the program
unless I have a newer version of the headers, which means I need a newer
version of the library. Of course, they have source-level "build
dependencies" to make sure this is true.
libc's ELF tricks are not for forward compatibility - they're for backward
compatibility. The problem is that "statfs" in one version of libc has a
totally different API than "statfs" in the next version, so they play tricks
to make sure I get the one I got during link time. It would have been much
less evil to have the headers enforce this instead (#define statfs
statfs_2_2_6), but that would have required foresight, something programmers
are notoriously bad at.
Have fun,
Avery