1

我喜欢使用该g++ -MM功能来自动构建我的依赖项。我这样做的方式如下:

include $(ALLOBJ:%.o=%.d)

%.d: %.cxx
    @echo making dependencies for $<
    @g++ -MM $(CXXFLAGS) $< -o $@
    @sed -i 's,$*\.o,& $@ ,g' $@

基本上我可以给出这个规则ALLOBJ,它会:

  1. 将每个.o名称转换为.d名称,然后include
  2. 当它找不到 a.d时,它将从.cxx文件 中创建它
    • 规则的最后一行%.d: %.cxx会将文件名添加.d到文件本身,这样依赖关系就会自动更新。

当我删除一个标题时,问题就出现了:.d文件仍然希望找到它,并且当它不存在时,make 会感到不安。一种解决方案是替换include-include, 并在编译规则中构建依赖项。不幸的是,这需要每个编译规则的依赖生成行,并且还会忽略所有其他include错误(这似乎有风险)。有没有其他简单的方法来自动构建依赖项来避免这个问题?

4

2 回答 2

2

为了重申我对另一个问题的回答,我这样做:

%.o: %.cpp
    @echo making $@ and dependencies for $< at the same time
    @$(CC) -MD -c $(CXXFLAGS) -o $@ $<
    @cp $*.d $*.P
    @sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
         -e '/^$$/ d' -e 's/$$/ :/' < $*.P >> $*.d
    @rm $*.P

-include $(ALLOBJ:%.o=%.d)

编辑:

它...它生成依赖文件,但更干净且没有sed命令:

%.o: %.cpp
    @echo making $@ and dependencies for $< at the same time
    @$(CC) -c $(CXXFLAGS) -o $@ $<
    @$(CC) -MM -MP $(CXXFLAGS) $< -o $*.d

-include *.d

所以现在我必须%.o在我自己的 makefile 中修改规则。从现在开始,在我编译的所有东西中都会有一点@JackKelly ,嘲笑我。哦,这是一个黑色的日子。

于 2012-10-12T23:02:08.913 回答
2

多阅读手册,感谢上面@jackKelly 和@Beta 的回复,我找到了以下解决方案:

include $(ALLOBJ:%.o=%.d)

%.d: %.cxx
    @echo making dependencies for $<
    @g++ -MM -MP -MT $*.d -MT $*.o $(CXXFLAGS) $< -o $@

总结这些标志:

  • -MM: 构建依赖(而不是编译)
  • -MP:为所有标题构建“虚拟”目标。这可以防止 make 在标题被删除并因此无法找到时抱怨。
  • -MT:指定规则的目标。这使我们能够告诉 make.d文件依赖于标头,而无需诉诸丑陋的 sed 规则。

我不相信我的解决方案比@Beta 的解决方案更正确。我倾向于在同一个 makefile 中对 C++ 文件使用多个编译规则,因此对所有文件使用单个依赖项规则比在每个编译规则中生成依赖项稍微干净一些(在我的情况下)。

于 2012-10-13T19:43:18.077 回答