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.