make - need VPATH for non-local files if implicit rules are used
Ran into a strange problem today, for some reason if a file isn’t in the current directory I need to have VPATH defined so that it points to the directory that contains the file(s) if the rule is implicit. For example, with the following structure where the Makefile is in a subdirectory below the location of the source file:
wink.c x/Makefile
and the Makefile file is:cat x/Makefile is:
wink@ic2d1:$ cat x/Makefile #VPATH=../wink.o: ../wink.cclean: rm *.o
If I now go into x and do a make –debug the we see the following:
wink@ic2d1:$ make --debug GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.This program built for x86_64-pc-linux-gnu Reading makefiles... Updating goal targets.... File `wink.o' does not exist. Must remake target `wink.o'. Successfully remade target file `wink.o'. make: Nothing to be done for `wink.o'.
So it knows it needs to”remake target ‘wink.o’” but then says “Successfully remade …” but it didn’t, wink.o isn’t built. If I now enable VPATH and Makefile is:
wink@ic2d1:$ cat x/Makefile VPATH=../wink.o: ../wink.cclean: rm *.o
Now make –debug does build wink.o and the output is:
wink@ic2d1:$ make --debug GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.This program built for x86_64-pc-linux-gnu Reading makefiles... Updating goal targets.... File `wink.o' does not exist. Must remake target `wink.o'. cc -c -o wink.o ../wink.c Successfully remade target file `wink.o'.
If you have an explicit rule everything works as expected as well:
wink@ic2d1:$ cat Makefile #VPATH=../wink.o: ../wink.c $(CC) $(CFLAGS) -c -o $@ $<clean: rm *.o
Now make –debug also builds wink.o and the output is:
wink@ic2d1:$ make --debug GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.This program built for x86_64-pc-linux-gnu Reading makefiles... Updating goal targets.... File `wink.o' does not exist. Must remake target `wink.o'. cc -c -o wink.o ../wink.c Successfully remade target file `wink.o'.
Another solution is don’t use Gnu Make but use pmake. Of course if the makefile isn’t compatible with pmake then this won’t work. On Ubuntu install the bin86 package via synaptic or “apt-get install pmake”.