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

Re: Deps of -dev packages with pkg-config .pc file: Policy Change?



On Fri, 17 Dec 2021 at 10:05:39 +0100, Alexander Traud wrote:
> I do not understand why:
> a) pkg-config itself is *not* a dependency as well

Sometimes it is appropriate for it to be, and sometimes it is not.

For some libraries, the only maintainer-supported way to consume the
library is via pkg-config. If that's the case, then a dependency on
pkg-config can be appropriate - although we don't add a dependency on
cc or binutils, which is equally necessary. Libraries with multiple
parallel-installable versions, like GTK, often behave like this: you have
to explicitly ask (via pkg-config) to add the version you want to use to
the compiler's search paths, so that you will not get the <gtk/gtk.h>
from GTK 2 or 4 where GTK 3 was expected.

For other libraries, either there are other supported ways to consume
the library (CMake metadata or sdl2-config or similar), or the library
is in the compiler's default search paths (not parallel-installable)
like libjpeg - so you *can* use pkg-config, but you don't *have* to.

> b) Lintian was not upgraded in 15 years to check the content of the .pc 
>    file and aid the maintainer in not missing any required dependency.

Lintian cannot know whether the required dependencies are present: that
is outside its scope. Lintian analyzes each package in isolation, without
referring to other packages. If your library depends on foo-bar, Lintian
cannot know whether foo-bar.pc is in libfoo-bar-dev, libfoo-bar2-dev,
libfoo-dev, libfoo2-dev or something else.

> Simon McVittie wrote:
> > this doesn't scale well
> 
> Then, I do not understand static linking. I thought, please correct me 
> here, static linking is about the '.a' file in the package, the current 
> one. I have to suffice its links as it was built, not the links when I 
> build.

Imagine you are packaging a library "libfoo" that makes use of GLib
(glib-2.0.pc, from src:glib2.0) but does not expose GLib in its header
files. This is an example of the class of dependency that you want
to move from Requires.private to Libs.private.

glib-2.0 currently depends on libpcre, which it uses to implement GRegex.
It does not include libpcre headers in its header files (the GRegex API
completely wraps libpcre), so libpcre is another example of the class of
dependency that you want to move from Requires.private to Libs.private.
Imagine that GLib had done this.

When you statically link your library libfoo into a program, you want to
end up with something like this:

    gcc -static ... -lfoo -lglib-2.0 -lpcre

libfoo.a provides symbols used by the program, libglib-2.0.a provides
symbols used by libfoo, and libpcre.a provides symbols used by libglib-2.0.a.
So far, everything is working.

If we were using Libs.private as you suggest, then glib-2.0.pc and libfoo.pc
would have something like:

    # glib-2.0.pc
    ...
    Libs: -L/usr/lib/MULTIARCH -lglib-2.0
    # generated from: Libs.private: $(pkg-config --static --libs libpcre)
    Libs.private: -L/usr/lib/MULTIARCH -lpcre

    # libpcre.pc
    ...
    Libs: -L/usr/lib/MULTIARCH -lfoo
    # generated from: Libs.private: $(pkg-config --static --libs glib-2.0)
    Libs.private: -L/usr/lib/MULTIARCH -lglib-2.0 -lpcre

Now imagine that GLib switches to libpcre2 (libpcre2-8.pc, -lpcre2-8)
as requested in #1000082. This will change the contents of glib-2.0.pc to:

    # glib-2.0.pc
    ...
    Libs: -L/usr/lib/MULTIARCH -lglib-2.0
    # generated from: Libs.private: $(pkg-config --static --libs libpcre2-8)
    Libs.private: -L/usr/lib/MULTIARCH -lpcre2-8

Without changing anything in libfoo, you'll find that libfoo.pc is now
wrong (until it is rebuilt and has the opportunity to update its idea of
what GLib depends on). Programs that depend on libfoo will fail to
link, because the new libglib-2.0.a requires symbols from libpcre2-8.a
instead of the old libpcre.a, but libfoo.pc still says
"Libs.private: ... -lpcre" because that's what it captured at libfoo's
build-time.

That's why I think it is best that the information about which libraries
GLib depends on is shipped with GLib and included by reference (via
either Requires.private: glib-2.0, or the Requires.internal: glib-2.0
proposed on https://bugs.freedesktop.org/show_bug.cgi?id=105572), instead
of copying the information about GLib's dependencies into libfoo-dev where
it will become outdated when GLib changes.

    smcv


Reply to: