How to specify Makefile target building order without put any physical dependencies?

c++, makefile

Solution

If you're willing to rely on non-portable aspects of GNU make, you can use order-only prerequisites order-only prerequisites for this. That's the only way to do it other than the stamp file method you've already discovered.

Problem

I have been working on a C++ project that links to a .so(dynamic library) file. Let's assume that I have a target PROG which needs to link to a.so, and a.so is also built by me, specified in the following Makefile. ``` PROG_SRCS = prog.cpp PROG_OBJS = $(PROG_SRCS: %.cpp:%.o) all: PROG PROG: $(PROG_OBJS) liba.so $(LINK.cpp) -o $@ $(PROG_OBJS) -la LIBA_SRCS = liba/a.cpp LIBA_OBJS = $(LIBA_SRCS: %.cpp:%.o) liba.so: $(LIBA_OBJS) $(LINK.cpp) -shared -Wl.-soname,$@ -o $@ $^ ``` I have used auto-dependency-generation to get the .cpp files get their own dependency on the .h files. And prog.cpp includes a.h. But by this way, once I change a.cpp, liba.so would be remake, then PROG would be remake(relink), which is not what I want. I just change the implementation of liba.so, but not any interface definitions. PROG should just remake after I change a.h. I want to make that a.so should be built before PROG is built, but the changes of a.so would not incur the building of PROG. The following Makefile is the method I figured out, but with a slightly side-effect (generate a temporary file). ``` ORDER = /tmp/.ORDER all: PROG PROG: $(PROG_OBJS) $(ORDER) $(LINK.cpp) -shared -Wl,-soname,$@ -o $@ $(PROG_OBJS) -la $(ORDER): liba.so test -e $@ || touch $@ ``` In this way, every time liba.so gets remake, $(ORDER) gets remake too. But it only touch the file if it doesn't exist. Is there any way to specify this kind of dependency without any side-effect, e.g. creating a tmp file.

Original source