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

Recursive call to makefile does not update object files

我有一个递归调用自身的生成文件。当我第一次 运行 make 时,目标文件被创建并链接得很好。但是,当我修改源文件并再次 运行 make 时,不会重新创建对象(make 表示目标是最新的)。我需要 运行 make clean 然后 运行 制作。这是我的 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第一次编译就好了。但是第二个returnsmake: "PROGNAME" is up to date.

在我看来,递归调用从未进行过。例如,如果我在调用 make 之前添加一个 echo,则 stdout 中不会显示任何内容。

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

提前致谢。

目标 PROGNAME 没有先决条件。

第一次make PROGNAME,Make发现没有这个文件,所以执行规则。

第二次(修改shared1.o后),Make发现PROGNAME已经存在,目标没有先决条件,所以它认为不需要重建目标。它不知道 PROGNAME 依赖于 shared1.o,因为你没有告诉它。

解决这个问题的方法不止一种。我建议你完全取消递归并使用 target-specific variable value:

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

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