I have a C++ project that produces a shared library and I want to add tests to it, in a separate executable that dynamically links with the library. So the relevant part of the Makefile looks like this:
libstuff.so: stuff.o
$(LINK_SHARED)
test: LDLFAGS += -L$(CURDIR) -Wl,-rpath=$(CURDIR) -lstuff
test: libstuff.so
test: test.o
$(LINK)
check:: test
./test
LINK_SHARED
and LINK
are defined to invoke the compiler in an appropriate fashion. The rpath
magic is to make sure the dynamic linker links with the exact version of the library I just compiled and want to test, not with the installed one.
The problem is that by default all target-specific variables are inherited by the prerequisites, so libstuff.so
gets -lstuff
in its LDFLAGS
and the linker complains that it can't find it (duh!).
Is there a way to say that I don't want a specific prerequisite to inherit my variables and be used for dependency purposes only?
There are some hacky workarounds that I don't like. For example I can override LDFLAGS=
in the libstuff.so
specification, but then it wouldn't pick up the global LDFLAGS if I decide to define them.
There's a "private" modifier on variables, which would solve my particular problem with LDFLAGS
but I'd still have other things like CFLAGS
inherited (and I want it to be inherited by other prerequisites like the .o
files). I want something like a private modifier on a prerequisite instead.
I can make the test executable statically link with the object files I'm testing, but I actually like the fact that I'm testing that I linked the shared object properly.
I can force make to start from a clean slate variable-wise by using recursive make invocation:
.PHONY: test_prerequisites
test_prerequisites:
$(MAKE) testlib.so
Marking the target as phony makes it execute every time (as it should, since the original make can't know about its real dependencies or it would try to make them itself). An unfortunate side effect is that the test
executable itself is rebuilt every time (though it's tolerable, and at least testlib.so
is not rebuilt unless necessary).