I recently tried installing an app from source (dwb on Debian Wheezy if it makes a difference). While installing, it would choke on some dependency problem, but to me it seemed I was meeting that dependency. I wasn't the only person with this problem. Which got me poking around in the project's config.mk.
In config.mk I found several blocks that looked like this:
REQPKG=foo
ifeq ($(shell pkg-config --exists $(REQPKG) && echo 1),1)
LIBS=$(REQPKG)
else
$(error Cannot find $(REQPKG))
endif
Which seems very counter intuitive to me. I searched and searched. Read the man page, consulted google. Read everything I could about pkg-config and found nothing. The man page is particularly frustrating as it simply lists '--exists' as a flag and gives no description (I guess it's as self explanatory as --help).
I began thinking that Debian's pkg-config had a bug where it returned inverse results. But, as it turns out 'pkg-config --exists' is supposed to return 0 (i.e. False) when the requested package is present.
Why is this? Wouldn't it produce cleaner code to return True/False or 1/0 indicating the presence of the required package? You could do this:
if (shell pkg-config --exists foo)
/*do things*/
else
/*throw error*/
endif
Instead of what looks to me like:
ifeq (($(not(True) && True)),True)
/*do things*/
else [...]
What am I missing about pkg-config? Does it act this way because it's a shell utility and some strange convention regarding them?
Also, why is the documentation so sparse? Am I missing a resource that would give the info I was looking for?
PS I don't have any real experience with C, so if my example code looks weird...
pkg-config --exists
doesn't create any output it simply returns with an exit code of 0
for success and 1
for failure.
&&
in the shell runs the right-hand side when the left-hand side returns success.
So that line is running pkg-config --exists
and iff it returns true (return code of 0
) it then echo
s a 1
as output. That 1
is then compared against the 1
in the ifeq
.
And as to why you can't do something simpler here the answer is because make (when not in target rules) doesn't deal with program return codes. Specifically $(shell)
pays the return code of the shell command being run no attention at all.
Personally, I'd probably have written that test as either:
ifeq ($(shell pkg-config --exists $(REQPKG); echo $?),0)
or something like
REQPKG=foo
REQPKG:=$(shell pkg-config --exists $(REQPKG) && echo '$(REQPKG)')
ifneq ($(REQPKG),)
LIBS=$(REQPKG)
else
$(error ...)
fi