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

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



Tollef Fog Heen wrote:

>Hi, any chance you could comment on this?  I'm somewhat inclined to
>agree with Steve, but you know this stuff better than I do, so I'd
>value a second opinion.
>
>Also, if there's anything unclear or anything, please do mail Steve
>(and the bug) with me in Cc.
>  
>
[snip]

>  
>
>Both the xrender and freetype2 headers are included in Xft/Xft.h, and types
>from both of these headers are exported in the Xft API -- so any software
>using Xft.h needs to be able to find these other headers as well.
>Currently, pkg-config does *not* pass cflags from packages listed in
>Requires.private when called as pkg-config --cflags <foo>.
>  
>

The fact that the headers are included makes them part of the _public_
ABI of Xft.  There are Xft functions that accept or return types defined
in the Xrender and freetype2 headers.

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.

>So far, the maintainer has resisted changing pkg-config to export cflags
>(which should really be called cppflags...) from Requires.private due to a
>fallacious argument regarding the nature of "private" dependencies.  There
>are three real use cases for libraries which depend on other libraries:
>
>- the library intentionally exports the API and ABI of its dependencies when
>  linked to, and therefore both the ldflags and the cflags of its
>  dependencies should be exported by pkg-config in all cases[1]
>  
>
Yep, this is the use case addressed by "Requires".

>- the library intentionally includes headers from dependencies in its own
>  headers in order to inherit type definitions, but these definitions are
>  not intended for direct consumption by users of this library alone;
>  therefore pkg-config must export the cflags from dependencies in all
>  cases, but the ldflags only when linking statically
>  
>
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.

>- the library's API includes no headers from its dependencies; pkg-config
>  needs to export the ldflags of private dependencies when statically
>  linking but not when dynamically linking, and should *never* need to
>  export the cflags of these headers.
>  
>
This is the use case for "Requires.private".  If the dependency doesn't
form part of the library's API, then it obviously doesn't require direct
linkage and is private.

>Please note that today, the handling of Requires.private in pkg-config maps
>to *none* of these cases -- I can't think of a single situation in which
>cflags of dependencies are needed when statically linking, and not needed
>when dynamically linking!
>
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.

Consider the following two .pc files.  First "foo.pc":
  Name: foo
  Description: foo
  Version: 1.0
  Cflags: foo-cflags
  Libs: foo-libs

And "bar.pc":
  Name: bar
  Description: bar
  Version: 1.0
  Cflags: bar-cflags
  Libs: bar-libs
  Requires.private: foo

For the dynamic linking case:
  $ pkg-config --cflags bar
  bar-cflags
  $ pkg-config --libs bar
  bar-libs

For the static linking case:
  $ pkg-config --static --cflags bar
  bar-cflags
  $ pkg-config --static --libs bar
  bar-libs foo-libs

>  Instead, the Requires.private handling is
>adequate for the third case; handling of Requires is correct for the first
>case; and there is no combination of options that is appropriate for the
>second case.
>  
>
I'd argue that the second case is a strawman.  If a particular library
exposes another in its API/ABI, then it is part of case 1.

>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.  Relying on indirect
linkage in a lot of cases just results in more fragile applications.

There are cases where it might make sense to move a library to
"Requires.private" even when it is used in some headers, but I don't
think this is one of them.  Some examples where it would be appropriate
include:

    * Cairo's dependency on glitz, xlib and freetype (this one has been
      done upstream).  Apps only depend on glitz if they include
      <cairo-glitz.h> and use those APIs.  Apps that don't use those
      APIs shouldn't be linked to glitz so that they'll work on systems
      where Cairo hasn't been built with glitz support.  The Cairo
      developers advise app developers to direct link to both cairo and
      glitz if they are using the glitz features.
    * GTK does not expose the X API through its headers except for
      <gdk/gdkx.h>.  You might argue that it should list the xlib
      dependency as private.

James.



Reply to: