What are the "serious" libraries?

Joe Nelson joe at begriffs.com
Sat Apr 11 02:56:24 UTC 2020


I'm working on the template for a portable Makefile which searches for
prerequisite libraries to link to the main program. Here's what I've
devised (using a made-up example that needs the ncurses and gpgme
libraries):

----------------------------------------

.POSIX:
SHELL=`command -v sh`

DEPS = 'ncurses >= 6.0' 'gpgme >= 1.13'

CFLAGS = -std=c99 -pedantic -Wall -Wextra

myapp : .lib.deps myapp.c
	$(CC) $(CFLAGS)  `pkg-config --cflags $(DEPS)` \
	      $(LDFLAGS) `pkg-config --libs $(DEPS)`   \
	      -o $@ myapp.c

.lib.deps :
	@pkg-config --exists --print-errors --short-errors $(DEPS) && \
	pkg-config --modversion $(DEPS) > $@

----------------------------------------

The idea is you put the library names in DEPS, along with version
constraints. Then there's a .lib.deps target which will only be created
if the libraries are present on the system in satisfactory versions. Any
target which requires the libraries can add .lib.deps as a dependency in
its make rule. In the build command, we add pkg-config's output along
with standard CFLAGS and LDFLAGS.

What's nice about this is it fails right away with a clear message when
libraries don't exist, rather than getting a confusing linker error
later on. If I change the ncurses version constraint to >=6.2, here's
how it fails:

$ make
Requested 'ncurses >= 6.2' but version of ncurses is 6.1.20180127
You may find new versions of ncurses at https://invisible-island.net/ncurses
make: *** [.lib.deps] Error 1

Another nice thing is how the pkg-config utility provides me with the
appropriate flags for my platform. On mac I'm getting these LDFLAGS:

	-L/opt/local/lib -lncurses -lgpgme -lassuan -lgpg-error

Other targets can continue to use the standard CFLAGS / suffix rules /
whatever.

Open question: how to specify lower AND upper version bounds for each
package? Is the following our best option?

DEPS = 'ncurses >= 6.0' 'ncurses < 7' 'gpgme >= 1.13' 'gpgme < 2'

This also raises the problem that if the project was previously built,
and afterward dependency libraries were upgraded too far, our .lib.deps
is already cached and make won't raise an error on the next build.


More information about the Friends mailing list