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
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.