GNU Makefile 包含文件(重新)制作命令

GNU Makefile Included file (re-)making order

我有一个大致如下结构的 Makefile:

SRC = some_file.c

include component.mk

OBJ = $(SRC:.c=.d)
DEP = $(SRC:.c=.d)

ifneq ($(MAKECMDGOALS),clean)
include $(DEP)
endif

all: some_file.o

$(DEP): component.mk

component.mk:
    echo "CPPFLAGS += -Iheaders_dir/" > $@
%.o: %.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
%.d: %.c
    $(CC) -MM -MT $(@:.d=.o) $(CPPFLAGS) $(CFLAGS) $< -o $@

clean:
    $(RM) $(OBJ) $(DEP) component.mk

问题是 .d 文件由于缺少 $(CPPFLAGS) 中的定义而无法创建;然而,这些定义是在 component.mk 中定义的,它包含在上面。

似乎 make 试图(重新)制作 missing/modified 包括 甚至在包括那些不需要(重新)制作的东西之前 .它似乎只是以相反的顺序 (??) 执行包含,因为它们出现在 Makefile 和(重新)沿途制作丢失的文件。

除了将 include component.mk 移动到 include $(DEP) 下方之外,这里还有其他解决方案吗,因为这似乎破坏了我实际 Makefile.

中的其他内容

编辑: 实际上,这似乎只有当 component.mk 也由 Makefile 中的某些规则(重新)制作时才会出现问题,所以 make 正确地包括那些不需要(重新)制作的文件,那些确实需要(重新)制作的文件。

编辑: 即使这样似乎也无济于事:

$(DEP): component.mk

虽然 component.mk 是在 .d 文件之前制作的,但这似乎并不影响包含顺序。将 include component.mk 移至 include $(DEP) 之下似乎也无济于事,make 似乎在实际包含它们之前尝试(重新)制作所有包含物。

您的问题是因为 component.mk 是包含的 makefile,而 *.d 文件也包含在 makefile 中。 make 总是尝试重新构建包含的 makefile,但您不能对此强制执行命令。如果您对 component.mk 的所有期望是向 CPPFLAGS 添加选项,为什么不简单地使用特定于目标的变量,而不是摆脱 component.mk?

SRC = some_file.c

OBJ = $(SRC:.c=.o)
DEP = $(SRC:.c=.d)

ifneq ($(MAKECMDGOALS),clean)
include $(DEP)
endif

all: some_file.o

%.o %.d: CPPFLAGS += -Iheaders_dir/

%.o: %.c %.d
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

%.d: %.c
    $(CC) -MM -MT $(@:.d=.o) $(CPPFLAGS) $(CFLAGS) $< -o $@

clean:
    rm -f $(OBJ) $(DEP)

另一种选择是使用递归 make 调用(第一个构建 component.mk 并调用第二个),但它可能会变得毫无用处。

注意:我修正了 OBJ 定义中的错字,并在 %.o 的先决条件中添加了 %.d