Hi, various .pc files that we ship contain a lot of stuff in the Libs and Libs.private field don't make much sense to me. I started looking at the documentation, and the documentation is very scarce, and what is there doesn't seem to have been thought out at all. I'm writing my observations and questions below. pc(5) says: Libs: Required linking flags for this package. Libraries this package depends on for linking against it, which are not described as dependencies should be specified here. Libs.private: Required linking flags for this package that are only required when linking statically. Libraries this package depends on for linking against it statically, which are not described as dependencies should be specified here. "described as dependencies" here means "not listed in Requires and Requires.private fields, which are used to specify dependencies on other pkgconf projects. On the face, this seems reasonable, but there's other documentation that has a different spin. E.g. https://people.freedesktop.org/~dbn/pkg-config-guide.html says: Libs: The link flags specific to this package and any required libraries that don't support pkg-config. Libs.private: The link flags for private libraries required by this package but not exposed to applications. The same rule as Cflags applies here. "required" here refers to using Requires and Requires.private to list other .pc files. Neither of the above approaches seems to be consistent with how we actually use .pc files, and even not much consistent with how they could be reasonably used: 1. pc(5) talks about "package", as if one would want to link to a whole "package" instead one of the specific library files provided by a package. Thankfully most .pc files only list one "-l" in Libs. (Counterexamples: tbbmalloc_proxy.pc says 'Libs:-ltbbmalloc_proxy -ltbbmalloc', and mit-krb5.pc says Libs:-lkrb5 -lk5crypto -lcom_err.) The concept of having multiple libs in Libs in itself is borked: either the libraries are functional separately, in which case they would better have separate .pc files, so that the programs using those libraries can link to the one they need, or if they are not functional separately, the one that exposes functionality that is useful externally should be advertised (the others will be pulled in automatically by the linker). 2. In practice, most .pc files that list multiple things in Libs seem to be doing exposing their own link dependencies there. For example mono-2.pc says 'Libs: -L${libdir} -lmono-2.0 -lm -lm -lpthread', and indeed ldd /usr/lib64/libmono-2.0.so says it is linked to libm.so.6. Of course this doesn't mean that programs using libmono would need to be linked to libm themselves. Items 1 + 2 are promoting overlinking, i.e. adding either unneeded libraries, or libraries that are used indirectly, to linker flags for some object being linked. If we take the pc(5) definition at its word, the Libs.private lines are even more broken in Fedora, because we almost never provide static libraries. Looking at Requires and Requires.private, there is more strangeness. pc(5): Requires: Required dependencies that must be met for the package to be usable. All dependencies must be satisfied or the pkg-config implementation must not use the package. Requires.private: Required dependencies that must be met for the package to be usable for static linking. All dependencies must be satisfied or the pkg-config implementation must not use the package for static linking. To a large extent pkgconfig files are duplicating dependency logic that is already provided by distro packaging (rpm in our case). This would seem like an OK idea: upstreams specify which libraries they need and downstreams use it. It seems not to work in practice: e.g. atk-bridge-2.0.pc specifies Requires.private: dbus-1 >= 1.5, atspi-2 >= 2.33.2, atk >= 2.36.0, glib-2.0 >= 2.32.0, gmodule-2.0 >= 2.0.0, gobject-2.0 >= 2.0.0 which is translated into: $ rpm -qRf /usr/lib64/pkgconfig/atk-bridge-2.0.pc /usr/bin/pkg-config pkgconfig(atk) >= 2.36.0 pkgconfig(atspi-2) >= 2.33.2 pkgconfig(dbus-1) >= 1.5 pkgconfig(glib-2.0) >= 2.32.0 pkgconfig(gmodule-2.0) >= 2.0.0 pkgconfig(gobject-2.0) >= 2.0.0 ... Two problems: 3. We autogenerate a dependency on /usr/bin/pkg-config for -devel. Logic is reversed here: the -devel package **provides** something that it consumed by pkg-config. Dependencies are from a consumer to the providing entity. 4. The -devel subpackage pulls in atk-devel, at-spi2-core-devel, dbus-devel, glib2-devel, and glib2-devel. Most of those dependencies are completely pointless. The only reason why one header package would require another header package is when the headers it provides #include other headers. at-spi2-atk-devel has a single header file, with '#include <glib.h>'. It thus should have a dependency on 'pkgconfig(glib-2.0)', and all the other deps generated from Requires.private just inflate the build root. (If glib.h or libglib-2.0.so in turn require other things for themselves, those dependencies will be specified by glib2.rpm.) And finally, we get to stuff which is included in Libs: /usr/lib64/pkgconfig/libresample.pc Libs: -Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -lresample -lm /usr/lib64/pkgconfig/libpsx.pc Libs: -L${libdir} -lpsx -lpthread -Wl,-wrap,pthread_create /usr/lib64/pkgconfig/ruby.pc DLDFLAGS=-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld Libs: ${DLDFLAGS} ${LIBRUBYARG_SHARED} ${LIBS} /usr/lib64/pkgconfig/libresample.pc Libs: -Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -lresample -lm /usr/lib64/pkgconfig/socket_wrapper.pc Libs: lib64/libsocket_wrapper.so /usr/lib/pkgconfig/gmodule-2.0.pc Libs: -Wl,--export-dynamic Those seems to be all errors: redhat-hardened-ld is supposed to be used in package builds, not exposed for user compilations. lib64/libsocket_wrapper.so cannot be resolved. And other link flags that change the resulting binary is not the something that libraries should specify. To summarize: - Re 3: drop the generator for the reversed dep? - Re 2: flat everything that is not -l, -L, in Libs with rpmlint? Zbyszek _______________________________________________ devel mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxx Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/devel@xxxxxxxxxxxxxxxxxxxxxxx Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure