对 Makefile 中的“-include”模式规则感到困惑

Confused about "-include" pattern rule in Makefile

提问人:Leo 提问时间:2/15/2023 更新时间:2/15/2023 访问量:57

问:

A1_SRC并定义我将编译的源代码 C。 并共享相同的标头和 .我在下面附上我的 Makefile:A2_SRCA1_SRCA2_SRCconst.hvar.h

EXEC=../bin
OBJ=../obj

CC=mpicc
CFLAGS=-O3 -Wall -traceback
LFLAGS=-lm -lfftw3 -lstdc++ -lmpi

$(OBJ)/%.o: %.c
    $(CC) -c $(CFLAGS) $< -o $@
    $(CC) $(CFLAGS) -MM $*.c > $(OBJ)/$*.d

A1_OBJ = $(A1_SRC:%.c=$(OBJ)/%.o)
A2_OBJ = $(A2_SRC:%.c=$(OBJ)/%.o)

A1_SRC = \
        test.c \
        alloc.c \
        func.c

A2_SRC = \
        test1.c \
        test2.c

A1: $(A1_OBJ) const.h var.h
    $(CC) $(LFLAGS) $(A1_OBJ) -o $(EXEC)/test_A1

A2: $(A2_OBJ) const.h var.h
    $(CC) $(LFLAGS) $(A2_OBJ) -o $(EXEC)/test_A2

all: A1 A2

.PHONY: clean
clean:
    rm -f $(OBJ)/*.o $(OBJ)/*.d $(EXEC)/*

install: clean all

-include $(A1_OBJ:$(OBJ)/.o=$(OBJ)/.d) $(A2_OBJ:$(OBJ)/.o=$(OBJ)/.d)

传统上,我们以一种简单的方式定义一个模式规则来从代码编译文件。在这个 Makefile 中,.o.c

$(CC) -c $(CFLAGS) $< -o $@, ,A1_OBJ = $(A1_SRC:%.c=$(OBJ)/%.o)A2_OBJ = $(A2_SRC:%.c=$(OBJ)/%.o)

才能实现这个目标。下一步是执行链接生成可执行文件,这是通过

$(CC) $(LFLAGS) $(A1_OBJ) -o $(EXEC)/test_A1,$(CC) $(LFLAGS) $(A2_OBJ) -o $(EXEC)/test_A2

但是,我不明白为什么它还使用?然后 Makefile 直到最后一行才使用这些文件......最后一行是什么意思,它与文件有什么关系?$(CC) $(CFLAGS) -MM $*.c > $(OBJ)/$*.d.d-include $(A1_OBJ:$(OBJ)/.o=$(OBJ)/.d) $(A2_OBJ:$(OBJ)/.o=$(OBJ)/.d).o

此外,在此模式规则中:

A1: $(A1_OBJ) const.h var.h
    $(CC) $(LFLAGS) $(A1_OBJ) -o $(EXEC)/test_A1

为什么我们需要两条线?我不明白为什么我们应该把第一行放在这里?$(A1_OBJ) const.h var.h

我希望有经验的程序员可以帮助回答我的问题。这将帮助更多与我有同样疑问的人找到解决方案。

c makefile gnu-make

评论

1赞 Jonathan Leffler 2/15/2023
该指令的意思是“尝试包含命名的文件(如果存在);如果它们不存在,则不会生成错误”。该选项会导致 GCC 为源创建文件。下次运行生成时,编译器将读取文件,然后检查依赖项。-include-MMxyz.dxyz.cxyz.d
0赞 MadScientist 2/15/2023
我建议你阅读 make.mad-scientist.net/papers/......看看它是否提供了任何有用的见解。
0赞 Andy J 3/13/2023
我不知道这个答案是否有帮助;它引用了 MadScientist 关于 .此外,您可能希望将目标放在 和 之上,或者没有任何参数只会使 .-includeallA1A2makeA1

答: 暂无答案