使文件突然对空目标感到困惑

Make file suddenly confused about an empty target

为了说明这个问题,我的 Makefile 被精简到最低限度,看起来像:

CC := cc
CFLAGS :=

AIOLIB := -lrt
MATHLIB := -lm

LIBS := $(LIBS) $(AIOLIB) $(MATHLIB)

CAW_EXECS := cawser_tim
ALL_EXECS := $(CAW_EXECS)

# Targets:

calc_and_write: cawser_tim    # < --- make gets confused with this target

# ========================= CALC AND WRITE ===================================
cawser_tim: calc_and_write_timing.c
        -$(CC) $(INCS) $(DEFS) $(CFLAGS) -o $@ $^ $(LIBS)

clean:
        -rm $(ALL_EXECS)

通常 calc_and_write 目标除了 cawser_tim 之外还有几个先决条件。出于说明目的,我已将其剥离。 'make' 构建 cawser_tim 没有问题。但后来它得到的想法是,除了 cawser_tim 之外,它还应该以某种方式生成一个文件 calc_and_write 并尝试根据

这样做
cc     calc_and_write.c cawser_tim   -o calc_and_write

当然,这完全失败了。在更大的Makefile中,这是其中的一部分,整个构建停止了。

现在,我通过引入 .PHONY 目标解决了这个问题:

.PHONY : calc_and_write clean
calc_and_write: cawser_tim

这不是我几乎从未做过的事情。 (我想我真可耻。)

所以我解决了这个问题,但这是我的问题:我从来没有见过这种事情发生。在我较大的 Makefile 中,我实际上还有其他类似于 calc_and_write 的空目标,它们构建得很好。谁能告诉我为什么 make 突然对这个目标如此“敏感”?顺便说一句,我的目录中实际上没有名为“calc_and_write”的文件;至少,这不是问题。

有无文件无关calc_and_write。重要的是有没有文件calc_and_write.c。好像有这样一个文件。

因为你的目标 calc_and_write 不是假的,make 会尝试构建它。如果它找不到任何构建它的规则,那么它只会说“哦好吧”而不做任何事情。但是,如果它可以找到要使用的规则,那么它将 运行 规则。

在这种情况下,make 找到了从源文件构建程序的内置规则:

% : %.c
        ...

并且它发现有一个名为 calc_and_write.c 的文件,所以这个内置规则匹配,因此 make 尝试使用它来创建程序 calc_and_write.