【问题标题】:To include or -include auto-generated dependencies?包含或 -include 自动生成的依赖项?
【发布时间】:2012-10-12 21:09:15
【问题描述】:

我喜欢使用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. 当它找不到.d 时,它将从.cxx 文件中创建它
    • %.d: %.cxx 规则的最后一行会将.d 文件的名称添加到文件本身,这样依赖关系就会自动更新。

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

【问题讨论】:

    标签: makefile g++


    【解决方案1】:

    为了重申我对the other question 的回答,我这样做:

    %.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
    

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

    【讨论】:

    • 两个问题:-MD 是做什么的?真的很长的 sed 线是怎么回事?
    • @Shep: -MD 创建 两个 文件,foo.ofoo.d。但是这个foo.dfoo.h 列为foo.o 的preq,所以它受制于你描述的问题。长 sed 命令修改 foo.d,将 preqs 附加为不带命令的规则的目标(例如 foo.h:)。这足以安抚Make并防止错误; foo.h 不见了,但有一个规则,所以 Make 相信一切都会得到照顾。
    • @Beta:你为什么不把-MP传给gcc
    • @JackKelly:嗯,因为,你看,呃...那是因为... 因为我不知道-MP!该死的,杰克凯利!该死的!
    【解决方案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:指定规则的目标。这使我们能够告诉使.d 文件依赖于标头,而无需诉诸丑陋的 sed 规则。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 2012-07-06
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多