[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#349318: [Steve Langasek] Bug#340904: Bug#349318: fixed in xft

Steve Langasek wrote:

>>If Xft is updated to a new version of either of those libraries such
>>that those types are defined differently (altered struct layout,
>>different type sizes, etc), then the app also needs to be updated to the
>>new version.
>Ok, here's the problem with this argument.
>Yes, if one of the freetype types that's used in Xft/Xft.h changes, that is
>an ABI change... *in libXft* -- that's why we care about it!  Because it's
>an ABI change in libXft, the soname of *libXft* should change.  With the
>change of libXft's soname, there's no reason an application that is a
>consumer of libXft, but *not* a consumer of freetype, should care about
>libfreetype *at all*.[1]
The simple matter of fact is that when you ask for the Xft API in your
app (#include <Xft/Xft.h>), you also get the freetype API at the same
time.  While some apps don't use it, we can't say that apps don't use
those APIs in the general case.  Until we have a widely used way to
express dependencies at that granularity, you need to look at the
library level.

>On the other hand, there are plenty of cases in which an ABI change in
>libfreetype will *not* cause an ABI change in libXft.  Addition or removal
>of functions, addition of typedefs, or removal or changing of any typedefs
>not used in libXft's ABI are all changes that should require an soname
>change in libfreetype but not an soname change in libXft.  The present ABI
>transition in libfreetype is such a case.  But because these applications
>are being encouraged to link directly to libfreetype, *even though they
>don't use it*, they have to care about ABI changes that should not affect
They are using it in conjunction with the Xft API.  There is no clear
separation between the Xft APIs that use it and those that don't.  Of
course, an app that only depends on Xft indirectly and doesn't use Xft's
APIs doesn't need direct linkage to freetype.

>The net result is that pkg-config's handling of Requires/Requires.private is
>directly causing churn in response to ABI changes in any indirect library
>dependencies, where this should be completely unnecessary on GNU/Linux
>platforms.  It increases the chances of segfaults or other failures from
>loading two different versions of a library into memory, and correspondingly
>increases the frequency with which binaries need to be rebuilt in response
>to ABI changes that don't actually concern them.  And it does this entirely
>to support a use case which, as explained above, should not actually exist.
The "app links to multiple versions of library A" problem is quite easy
to diagnose, and also makes it clear that an app needs to be rebuilt if
the old library version is removed (i.e. the app doesn't start).  The
"app depends on the structure layout of the old version of library A but
doesn't directly link to library A" is more difficult to catch.

It sounds like your argument is that "Xft shouldn't expose the freetype
API".  Given that this isn't the case, the direct linkage makes sense. 
The freetype change in this case might not break many Xft using apps,
but that won't necessarily be the case next time this type of situation

>>Changes to type definitions _do_ change the ABI.  If library A uses
>>library B's types in its ABI, then it's ABI will break if library B
>>changes those types.  An app using library A should definitely record
>>the version of library B being used.
>- If library A's soname is correctly changed in sync with library B's,
>  linking application C to library B is redundant.
>- If library A's soname is not changed when library B's soname changes,
>  pkg-config's behavior does not prevent applications from being broken by
>  the ABI change in libA.  At most, it makes it easier to detect such
>  breakage due to double-linkage of libB.
I'd argue that this is a useful feature to have, rather than having apps
break with no indication of the cause.

>>The cflags of dependencies listed in "Requires.private" are not included
>>for either dynamic or static modes of pkg-config, so maps to case 3
>>quite well.
>Ah, guess I should have looked a bit closer at the behavior in that case.
Case 3 was exactly the sort of use case I was trying to model with how
Requires.private functions.

>>>This is unfortunate, because there are a great many packages that are
>>>inheriting dependencies this way on libraries they don't use.  While it is
>>>true that an ABI change in the dependent library will *sometimes* mean an
>>>ABI change in the depending library, this is not always the case.  As a
>>>result, this behavior of pkg-config causes unnecessary churn for packages
>>>depending on libraries in this scenario.  In the case of libxft2, that's
>>>over 400 packages in Debian that are potentially affected.
>>Sure, unnecessary churn is bad and should be avoided.  But you do want
>>to make sure that the churn happens when required.
>Er, the whole reason I'm objecting to the current behavior is that it *is*
>unnecessary churn.  If the libfreetype ABI change affected the ABI of
>libXft, there would be no sense in trying to avoid the double-linking, and I
>wouldn't be bothering! :)
I understand that ABI changes are painful, but this doesn't seem like
the right way to try and combat it.  Other options include:

    * don't break the ABI.
    * don't expose unstable dependencies in your own API.
    * increase soname version numbers in lockstep with dependencies.

These all require upstream cooperation though.

>>Relying on indirect linkage in a lot of cases just results in more fragile
>No, recursive linking of indirect dependencies results in more *brittle*
>applications, which break any time anything anywhere in the dependency tree
>changes.  I'm not sure why you think that "relying" on libraries to take
>care of their own messes without bothering the application is fragile.
If the indirect dependency is solely the library's mess, then relying on
indirect linking is the right solution (and is what should happen with

When details of the indirect dependency leak through the library's API
then the mess belongs to both the app and library, and should be treated
as such.


Reply to: