Q:

GNU make Pattern Rule Fails with 'Main.cpp"

I've got a general-purpose makefile that I've successfully used for small (personal) projects before, as below:
#Makefile to compile a folder's contents into a program.

PROGNAME := MyProgram

LIBRARIES := 

CXX := g++ --std=c++11
INCLUDES := -Isrc -Ihdr
VPATH := src:hdr

CPP_FILES := $(wildcard src/*.cpp)
OBJ_FILES := $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES))

$(PROGNAME): $(OBJ_FILES)
    $(CXX) $(INCLUDES) $(LIBRARIES) $^ -o $@ $(ROOTFLAGS)

#Automatically generate dependencies (-MM), change the target to be the
# object file (-MT) and output it to the dependency file (-MF).
%.d: src/%.cpp
    $(CXX) $(INCLUDES) -MM -MT '$(patsubst src/%.cpp,obj/%.o,$<)' $< -MF $@

obj/%.o: src/%.cpp %.d hdr/%.h
    echo $@
    $(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)

.PHONY: clean

clean:
    rm obj/*.o $(PROGNAME)

This is designed for the following directory structure:
ParentFolder/
    Makefile
    hdr/
        file1.h
        ...
    src/
        file1.cpp
        ...
    obj/

I gave the makefile to a colleague and they found it didn't work - after some investigation, the cause of the problem seems to be that they had a source file called main.cpp in src/, which when running make would give the following error:
make: *** No rule to make target `obj/main.o', needed by `MyProgram'.  Stop.

If I rename main.cpp to something else (e.g. test.cpp) then the makefile works as expected.
What is the cause of this behaviour? I've looked through the GNU Make Manual but did not find anything regarding special treatment of files called main.* (in fact, some of the examples use it).
While trying to fix the problem, I found that defining an explicit rule for main.o meant that it would be found - therefore, I presume it's an interaction with the main name and pattern-based rules, but I have not been able to find what that may be.

A:

The trouble is that this rule:
obj/%.o: src/%.cpp %.d hdr/%.h
    echo $@
    $(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)

requires a corresponding header file. I suspect that there is no hdr/main.h, and Make has no way to build one, so when it is searching for a way to build obj/main.o it considers this rule, rejects it, and finds no other.
I suggest you add another pattern rule (after this one) to handle source files without matching header files:
obj/%.o: src/%.cpp %.d
    echo $@
    $(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)

(P.S. Your dependency handling is a little odd and appears to be vestigial -- you generate dependency files and never use them. We can help you with that, once you're building main.o correctly.)

