gnu make"删除中间文件"

时间:2017-11-23 04:03:22

标签: 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 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 $@ $<

当构建完成时,GNU make说 Removing intermediate files...并删除我想要的所有.pp个文件。

为什么这样做?
我该如何阻止它?

4 个答案:

答案 0 :(得分:3)

如果您搜索&#34; gnu制作中间文件&#34;您可以在GNU制作手册部分Chains of Implicit Rules中立即找到答案,了解它为何会发生。

它还告诉您如何避免它:如果文件在makefile中被提及为目标或先决条件,则文件不能是中间文件。

因此,只需将您的.pp文件列为某个规则的先决条件。它不一定是一个被调用过的规则。你没有给我们足够的makefile供我们提供完整的答案,但它会是这样的:

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

假设您的变量ALL_OBJECTS包含所有.o个文件。

答案 1 :(得分:0)

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

.PRECIOUS: $(BUILD)/%.pp  # ADD THIS LINE
$(BUILD)/%.pp: %.c
    $(ECHO) "PreProcess $<"
    $(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<

documentation关于.PRECIOUS指令的说法是这样的:

  

.PRECIOUS所依赖的目标具有以下特殊处理:如果在执行其配方期间make被杀死或中断,则不会删除目标。

     

[...]

     

此外,如果目标是中间文件,则不再需要它,就像通常那样,它不会被删除。

     

[...]

     

您还可以将隐式规则的目标模式(例如'%.o')列为特殊目标.PRECIOUS的必备文件,以保留由目标模式与该文件名匹配的规则创建的中间文件

这样做的好处是不会创建不需要的附加规则。您也可以清楚地知道要做什么:保留可能昂贵的昂贵的中间文件。

答案 2 :(得分:0)

这是一个细节,终于让PRECIOUS为我工作。您赋予PRECIOUS的模式必须精确地是 在创建中间文件的规则中使用的模式。我想保存所有以moc_为前缀的文件。起初我用 .PRECIOUS:moc_% 无济于事。然后我尝试 .PRECIOUS:moc _%。cpp 这就是窍门。

答案 3 :(得分:0)

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

.SECONDARY:

引用 manual

<块引用>

.SECONDARY 没有先决条件会导致所有目标都被视为次要目标(即,没有目标被移除,因为它被认为是中间目标)。

为什么这比将目标作为一次性目标的先决条件要好?这更加混乱,并且必须针对可能使用模式规则生成的每组文件明确地完成。

为什么这比 .PRECIOUS 好?这会导致文件在使用 .DELETE_ON_ERROR 时即使它们的配方失败也被保留。后者对于避免失败的配方留下不好的输出很重要,这些输出然后被后续 make 调用视为当前。 IMO,你总是想要 .DELETE_ON_ERROR,但 .PRECIOUS 打破了它。