This rule is wrong:
$(OBJECTS): $(SOURCES) makefile
What does this expand to? If you have sources src/foo.cpp
, src/bar.cpp
, and src/baz.cpp
then it will be this:
obj/foo.o obj/bar.o obj/baz.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
This is an extremely common problem: people seem to have this idea that make will somehow massage all these targets and prerequisites to match them up somehow so that each object file depends only on the corresponding source file.
But, make does NOT do that. The above rule is exactly identical to writing all these rules:
obj/foo.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
obj/bar.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
obj/baz.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
Now maybe you can see why you see the behavior you do: the first prerequisite for every target is exactly the same file src/foo.cpp
so when you use the $<
automatic variable, that's the one you always get.
You have to write ONE rule that builds ONE object, then let make figure out how to apply that rule for all the appropriate objects.
So, to build one object file from one source file you can use a pattern rule like this:
obj/%.o : src/%.cpp makefile
@mkdir -p obj
$(CXX) $(WARNING) $(CXXFLAGS) -MMD -MP -c $< -o $@
That's all you need.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…