在建议的使用 makefile 的自动依赖生成中,在 %.o 目标的先决条件中列出 c/c++ 源文件是否有用?
Is it useful to list the c/c++ source file in the prerequisites for the %.o target in the recommended Auto-Dependency Generation with makefiles?
我指的是为 GNU make+gcc 推荐的 Auto-Dependency Generation 的高级方法。我本可以在 Mad Scientist 网站上提问,但作者在 SO 上非常活跃。
在该方法中,目标“%.o”的依赖链总结为以下几行:
%.o : %.cxx $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
根据我对 GNU make 的理解和一些基本实验,在我看来,在目标“%.o”的先决条件列表中包含“%.cxx”是不必要和多余的。我们可以有完全相同的行为:
%.o : $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $*.cxx
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
理由是依赖文件明确列出了源文件作为目标文件的先决条件。当然,原页面中的精彩分析各方面仍然有效(例如内置规则可能需要删除,丢失的依赖文件无论如何都会触发目标文件的规则等)
这似乎是一个微不足道的变化,但有一个重要的含义:从 C 源文件构建的目标对象文件的先决条件列表与从 C++ 源文件构建的目标对象文件完全相同或任何其他编译语言,它可以将更多工作委托给某些宏,并且所有编译语言只有一个规则:
%.o: %.d
$(COMPILE) $(OUTPUT_OPTIONS) $(SOURCE)
$(POSTCOMPILE)
宏 COMPILE、OUTPUT_OPTIONS 和 SOURCE 可以使用目标特定值和 $* 分析的任意组合来完成工作。
所以,问题是:在这种情况下,除了识别源文件中使用的语言之外,在列表中列出源文件(除了依赖文件)是否有用?目标对象文件的先决条件?
反过来才是正确的方法:
%.o : %.cxx
那是因为您希望在编辑 .cxx
后重建 .o
。从不编辑 .d
个文件。
并且不依赖于 %.d
。
但是,当 %.d
包含在 makefile 中时,makefile 会依赖于那个 .d
并尝试更新它,因此你仍然需要那个空的 $(DEPDIR)/%.d: ;
规则。
第一次完成构建时不需要依赖项,因为所有内容都需要构建。下一次构建依赖项用于确定需要重建的内容。
一种更直接的方法是将所有依赖文件放在同一目录中相应的 .o
文件旁边。因为不同的构建模式(debug/release)可能有不同的包含(每个构建模式必须有自己的输出目录,这样你就可以在模式之间切换而不必先做make clean
)。在我看来,不应遵循那篇文章中处理依赖项的示例。
It might seem like a trivial change but there is a significant implication: the list of prerequisites for a target object file built from a C source file would be exactly the same as a target object file built from a C++ source file or any other compiled language
好吧,我不确定 C/C++ 你指的是什么语言。
The macros COMPILE, OUTPUT_OPTIONS and SOURCE could use any combination of target-specific values and analysis of $* to get the job done.
我相信它不如简单地拥有几个不同的规则方便。所以,即使你的建议可行,我也看不出有任何实际理由这样做。
考虑到可能存在的问题,我至少可以看到一个:如果 $*.cxx 是一个 auto-generated 文件,那么它根本无法工作,因为您有效地破坏了任何隐式规则链接。
我指的是为 GNU make+gcc 推荐的 Auto-Dependency Generation 的高级方法。我本可以在 Mad Scientist 网站上提问,但作者在 SO 上非常活跃。
在该方法中,目标“%.o”的依赖链总结为以下几行:
%.o : %.cxx $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
根据我对 GNU make 的理解和一些基本实验,在我看来,在目标“%.o”的先决条件列表中包含“%.cxx”是不必要和多余的。我们可以有完全相同的行为:
%.o : $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $*.cxx
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS))))
理由是依赖文件明确列出了源文件作为目标文件的先决条件。当然,原页面中的精彩分析各方面仍然有效(例如内置规则可能需要删除,丢失的依赖文件无论如何都会触发目标文件的规则等)
这似乎是一个微不足道的变化,但有一个重要的含义:从 C 源文件构建的目标对象文件的先决条件列表与从 C++ 源文件构建的目标对象文件完全相同或任何其他编译语言,它可以将更多工作委托给某些宏,并且所有编译语言只有一个规则:
%.o: %.d
$(COMPILE) $(OUTPUT_OPTIONS) $(SOURCE)
$(POSTCOMPILE)
宏 COMPILE、OUTPUT_OPTIONS 和 SOURCE 可以使用目标特定值和 $* 分析的任意组合来完成工作。
所以,问题是:在这种情况下,除了识别源文件中使用的语言之外,在列表中列出源文件(除了依赖文件)是否有用?目标对象文件的先决条件?
反过来才是正确的方法:
%.o : %.cxx
那是因为您希望在编辑 .cxx
后重建 .o
。从不编辑 .d
个文件。
并且不依赖于 %.d
。
但是,当 %.d
包含在 makefile 中时,makefile 会依赖于那个 .d
并尝试更新它,因此你仍然需要那个空的 $(DEPDIR)/%.d: ;
规则。
第一次完成构建时不需要依赖项,因为所有内容都需要构建。下一次构建依赖项用于确定需要重建的内容。
一种更直接的方法是将所有依赖文件放在同一目录中相应的 .o
文件旁边。因为不同的构建模式(debug/release)可能有不同的包含(每个构建模式必须有自己的输出目录,这样你就可以在模式之间切换而不必先做make clean
)。在我看来,不应遵循那篇文章中处理依赖项的示例。
It might seem like a trivial change but there is a significant implication: the list of prerequisites for a target object file built from a C source file would be exactly the same as a target object file built from a C++ source file or any other compiled language
好吧,我不确定 C/C++ 你指的是什么语言。
The macros COMPILE, OUTPUT_OPTIONS and SOURCE could use any combination of target-specific values and analysis of $* to get the job done.
我相信它不如简单地拥有几个不同的规则方便。所以,即使你的建议可行,我也看不出有任何实际理由这样做。
考虑到可能存在的问题,我至少可以看到一个:如果 $*.cxx 是一个 auto-generated 文件,那么它根本无法工作,因为您有效地破坏了任何隐式规则链接。