On Fri, 03 Jul 2020 at 21:16:44 +0300, Michael Tokarev wrote: > On Fri, 03 Jul 2020 18:45:07 +0900 Mike Hommey <mh+report...@glandium.org> > wrote: > .. > > Arguably, freetype2.pc shouldn't depend on libbrotlidec.pc except with a > > Required.private, assuming one doesn't actually need to include > > libbrotli headers or link against libbrotli library (presumably, that's > > the case). > > The thing is that libbrotli *is* in Requires.private, and pkg-config still > insists on it to exist.
This is because there are three possible "weights" of dependency, and only two dependency lists in a .pc file, so the dependency lists cannot possibly be 100% correct for all three "weights". In decreasing order of "weight": 1. Public dependency: depending on A guarantees availability of B because they are inextricably linked, and you can't use A without B (for example GTK depends on GLib like this). This is Requires. pkg-config --cflags A includes B. pkg-config --libs A includes B. pkg-config --static --cflags A includes B. pkg-config --static --libs A includes B. A-dev must depend on B-dev. 2. Use of data structures: some header files from A include header files, macros, data structures from B; it is possible to use A without directly linking to B, but you can't successfully #include all the headers of A unless you have B-dev installed (for example GTK depends on Pango like this, I think). This is Requires.private. pkg-config --cflags A includes B. pkg-config --libs A does not include B. pkg-config --static --cflags A includes B. pkg-config --static --libs A includes B. A-dev must depend on B-dev, even if you don't care about static linking. 3. Implementation detail: A uses B internally, but does not mention it in its header files at all. It is possible to use A without having B-dev, *unless* you are linking statically (for example GTK depends on epoxy like this). pkg-config does not have a representation for this at the moment, although a new Requires.internal was proposed in 2018 (<https://bugs.freedesktop.org/show_bug.cgi?id=105572>). Requires.private behaved like this before 2007 (#390132), but we have had 13 years of packages depending on Requires.private's new meaning, so reverting that change would be harmful. Ideally the behaviour here would be: pkg-config --cflags A should not include B. pkg-config --libs A should not include B. pkg-config --static --cflags A should not include B. pkg-config --static --libs A should include B. A-dev does not need to depend on B-dev unless you care about static linking (so maybe weakening it to a Recommends or Suggests would be OK). Known workarounds for the nonexistence of Requires.internal are: * Don't mention B in A.pc at all. Statically linking A will not work. This is perhaps the least bad solution if A or one of its dependencies is shared-only and does not support static linking, for example Mesa or libsystemd, but it's difficult to make that decision in practice. For example, libdbus conditionally depends on libsystemd, so it cannot easily be statically linked *in Debian* - but I think the same upstream source code *can* be statically linked in Devuan or on non-Linux, where the libsystemd dependency is disabled, so it is not straightforward for the upstream developer to know whether static linking is supported when generating the .pc file. * Put B and all its recursive dependencies in Libs.private, which is not great because it requires hard-coding part of the information you got from B.pc into A.pc, meaning A.pc can be out of date if B.pc has changed (for example gaining a dependency) since A was built. * Strengthen the dependency to Requires.private. This is what usually happens in practice (as in this case), and means you need B-dev installed even though in principle shared linking shouldn't need it. smcv