Makefile gnu make“;“删除中间文件”;

Makefile gnu make“;“删除中间文件”;,makefile,gnu-make,Makefile,Gnu Make,我有以下规则 define compile_c $(ECHO) "CC $<" $(Q)$(CC) $(CFLAGS) -c -MD -o $@ $< @# The following fixes the dependency file. @# See http://make.paulandlesley.org/autodep.html for details. @# Regex adjusted from the above to play better with Windows

我有以下规则

define compile_c
$(ECHO) "CC $<"
$(Q)$(CC) $(CFLAGS) -c -MD -o $@ $<
@# The following fixes the dependency file.
@# See http://make.paulandlesley.org/autodep.html for details.
@# Regex adjusted from the above to play better with Windows paths, etc.
@$(CP) $(@:.o=.d) $(@:.o=.P); \
  $(SED) -e 's/#.*//' -e 's/^.*:  *//' -e 's/ *\\$$//' \
      -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \
  $(RM) -f $(@:.o=.d)
endef

vpath %.c . $(TOP)
$(BUILD)/%.o: %.c $(BUILD)/%.pp
    $(call compile_c)

vpath %.c . $(TOP)

$(BUILD)/%.pp: %.c
    $(ECHO) "PreProcess $<"
    $(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<
定义编译
$(ECHO)“CC$如果您搜索“gnu制作中间文件”,您将立即在gnu制作手册部分找到关于为什么会发生这种情况的答案

它还告诉您如何避免它:如果在makefile中提到某个文件作为目标或先决条件,则该文件不能是中间文件

因此,只需在某处列出您的
.pp
文件作为某些规则的先决条件。它不必是曾经调用过的规则。您在此处提供的makefile不够多,我们无法提供完整的答案,但它可能类似于:

all_pps: $(ALL_OBJECTS:.o=.pp)

假设您有一个变量
ALL_OBJECTS
,其中包含所有
.o
文件。

由于您使用的是GNU Make,您可以对Makefile进行以下调整:

.PRECIOUS:$(构建)/%.pp#添加此行
$(构建)/%.pp:%.c

$(ECHO)“预处理$这里有一个细节,它最终对我来说非常有用。您提供给PRECIOUS的模式必须与创建中间文件的规则中使用的模式完全相同。我想保存所有以moc_前缀的文件。起初我用 .珍贵:商务部 无济于事。然后我试着 .珍贵:商务部
这就成功了。

我认为最好的解决方案是使用
.SECONDARY
特殊目标。只需添加这一行:

.SECONDARY:
引述:

.SECONDARY
如果没有先决条件,则会将所有目标视为次要目标(即,没有目标被删除,因为它被视为中间目标)

为什么这比让目标成为一次性目标的先决条件要好?这更混乱,并且必须为可能使用模式规则生成的每一组文件显式执行


为什么这比
.PRECIOUS
好?这会导致即使在使用
时配方失败,文件也会被保留。删除\u ON \u ERROR
。后者对于避免失败的配方留下错误的输出非常重要,这些输出随后被后续的
make
调用视为当前输出。在我看来,您总是希望
.DELETE\ON\u ERROR
,但
.PRECIOUS
会破坏它。

您用于生成依赖项的URL已过时,可能会在某个时候消失。你应该使用正确的URL:我个人会避免使用
.PRECIOUS
,除非它真的是你想要的。当然,它不应该被用作在上面的答案中声明目标的临时替代品。仔细考虑文档所说的:如果制造被杀死或中断,目标不会被删除。如果您正在编译一个大文件并使用
^C
?这会中断make,也会中断编译器。一些编译器将清理半创建的目标,但其他编译器不会。由于半创建的目标具有较新的时间戳,make将不会重新创建它。这可能是一个很难找到的问题。如果我搜索“gnu生成中间文件”。我找到了这个帖子。这篇文章本身就保证了它在谷歌上的成功!