I had a strange bug that I managed to reduce to the following. I have a folder with only two empty files: a Makefile and a cpp file:
$ ls -la
total 8
drwxrwxr-x 2 erelsgl erelsgl 4096 Mar 3 20:12 .
drwxrwxr-x 13 erelsgl erelsgl 4096 Mar 3 20:10 ..
-rw-rw-r-- 1 erelsgl erelsgl 0 Mar 3 20:12 Demo.cpp
-rw-rw-r-- 1 erelsgl erelsgl 0 Mar 3 20:09 Makefile
$ cat Makefile
$ cat Demo.cpp
When I run make I get the expected result:
$ make
make: *** No targets. Stop.
But when I run make Demo.o I get a very strange outcome:
$ make Demo.o
clang++-5.0 -std=c++17 -c -o Demo.o Demo.cpp
make: clang++-5.0: Command not found
<builtin>: recipe for target 'Demo.o' failed
make: *** [Demo.o] Error 127
The command "clang++-5.0 -std=c++17" were actually in the Makefile some days ago, but I have long since then replaced it with clang++-9. And now, as you can see, the Makefile is entirely empty. Why is make still running these old commands?
EDIT: The same thing happens when I change the Makefile to contain these two lines:
%.o: %.cpp xxx.h
clang++-9 --compile $< -o $@
when the file xxx.h does not exist. This is very confusing: I run make Demo.o and it is built with clang++-5.0 instead of clang++-9!
CXXand/orCXXFLAGSdefined in your environment? if so,makeis likely using those as part of a default rulemake -rormake --no-builtin-rulesshould disable builtin rules altogether. However you should always be able to override environment variables at run time ex.CXX=g++ CXXFLAGS= make Demo.o%.o: %.c\n clang...andxyz.o: xxx.h yyy.h ...(A single line: no recipe).