我之前有一个通用的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)
这是为以下目录结构设计的:
ParentFolder/
Makefile
hdr/
file1.h
...
src/
file1.cpp
...
obj/
我把makefile给了同事,他们发现它没有用 - 经过一些调查后,问题的原因似乎是他们在{{1}中有一个名为main.cpp
的源文件运行src/
时会出现以下错误:
make
如果我将make: *** No rule to make target `obj/main.o', needed by `MyProgram'. Stop.
重命名为其他内容(例如main.cpp
),则makefile按预期工作。
这种行为的原因是什么?我查看过GNU Make Manual但没有找到任何关于文件test.cpp
的特殊处理的事情(事实上,有些例子使用它)。
在尝试解决问题时,我发现为main.*
定义一个明确的规则意味着它会被找到 - 因此,我认为它与main.o
名称相互作用,基于模式的规则,但我无法找到可能的内容。
答案 0 :(得分:1)
麻烦在于这条规则:
obj/%.o: src/%.cpp %.d hdr/%.h
echo $@
$(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)
需要相应的头文件。我怀疑没有hdr/main.h
,并且Make无法构建一个,所以当它搜索构建obj/main.o
的方法时,它会考虑这个规则,拒绝它,并且找不到其他的。< / p>
我建议您添加另一个模式规则(在之后)以处理源文件而不匹配头文件:
obj/%.o: src/%.cpp %.d
echo $@
$(CXX) $(INCLUDES) -o $@ -c $< $(ROOTFLAGS)
(PS你的依赖处理有点奇怪,似乎是残留的 - 你生成依赖文件,从不使用它们。一旦你正确构建main.o
,我们可以帮助你。)