On Tue, 2021-01-12 at 12:35 +0000, jerem...@pdp10.guru wrote: > > After a quick squiz at your makefile I’m guessing line 42 should > > not read > > -o bin/M2-Planet > > But rather > > -o M2-Planet > > Or even better: > > -o $@ > > No? > > Similar changes for line 67 are probably in order > > No that does not correct the issue reported. > As bin is in the VPATH on line 19.
Whether bin is on VPATH is not relevant. That's not how VPATH works: VPATH is _only_ useful for locating _source_ files (files that always exist). It cannot be used for locating generated files. For more details read this: http://make.mad-scientist.net/papers/how-not-to-use-vpath/ > Further it would break the all of the tests. > As they expect bin/M2-Planet. Your rule MUST ALWAYS build the target file that you told make they would build. It's invalid, and will lead to breakage, if you tell make that your recipe will create M2-Planet but it instead creates bin/M2- Planet, which is a completely different file. As a result, as Malcolm says, all recipes should build $@ and never some alternate version of that (like bin/$@ or whatever). If you really need the generated file to be bin/M2-Planet then your target should build bin/M2-Planet: all: bin/M2-Planet bin/M2-Planet: ... $(CC) ... -o $@ If you want to be able to run "make M2-Planet" you can create a shortcut like this: M2-Planet: bin/M2-Planet Further, it's not going to work reliably to write a make command line like this: > make clean test -j42 That's because make will build the command line targets in parallel as well, which means (because "clean" is not a prerequisite so make doesn't know to make sure it's completed first) "test" and "clean" will be run at the same time, which could mean that things that "test" is creating (such as bin/M2-Planet) will be deleted by "clean". The simplest solution is to run this instead: make clean && make test -j42 If you really want to be able to run "make clean test" then you'll have to do something fancy: ensure clean is a prerequisite of all the targets but ONLY when specified on the command line. You can use this: CLEAN_TARGET := $(filter clean,$(MAKECMDGOALS)) which will be set to "clean" if "clean" was a target on the command line, or the empty string if not. Then you have to add $(CLEAN_TARGET) to all the targets (it's not enough to make it a prerequisite of "test" because that doesn't make it a prerequisite of the things "test" depends on). In your makefile it may be enough to list $(CLEAN_TARGET) as a prerequisite of M2-Planet because it seems most everything depends on that, since you compile from source rather than building object files.