Makefile GNU生成模式规则因';Main.cpp“;

Makefile GNU生成模式规则因';Main.cpp“;,makefile,Makefile,我有一个通用的makefile,我以前曾成功地用于小型(个人)项目,如下所示: #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 := $

我有一个通用的makefile,我以前曾成功地用于小型(个人)项目,如下所示:

#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)
我把makefile给了一位同事,他们发现它不起作用-经过一些调查,问题的原因似乎是他们在
src/
中有一个名为
main.cpp
的源文件,当运行
make
时会出现以下错误:

make: *** No rule to make target `obj/main.o', needed by `MyProgram'.  Stop.
如果我将
main.cpp
重命名为其他名称(例如
test.cpp
),则生成文件将按预期工作

这种行为的原因是什么?我查阅了GNU Make手册,但没有找到任何关于名为
main.*
(实际上,一些示例使用它)的文件的特殊处理的内容


在试图解决此问题时,我发现为
main.o
定义一个显式规则意味着它将被找到-因此,我假设它是与
main
名称和基于模式的规则的交互,但我无法找到可能的规则。

问题在于此规则:

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

(请注意,您的依赖项处理有点奇怪,而且似乎有缺陷——您生成依赖项文件,但从不使用它们。一旦您正确构建
main.o
),我们可以帮助您完成这项工作。)

啊,非常感谢!添加规则解决了问题—事实证明,当我将
main.cpp
重命名为
test.cpp
时,首先查看了另一个以s开头的文件,该文件编译失败,因此我从未看到
test.o
的“无匹配规则”错误,并认为问题已经解决。我很乐意在依赖文件方面得到帮助。我认为我使用它们是正确的,但也许不是。我应该补充一点,我根据发现的一个修改了我的Makefile
obj/%.o: src/%.cpp %.d hdr/%.h
    echo $@
    $(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)
obj/%.o: src/%.cpp %.d
    echo $@
    $(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)