对makefile的递归调用不会更新目标文件

我有一个带有递归调用的makefile。 当我第一次运行make时,会创建目标文件并将其链接得很好。 但是当我修改源文件并再次运行make时,不会重新创建对象(make表示目标是最新的)。 我需要运行make clean然后运行make。 这是我的makefile的简化版本,我认为包括所有相关信息:

 PCC = mpicc #Locations OBJDIR = ./objects #Compiler and linker flags FLAGS = -g -lm #Object files SHAREDOBJS = $(addprefix $(OBJDIR)/,shared1.o shared2.o) SPECIFICOBJS = $(addprefix $(OBJDIR)/,specific1.o specific2.o) #How to compile and link $(OBJDIR)/%.o: %.c $(PCC) -c $*.c $(EXTRA_FLAGS) -o $(OBJDIR)/$*.o PROGNAME: $(MAKE) $(MAKEFLAGS) EXTRA_FLAGS="$(FLAGS)" PROGNAME_TARGET PROGNAME_TARGET: $(SHAREDOBJS) $(SPECIFICOBJS) $(PCC) $(SHAREDOBJS) $(SPECIFICOBJS) $(EXTRA_FLAGS) -o PROGNAME 

所以运行make PROGNAME第一次编译就好了。 但第二个回报make: "PROGNAME" is up to date.

在我看来,递归调用永远不会发生。 例如,如果我在调用make之前添加一个echo ,则stdout不会显示任何内容。

为什么会这样? 为什么在递归调用中没有检查源文件的时间戳? 我不明白为什么递归破坏了对源文件的依赖。

提前致谢。

目标PROGNAME没有先决条件。

第一次make PROGNAME ,Make会发现没有这样的文件,因此它会执行规则。

第二次(在修改shared1.o ),Make看到PROGNAME已经存在,并且目标没有先决条件,因此它看不到重建目标。 它不知道PROGNAME依赖于shared1.o ,因为你没有告诉它。

解决这个问题的方法不止一种。 我建议你完全取消递归并使用特定于目标的变量值 :

 PROGNAME: EXTRA_FLAGS="$(FLAGS)" PROGNAME: PROGNAME_TARGET 

(您的目标名称可以改进,但可以等待。)