make always rebuilds Makefile targets

僤鯓⒐⒋嵵緔 提交于 2019-11-28 06:39:23

问题


I redesigned most of the Makefile files for my dissertation project in order to correctly reflect the workflow (Creating make rules for dependencies across targets in project's sub-directories). However, in a particular sub-directory (prepare), make always rebuilds all targets, even when there are no changes in dependencies. What could be the reason for this unexpected behavior?

NOTE: sf.done is a real file (of type, which I call "flag files"), located in a different sub-directory and created/updated upon completion of data collection (import) - dependent step for the target transform.

prepare/Makefile:

IMPORT_DIR=../import

prepare: import \
         transform \
         cleanup \
         merge \
         sample

import: $(IMPORT_DIR)/sf.done
transform: transform.done
cleanup: cleanup.done
merge: merge.done
sample: sample.done

transform.done: transform.R import
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

cleanup.done: cleanup.R transform
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

merge.done: merge.R cleanup
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

sample.done: sample.R merge
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

.PHONY: import transform cleanup merge sample clean

# remove intermediate files
clean:
    rm -f tmp*.bz2 *.Rdata .Rout

UPDATE:

IMPORT_DIR = ../import
IMPORT_DONE = $(IMPORT_DIR)/sf.done

prepare: import \
         transform \
         cleanup \
         merge \
         sample

import: import.done
transform: transform.done
cleanup: cleanup.done
merge: merge.done
sample: sample.done

import.done: $(IMPORT_DONE)
    @cd $(IMPORT_DIR) && $(MAKE)

transform.done: transform.R import.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

cleanup.done: cleanup.R transform.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

merge.done: merge.R cleanup.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

sample.done: sample.R merge.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch $@

.PHONY: import transform cleanup merge sample clean

回答1:


You've declared the targets import transform cleanup merge sample clean to be .PHONY. That means that make will always consider them to be out of date.

Then you declare the various .done targets to depend on those .PHONY targets. Since the phony targets are always considered out of date, those .done targets always need to be updated, and the recipes always fire.



来源:https://stackoverflow.com/questions/23956295/make-always-rebuilds-makefile-targets

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