考虑以下简单的 makefile:
#------------------------------#
# List all object files #
#------------------------------#
objects := main.o foo.o bar.o baz.o
#------------------------------#
# Define pattern rule #
# for *.c -> *.o #
#------------------------------#
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
#------------------------------#
# Define the rule to make #
# the end result #
#------------------------------#
.PHONY all
all: myApp.elf
myApp.elf: $(objects)
$(CC) $(objects) -o myApp.elf $(LFLAGS) $(LIBS)
如果你发出命令make all
, GNU make 将从目标开始myApp.elf
。它会考虑所有先决条件main.o
, foo.o
, bar.o
and baz.o
并尝试更新它们。
为此,make 使用 makefile 中间定义的模式规则。该模式规则扩展如下:
main.o: main.c
$(CC) -c $(CFLAGS) main.c -o main.o
foo.o: foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o: bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o
baz.o: baz.c
$(CC) -c $(CFLAGS) baz.c -o baz.o
到目前为止,一切都很好。但您可以清楚地看到缺少依赖项(包括 h 文件)。
我发现一些资料来源推荐以下方法:
#------------------------------#
# List all object files #
# and all dependency files #
#------------------------------#
objects := main.o foo.o bar.o baz.o
deps := $(objects:.o=.d)
#------------------------------#
# Define pattern rule #
# for *.c -> *.o #
#------------------------------#
%.o: %.c
$(CC) -c $(CFLAGS) -MMD -MP $< -o $@
#------------------------------#
# Define the rule to make #
# the end result #
#------------------------------#
.PHONY all
all: myApp.elf
myApp.elf: $(objects)
$(CC) $(objects) -o myApp.elf $(LFLAGS) $(LIBS)
-include $(deps)
我正在尝试理解这种方法。首先,GNU make 读取 makefile 并查找其他包含的 makefile(请参阅 GNU make 手册第 3.5 段“如何重新制作 Makefile”)。尝试更新它可以找到的每个包含的 makefile(在本例中为依赖文件main.d
, foo.d
, bar.d
and baz.d
) 在开始执行 makefile 之前。我在下图中总结了这一点:
确切地。我没有看到任何将依赖文件指定为目标的规则。
请帮助我了解接下来实际发生的事情。请将您的答案写成一系列逐步的事件。如果能够深入了解此事,那就太好了。
Note:
当然,-MMD
and -MP
编译命令中的参数(请参阅中间的模式规则)导致创建依赖文件。但这个模式规则的目标是object- 文件,而不是依赖性-files.
Note:
我错误地认为 GNU make 有一个隐式规则在这里被激活。但感谢您的评论和回答,我现在知道这是错误的:-)