这条规则是错误的:
$(OBJECTS): $(SOURCES) makefile
这扩展到什么?如果你有货源src/foo.cpp
, src/bar.cpp
, and src/baz.cpp
那么就会是这样的:
obj/foo.o obj/bar.o obj/baz.o : src/foo.cpp src/bar.cpp src/baz.cpp makefile
这是一个极其常见的问题:人们似乎有这样的想法,即 make 会以某种方式处理所有这些目标和先决条件,以某种方式将它们匹配,以便每个目标文件仅依赖于相应的源文件。
但是,make 并没有这样做。上述规则与编写所有这些规则完全相同:
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
现在也许您可以明白为什么会看到您所做的行为:每个目标的第一个先决条件是完全相同的文件src/foo.cpp
所以当你使用$<
自动变量,这是你总是得到的。
您必须编写一条构建一个对象的规则,然后让 make 弄清楚如何将该规则应用于所有适当的对象。
因此,要从一个源文件构建一个目标文件,您可以使用如下模式规则:
obj/%.o : src/%.cpp makefile
@mkdir -p obj
$(CXX) $(WARNING) $(CXXFLAGS) -MMD -MP -c $< -o $@
这就是你所需要的。