1
votes

Consider the following Makefile (it is not particularly nice, but a MWE):

SRC := $(wildcard *.cpp)
TST := $(addprefix test_, $(SRC:.cpp=))

.PRECIOUS: %.exe

%.o: %.cpp
    g++ -c -o $@ $^

%.exe: %.o
    g++ -o $@ $^

test_%: %.exe
    ./$< "Test"

.PHONY: clean $(TST)

clean:
    rm *.exe

Its goal is to test .exe files which are built from .cpp files of the same name. For example, foo.cpp will be built to become foo.exe, which will be executed with a test argument, like ./foo.exe "Test". The test target name is test_foo for foo.cpp/foo.exe.

If I include all test targets (in the variable $(TST)) as dependencies to the .PHONY target, as above, they show up during auto-completion in bash, but they do not work, i.e., make always states make: Nothing to be done for 'test_foo'. even when foo.cpp has been changed.

Conversely, if I remove $(TST) from the .PHONY target, changes to foo.cpp trigger a build and a test process, as desired. However, the target does not show up during auto-completion in bash.

My question is: Is there a way to convince make that all test_ targets are phony targets without losing the ability to actually build and execute the test? According to the documentation, file dependencies should not be prerequisites for non-file targets. make -d test_foo shows

[..]
Considering target file 'test_foo'.
 File 'test_foo' does not exist.
 Finished prerequisites of target file 'test_foo'.
Must remake target 'test_foo'.
Successfully remade target file 'test_foo'.
make: Nothing to be done for 'test_foo'.

It seems that make does not even look at the prerequisites. This does not change even when I make them order-first prerequisites. Is there a way to get make to process the prerequisites as it does when I am not adding my test_ targets to .PHONY?

1

1 Answers

1
votes

Looks like you need a static pattern rule to make $(TST) an explicit list of targets in the pattern rule. This worked:

$(TST) : test_%: %.exe
    ./$< "Test"

My guess about the reason is – it's insufficient to declare something .PHONY for make to consider it actually being a target worth matching a pattern. Don't know what is the reasoning in bash-completion.