0

这是我的 Makefile 的相关部分。

...
LIBS = gc ft

vpath %.a $(LIBS:%=lib%)

all:
    $(MAKE) $(NAME)

$(NAME): $(LIBS:%=lib%.a) $(OBJS) | libs
    $(CC) $(CFLAGS) $(OBJS) -o $(NAME) $(LDFLAGS)

-include $(DEPENDENCIES)
$(OBJS_DIR)/%.o: %.c $(OBJS_DIR)/debug$(DEBUG) | $(OBJS_DIR)
    $(CC) $(CFLAGS)  $(INCLUDES_DIR:%=-I %) -c $< -o $@

$(OBJS_DIR):
    $(MKDIR) $@

libs: $(LIBS:%=lib%.a)
    $(foreach LIB, ${LIBS}, ${MAKE} -C lib${LIB} ;)

lib%.a:
    $(MAKE) -C $(@:%.a=%)
...

我的问题是,每当我触摸其中一个库中的文件时,都要重新编译该库,但我必须再次运行 make 以使其重新链接目标文件。
我究竟做错了什么 ?
提前致谢。

---编辑---
所以现在我的 Makefile 看起来像这样。

...
all: $(NAME)

$(NAME): $(OBJS) libft/libft.a libgc/libgc.a
    $(CC) $(CFLAGS) $(OBJS) -o $(NAME) $(LDFLAGS)

-include $(DEPENDENCIES)
$(OBJS_DIR)/%.o: %.c $(OBJS_DIR)/debug$(DEBUG) | $(OBJS_DIR)
    $(CC) $(CFLAGS)  $(INCLUDES_DIR:%=-I %) -c $< -o $@

$(OBJS_DIR):
    $(MKDIR) $@

libft/libft.a:
    $(MAKE) -C libft

libgc/libgc.a:
    $(MAKE) -C libgc
    ...

它不再重新链接,但如果更改我的库源中的某些文件,它也不会重新编译。

4

1 回答 1

0

您不能使用 vpath 来查找生成的文件。它只能用于定位源文件(始终存在)。有关详细信息,请参阅http://make.mad-scientist.net/papers/how-not-to-use-vpath/

您需要使用生成的库的真实路径作为先决条件,以便在 make 检查其修改时间时知道它们已更改。

预计到达时间

您正在使用递归制作模型进行构建。这意味着此 makefile 不知道您的库是否已过时:这里您没有列出它们的任何先决条件,因此就 make 而言它们是否存在,它们是最新的。

相反,您已将有关库是否为最新的知识降级到子目录 makefiles 中。这意味着为了知道它们是否是最新的,您必须运行该子制作以便它可以检查。这意味着您总是想运行子制作,它只会在库过时时更新它们。一个简单的方法是使用FORCE目标

libft/libft.a: FORCE
        $(MAKE) -C libft

libgc/libgc.a: FORCE
        $(MAKE) -C libgc

FORCE:;
于 2021-09-25T17:40:29.527 回答