[Xcb] [ANNOUNCE] xcb-util 0.3.9
Jeremy Huddleston
jeremyhu at freedesktop.org
Tue Jun 5 22:03:44 PDT 2012
On Jun 5, 2012, at 6:35 PM, Josh Triplett <josh at joshtriplett.org> wrote:
> [Side note: your mails show up with ridiculously long uwrapped lines,
> which makes them harder to reply to.]
Interesting, the one in my sent folder is quoted-printable with proper-length lines.
The mail that I see from the list server is 7bit instead of quoted-printable, and it has incorrectly long lines that violate RFC2821. I don't know what might be causing that, but I'll do some experiments, thanks. I'm sorry this line will likely appear as "long", but I want to test this message. I'll manually break lines below.
>> Take libXi for example, since it's probably fresh in most of our minds. With Xi2, libXi added a ton of new functionality and remained backwards compatible. Thus, the minor version of the library was bumped (http://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=0d19a3ec942aedf5432a9bda1e80f29f7186ce5b) from 6.0 to 6.1.
>>
>> As far as I can tell, though, symbols are not annotated with "available in 6.1 and later" so the only difference is the minor version bump, and as you said, Linux/ELF essentially ignores this ... so in this case, there is no *practical* difference between going forward with an added symbol and going backwards with a removed symbol. To make this a bit more clear (words fail me, sorry), consider:
>>
>> case 1:
>> libABC.0.0 contains symbols a, b, c
>> libABC.1.0 contains symbols a, b
>> libABC.1.1 contains symbols a, b, c (c was added back in but not annotated as new in 1.1)
>>
>> case 2:
>> libABC.0.0 contains symbols a, b, c
>> libABC.0.1 contains symbols a, b
>>
>> In case 1, libABC.1.1 and libABC.0.0 are identical. Since Linux/ELF
>> ignores minor version, there is no effective difference between
>> linking against libABC.1.1 and running with libABC.1.0 in case 1
>> compared to linking against libABC.0.0 and running with libABC.0.1 in
>> case 2.
>
> I agree with your statement that from a functional standpoint this holds
> true: the linker doesn't seem to enforce the minor version rule, so you
> can build against a newer library and run with an older one, or vice
> versa, as long as the major version matches. The linker will complain
> if you use a symbol that it can't resolve, though.
As it should (well unless the symbol is weak and can be checked for at
runtime).
> Linux distributions primarily want to avoid the scenario in which the
> dynamic linker considers a library version acceptable but the program
> requiring that library crashes or otherwise breaks at runtime.
I think that's a fairly universal concern beyond just Linux distros.
> That
> doesn't happen with the addition or removal of symbols, because the
> dynamic linker will attempt to resolve those symbols and complain if it
> can't; in that scenario, the rule of bumping the major version when
> removing functions represents a "don't do that" convention to avoid
> having users surprised by programs that suddenly refuse to run with a
> library that claims compatibility; upgrading to a newer version of a
> library with the same major number should never cause existing programs
> to stop working.
Yes, I thoroughly agree with that, but I also believe that applications
built against a newer version of a library should be *capable* of running
on older versions of that library (with the same major version) and that
API should *almost never* be removed (deprecated yes, removed no) to allow
the best portability possible.
> In particular, the minor version serves as a hint to the programmer that
> if they link against libABC.so.1.1, they might or might not successfully
> run against libABC.so.1.0, depending on what symbols they used.
IMO, that should be annotated in header files in a way that allows those
symbols to be weak linked and checked for at runtime (and thus go down an
alternative codepath if unavailable).
> On the
> other hand, a programmer expects that a program linked against
> libABC.so.1.0 should *always* work with libABC.so.1.1, but won't
> necessarily work with libABC.so.2.0.
Well, it won't *EVER* work with libABC.so.2.0 because the dynamic linker
sees it as a completely different library.
> Removing or changing symbols
> breaks that assumption; adding symbols doesn't.
>
> Libraries typically introduce symbol versioning to handle more complex
> cases that the linker can't catch on its own, namely a *change* to an
> existing symbol, such as by adding a new parameter to a function, or
> more subtly by changing the layout of a data structure used by a
> function. In that scenario, the linker will see no problem, but the
> program will break at runtime, precisely as if you cast a function
> pointer to a different type with different parameters and tried to call
> it (because, effectively, you did). Symbol versioning lets you maintain
> ABI (though often not API) compatibility in this case, by having old
> programs use a compatibility symbol that knows how to handle the old
> calling signature.
Yeah, we essentially have that same mechanism in place, usually for
cancelable/non-cancelable variants, legacy vs UNIX-conforming variants,
changes to 'struct stat', ...
> However, the details of how much the dynamic linker enforces and how
> much just occurs by convention don't change the general rules for how to
> set library major and minor versions: always bump the major version if
> you remove symbols or change the meaning of existing symbols.
> Exceptions to that rule lead to unexpected breakage, even when
> attempting to claim that a symbol doesn't represent public API, and such
> exceptions should only occur with careful consideration of the breakage
> they'll introduce.
I just disagree with this point. If a symbol exists just for internal
consumption but is exported (yes, the developer should've used visibility),
then I don't believe removing it warrants a major version bump.
More information about the xorg
mailing list