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

时间:2016-03-21 13:46:09

标签: c++ compilation makefile

我想"完全"在项目的Makefile中自动化依赖项生成过程。到目前为止,我已经关注自动依赖关系this tutorial,这非常有效。只有一个问题:这只适用于头文件依赖项,因此它会自动检测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)))

现在问题出现了:为了让它发挥作用,我需要运行&#34; make&#34;两次。生成* .bin.d依赖文件,但仅在第二次运行时生成,实际上是#34;实现&#34;也就是说bin_1也需要header_1.o,而不仅仅是bin_1.o。在第一次运行时,它尝试将所有目标文件链接在一起,而不首先实际构建所有目标文件。

有没有办法解决这个问题,我。即第一次通过时一切正常吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

由于Make会在1st读入整个makefile,然后执行目标。一次通过更新%.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