生成文件:自动生成二进制文件的依赖项

Makefile: automatic generation of dependencies for binaries

本文关键字:依赖 二进制文件 自动生成 文件      更新时间:2023-10-16

我想在项目的 Makefile 中"完全"自动化依赖生成过程。到目前为止,我已经按照这个关于自动依赖项的教程进行操作,它工作得很好。只有一个问题:这仅适用于头文件依赖项,因此它会自动检测 bin_1.o 是否依赖于 header_1.h 和 header_2.h。但是,我可以直接将头文件依赖项转换为对象文件依赖项。比如说,其中一个自动生成的依赖项文件说

bin_1.o: bin_1.cpp header_1.h header_2.h

因此,在链接步骤中,我可以立即得出结论,我需要将文件bin_1.o、header_1.o 和 header_2.o 链接在一起,以便生成二进制bin_1。换句话说,bin_1的相应依赖项文件应该具有

bin_1: bin_1.o header_1.o header_2.o

这正是我努力实现的目标。上面描述的翻译是由一个小的python脚本完成的,extract_dependencies.py,我的Makefile的精简版本看起来像这样:

binaries = bin_1 bin_2 bin_3
SRCS := $(wildcard *.cpp)
all: $(binaries)
# dependencies
DEPDIR := .d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) -c
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
GENERATE_BINARY_DEPS = python extract_dependencies.py $(DEPDIR)/$*.d > $(DEPDIR)/$*.bin.d
$(DEPDIR)/%.d: ;
$(DEPDIR)/%.bin.d: ;
.PRECIOUS: $(DEPDIR)/%.d $(DEPDIR)/%.bin.d
$(binaries): % : %.o $(DEPDIR)/%.bin.d
    ${CC} ${CFLAGS} $(shell cat .d/$@.bin.d | cut -d ' ' -f 2-) ${LDFLAGS} -o $@
%.o: %.cpp
%.o: %.cpp $(DEPDIR)/%.d
    $(COMPILE) $<
    $(POSTCOMPILE)
    $(GENERATE_BINARY_DEPS)
clean:
    rm -vf *.o
    rm -vf bin_1 bin_2 bin_3
realclean:
    $(MAKE) clean
    rm -fr .d
-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))
-include $(patsubst %,$(DEPDIR)/%.bin.d,$(basename $(SRCS)))

现在问题来了:为了使其工作,我需要运行"make"两次。生成 *.bin.d 依赖项文件,但仅在第二次运行时,Make 实际上"意识到"说 header_1.o 对于bin_1也是必需的,而不仅仅是 bin_1.o。在第一次运行时,它会尝试将所有对象文件链接在一起,而无需先实际构建所有对象文件。

有没有办法解决这个问题,即在第一次通过时就把一切都做好了?

谢谢!

由于 Make 将在 1st 读入整个制作文件,然后执行目标。 很难一次性更新 %.bin.d。或者,我们可以尝试在内部触发第二个"make",例如,

ifneq ($(STAGE),2)
$(binaries): % : %.o $(DEPDIR)/%.bin.d
        @{MAKE} $(binaries) STAGE=2
else
#2nd pass
$(binaries):
        ${CC} ${CFLAGS} -o $@ $(shell cat .d/$@.bin.d | cut -d ' ' -f 2-) ${LDFLAGS}
endif