[build2] Naming of library imports from pkg-config files

Boris Kolpackov boris at codesynthesis.com
Mon Jul 31 11:55:13 UTC 2023


Christopher Head via users <users at build2.org> writes:

> I’m trying to build against a system library (almost certainly built
> with something other than build2) that provides a properly installed .pc
> file (in /usr/lib64/pkgconfig, as one would expect). It’s working fine,
> but there’s something I haven’t been able to figure out from the
> documentation. In my buildfile, I have a line of this form:
> 
> import libs = foo%lib{bar}
> 
> “foo” is easy: it’s the basename of the .pc file (or at least it seems
> to be). But what am I supposed to write for “bar”? I haven’t been able
> to find where the meaning of that part is documented for .pc-file-based
> imports specifically. Experimentally, it seems as if I can write
> anything nonempty there, but that bothers me since I assume there’s
> probably some kind of rule or guideline I just haven’t found yet and
> may be silently breaking things.

You are approaching this from a special case (importing a system-installed
library with a .pc file) while I think it makes sense to start from the
general case (importing a target from a project) and then see how it's
made to fit the special case.

What we have in the import directive is a project-qualified target name
(this is documented in Target Importation[1]):

import libs = <project-name>%<target-type>{<target-name>}

To give a concrete example, take libevent[1]. The project name is libevent
and it provides a bunch of libraries (lib{event_core}, lib{event_extra},
etc). So we could write:

import libs = libevent%lib{event_core}
import libs += libevent%lib{event_extra}

Now back to the special case. The goal here is to take the project-qualified
library name and find the corresponding system-installed library name and
its .pc file (BTW, we don't search for .pc files directly, rather we first
find the .a/.so binary and then look for the corresponding .pc file; see
[3] for details if interested).

In the ideal world, the names of the .pc files would match the library
names and we would be able to derive their names from just <target-name>.
In the real world, however, the .pc file names are all over the place.
The canonical example of how detached things could be is zlib: the
library name is libz.a/libz.so but the .pc file name is not libz.pc,
and not even z.pc, but zlib.pc. As a result, when we search for the
.pc file, we first try <target-name> (with and without the lib prefix)
and then the <project-name> to cover outliers like zlib. So the
following works as expected:

import libs = zlib%lib{z}

Now to answer the question of what one should use for <project-name>
when the library only comes from the system (at least of now, this
can always change in the future). The recommendation is to use the
project name to which this library belongs. A distribution package
name is usually a good default. But sometimes you may also need to
make sure that it will allow you to find the .pc file, like in the
zlib case.

[1] https://build2.org/build2/doc/build2-build-system-manual.xhtml#intro-import
[2] https://cppget.org/libevent?f=full
[3] https://github.com/build2/libpkg-config#recommended-usage



More information about the users mailing list