Reputation: 3705
Fedora Packaging Guidelines (permalink) officially recommends using the pkgconfig(NAME)
syntax when declaring build dependencies. So for example, instead of BuildRequires: libxcb-devel
, you would declare BuildRequires: pkgconfig(xcb)
. (Similarly, dnf install 'pkgconfig(xcb)'
would offer to install libxcb-devel
, which is why I assumed this is a feature of dnf
as opposed to the SPEC file processor.)
I've always been curious, and honestly it has bugged me throughout these few years I've been doing packaging - how exactly does this work? I know pkg-config
(or pkgconf
) uses .pc
files to determine a library's associated names and arguments, and that those .pc
files are shipped with development libraries (*-devel
packages on Fedora). But that's the problem - how does the build system (more specifically, dnf
) resolve a declaration like pkgconfig(xcb)
before installing libxcb-devel
which provides the .pc
file?
The only possible explanation I can think of at this point is if there's some kind of central registry of all .pc
files within the remote repositories that dnf
can easily query. But I can find absolutely no documentation for this, nor have I noticed the existence of such a file in various mirrors.
So what kind of magic is dnf install pkgconfig(NAME)
doing? Is there a map (or a command to compute a map) between pkgconfig(NAME)
and the concrete packages they point to? This would make the process of looking up the right name to declare in BuildRequires:
a whole lot easier for me.
Upvotes: 0
Views: 1382
Reputation: 107
The accepted answer was talking mainly of runtime dependencies and how DNF resolves them.
In the BuildRequires:
field, however, the use of pkgconfig()
syntax has more to do with how pkgconf
resolves build-time dependencies. To quote the guidelines you linked to
The build infrastructure for a given package will often locate and use required libraries by using pkg-config.
Thus, pkgconfig(foo) is the true statement of the build dependency
Note that after Fedora 26 this means Ariadne Conill’s pkgconf
. The following commits are relevant here
https://github.com/pkgconf/pkgconf/commit/f9101659bc46401ad412d3132ba4fe09d06fec91
https://github.com/pkgconf/pkgconf/commit/d304d9cb2e3ddd1aada1eaa6211b1b41015a246a
Upvotes: 1
Reputation: 3705
So I did some digging, and it turns out the pkgconfig(...)
entries are listed as "provides" entries in the package metadata. Therefore there is not really anything special with the pkgconfig(...)
syntax; it's just another string in the eyes of dnf. In fact, a quick search in the dnf repository returns nothing at all:
$ rg 'pkg-?conf(ig)?'
# nothing printed
During package build, it seems like rpmbuild
will look for all *.pc
files declared by the spec file, and generate corresponding pkgconfig(...)
provides entries. Those entries are stored in the package metadata, which means they are trivially queryable even before installing the package.
To list the items provided by a package, run:
$ dnf repoquery --provides <PKG>
# for example (bzip2-devel, RHEL8)
$ dnf repoquery --provides bzip2-devel
bzip2-devel = 1.0.6-26.el8
bzip2-devel(x86-32) = 1.0.6-26.el8
bzip2-devel(x86-64) = 1.0.6-26.el8
pkgconfig(bzip2) = 1.0.6
To list the packages that provide an item, run:
$ dnf provides <ITEM>
# for example (pkgconfig(bzip2), RHEL8)
# note that parentheses need to be either quoted or escaped
# see https://unix.stackexchange.com/a/26064/375550
$ dnf provides 'pkgconfig(bzip2)'
bzip2-devel-1.0.6-26.el8.i686 : Libraries and header files for apps which will use bzip2
Repo : rhel-8-for-x86_64-baseos-rpms
Matched from:
Provide : pkgconfig(bzip2) = 1.0.6
bzip2-devel-1.0.6-26.el8.x86_64 : Libraries and header files for apps which will use bzip2
Repo : rhel-8-for-x86_64-baseos-rpms
Matched from:
Provide : pkgconfig(bzip2) = 1.0.6
Upvotes: 1