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

时间:2015-01-28 17:57:13

标签: c makefile gnu-make

我有一个带有递归调用的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中不会显示任何内容。

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

提前致谢。

1 个答案:

答案 0 :(得分:3)

目标PROGNAME没有先决条件。

第一次make PROGNAME时,Make看到没有这样的文件,因此它执行规则。

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

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

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

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