Makefile 要包含或-包含自动生成的依赖项?

Makefile 要包含或-包含自动生成的依赖项?,makefile,g++,Makefile,G++,我喜欢使用g++-MM特性来自动构建依赖项。我的做法如下: include $(ALLOBJ:%.o=%.d) %.d: %.cxx @echo making dependencies for $< @g++ -MM $(CXXFLAGS) $< -o $@ @sed -i 's,$*\.o,& $@ ,g' $@ 基本上我可以给这个规则ALLOBJ,它将: 将每个.o名称转换为.d名称,并将其包括在内, 当它找不到.d时,它将从.cxx文件创建它

我喜欢使用g++-MM特性来自动构建依赖项。我的做法如下:

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

%.d: %.cxx
    @echo making dependencies for $<
    @g++ -MM $(CXXFLAGS) $< -o $@
    @sed -i 's,$*\.o,& $@ ,g' $@
基本上我可以给这个规则ALLOBJ,它将:

将每个.o名称转换为.d名称,并将其包括在内, 当它找不到.d时,它将从.cxx文件创建它 %.d:%.cxx规则的最后一行将向文件本身添加.d文件的名称,以便自动更新依赖项。 当我删除一个头文件时,问题就出现了:这个.d文件仍然希望找到它,当它不在那里时,make会感到不安。一种解决方案是用-include替换include,并在编译规则中构建依赖项。不幸的是,这需要为每个编译规则生成一行依赖项,并且还将忽略所有其他看起来有风险的include错误。是否有其他简单的方法可以自动生成依赖项以避免此问题

重申我的答案,我是这样做的:

%.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)
所以现在我必须在我自己的makefile中修改%.o规则。从现在开始,我编译的每件东西都会有一点@JackKelly,嘲笑我。哦,这是一个黑暗的日子。

为了重申我的答案,我这样做:

%.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)
所以现在我必须在我自己的makefile中修改%.o规则。从现在开始,我编译的每件东西都会有一点@JackKelly,嘲笑我。哦,这是一个糟糕的日子。

再多阅读一下手册,多亏了@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的解决方案更正确。我倾向于使用同一个Mag文件中的C++文件的多个编译规则,所以在我的情况下,对于它们中的所有一个依赖规则都比在每个编译规则中生成依赖性略微干净。p> 再仔细阅读一下手册,多亏了@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的解决方案更正确。我倾向于使用同一个Mag文件中的C++文件的多个编译规则,所以在我的情况下,对于它们中的所有一个依赖规则都比在每个编译规则中生成依赖性略微干净。p> 两个问题:MD做什么?“真的很长的sed行是怎么回事?”@Shep:-MD创建了两个文件,foo.o和foo.d。但是这个foo.d将foo.h列为foo.o的preq,因此它取决于您描述的问题。长sed命令修改foo.d,将preq附加为规则的目标,而不使用命令,例如foo.h:。这足以缓和和防止错误;foo.h不见了,但有个规定,所以要相信一切都会处理好。@Beta:你为什么不把-MP传给gcc?@JackKelly:好吧,因为,你看,呃。。。那是因为。。。因为我不知道-MP!该死的,杰克·凯利!该死的!两个问题:MD做什么?“真的很长的sed行是怎么回事?”@Shep:-MD创建了两个文件,foo.o和foo.d。但是这个foo.d将foo.h列为foo.o的preq,因此它取决于您描述的问题。长sed命令修改foo.d,将preq附加为规则的目标,而不使用命令,例如foo.h:。这足以缓和和防止错误;foo.h不见了,但有个规定,所以要相信一切都会处理好。@Beta:你为什么不把-MP传给gcc?@JackKelly:好吧,因为,你看,呃。。。那是因为。。。因为我不知道-MP!该死的,杰克·凯利!该死的!