gnu make “Removing intermediate files”

南笙酒味 提交于 2020-05-14 19:13:23

问题


I have the following rules

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 $@ $<

When the build finishes, GNU make says
Removing intermediate files... and deletes all the .pp files which I do NOT want.

Why is it doing this?
How do I stop it?


回答1:


If you search for "gnu make intermediate files" you'll immediately find the answer as to why it's happening, in the GNU make manual section Chains of Implicit Rules.

It also tells you how to avoid it: a file cannot be intermediate if it is mentioned in the makefile as a target or prerequisite.

So, just list your .pp files as a prerequisite of some rule, somewhere. It doesn't have to be a rule that's ever invoked. You don't give enough of your makefile here for us to provide a complete answer, but it would be something like:

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

assuming you had a variable ALL_OBJECTS containing all your .o files.




回答2:


Since you're using GNU Make, you can make the following adjustment to your Makefile:

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

The documentation has this to say about .PRECIOUS directives:

The targets which .PRECIOUS depends on are given the following special treatment: if make is killed or interrupted during the execution of their recipes, the target is not deleted.

[...]

Also, if the target is an intermediate file, it will not be deleted after it is no longer needed, as is normally done.

[...]

You can also list the target pattern of an implicit rule (such as ‘%.o’) as a prerequisite file of the special target .PRECIOUS to preserve intermediate files created by rules whose target patterns match that file's name.

This has the benefit of not creating an unwanted additional rule. It's also clearer what you're trying to do: keep the precious intermediate files that might be expensive to recreate.




回答3:


Here is a detail that finally got PRECIOUS working for me. The pattern that you give to PRECIOUS has to be exactly the pattern that is being used in the rule that creates the intermediate file. I want to save all files prefixed by moc_. At first I used .PRECIOUS: moc_% to no avail. Then I tried .PRECIOUS: moc_%.cpp and this did the trick.



来源:https://stackoverflow.com/questions/47447369/gnu-make-removing-intermediate-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!