Makefile第一个规则目标

我正在尝试使用简单的三个文件来学习make

foo.h中

 #ifndef __foo_H_ #define __foo_H_ void print(); #endif 

foo.c的

 #include  #include "foo.h" void print() { printf("Hello World !"); } 

main.c中

 #include "foo.h" int main() { print(); return 0; } 

当我使用以下makefile时,一切运行正常

生成文件

 CC = gcc CFLAGS = -I. DEPS = foo.h OBJ = foo.o main.o .PHONY: clean main: $(OBJ) gcc -o $@ $^ $(CFLAGS) %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) clean: rm *.o 

以上是有效的,因为默认情况下make运行第一个目标(我基本上到处读取)。

如果我使用下面的makefile

 CC = gcc CFLAGS = -I. DEPS = foo.h OBJ = foo.o main.o .PHONY: clean clean: rm *.o main: $(OBJ) gcc -o $@ $^ $(CFLAGS) %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) 

在上面的makefile上调用make只运行make clean因为make默认运行第一个规则。

问题出在这个makefile上

 CC = gcc CFLAGS = -I. DEPS = foo.h OBJ = foo.o main.o .PHONY: clean %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) main: $(OBJ) gcc -o $@ $^ $(CFLAGS) clean: rm *.o 

在上面的makefile中使用make得到

 gcc -c -o foo.o foo.c -I. gcc -c -o main.o main.c -I. gcc -o main foo.o main.o -I. 

为什么不构建.o文件并停止,因为它是第一个目标,为什么还要继续构建main? 我没有在第一条规则中指定构建main的地方。

“第一个目标”规则仅计算明确的目标。 它不计算隐式目标,例如后缀规则或模式规则。

考虑一下:如何确定它应该构建.o文件? 它应该构建哪些.o文件? 如何理解它应该在变量OBJ构建那些,而不是任何其他变量?

我正在寻找手册的一个很好的部分来指出你,但没有发现任何具体和具体的使用。 据我所知,问题的答案是模式规则不是目标,默认目标必须如其名称所示,是目标。

如果您使用的是静态模式规则(确实定义了目标),那么您的期望几乎是正确的,因为make将选择第一个这样的文件,并在这种情况下构建(不是所有的,就像您预期的那样)。