我有一个这样的makefile:
program: \
a/a.o \
b/b.o
$(CXX) $(CXXFLAGS) -o program \
a/a.o \
b/b.o
a.o: \
a/a.cpp \
a/a.h
$(CXX) $(CXXFLAGS) -c a/a.cpp
b.o: \
b/b.cpp \
b/b.h
$(CXX) $(CXXFLAGS) -c b/b.cpp
所以在makefile的目录中我有两个子目录a和b 它们分别包含a.h,a.cpp和b.h,b.cpp。 问题是如果我修改.cpp文件,发出make重建目标程序 但如果我修改.h文件,请不要重建除了
之外的任何内容make: `program' is up to date.
我无法理解为什么,因为.h文件位于先决条件行中 以及.cpp文件。 有趣的是,如果我在像
这样的目标文件目标上发出一个make$ make a.o
相反,对a / a.h的修改 检测到目标a / a.o重建。 问题在哪里?
答案 0 :(得分:1)
您之后添加到问题中的子目录确实会导致问题。目标program
取决于a/a.o
和b/b.o
,但没有明确的规则来制作.o
个文件 - 只有目标a.o
和{{ 1}}存在,但那些不在子目录中。
因此,b.o
会查找构建make
和a/a.o
的隐式规则。该规则确实存在,您将在运行b/b.o
时看到它被找到。该隐式规则仅取决于make -d
,而不取决于a/file_a.cpp
。因此,根据该隐式规则更改a/file_a.h
会使a/file_a.cpp
过期,而a/a.o
则不会。{/ p>
作为参考,make用户手册有一个Catalogue of Implicit Rules部分。这也解释了您可以使用参数a/file_a.h
来避免这种隐式行为。如果您使用该标准,则会看到--no-builtin-rules
找不到要制作make
和a/a.o
的任何规则。
最后,运行b/b.o
将运行makefile中定义的目标make a.o
的配方。该目标确实以a.o
为先决条件,因此对该文件的任何更改都将导致重新编译。但实质上,这与目标a/a.h
无关,目标program
具有不同的先决条件。