Make всегда восстанавливает цели Makefile

Я переработал большинство файлов Makefile для моего проекта диссертации, чтобы правильно отразить рабочий процесс (Создание правил make для зависимостей между целевыми объектами в подкаталогах проекта). Однако в конкретном подкаталоге (prepare) make всегда восстанавливает все цели даже при отсутствии изменений в зависимостях. Что может быть причиной такого неожиданного поведения?

ПРИМЕЧАНИЕ. sf.done - это реальный файл (типа, который я называю "файлы флагов" ), расположенный в другом подкаталоге и созданный/обновленный после завершения сбора данных (import) - зависимый шаг для цель transform.

подготовить /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 [email protected]

cleanup.done: cleanup.R transform
    @$(RSCRIPT) $(R_OPTS) $<
    @touch [email protected]

merge.done: merge.R cleanup
    @$(RSCRIPT) $(R_OPTS) $<
    @touch [email protected]

sample.done: sample.R merge
    @$(RSCRIPT) $(R_OPTS) $<
    @touch [email protected]

.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 [email protected]

cleanup.done: cleanup.R transform.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch [email protected]

merge.done: merge.R cleanup.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch [email protected]

sample.done: sample.R merge.done
    @$(RSCRIPT) $(R_OPTS) $<
    @touch [email protected]

.PHONY: import transform cleanup merge sample clean

Ответ 1

Вы указали цели import transform cleanup merge sample clean равными .PHONY. Это означает, что make всегда будет считать их устаревшими.

Затем вы объявляете различные цели .done зависимыми от этих .PHONY целей. Поскольку фальшивые цели всегда считаются устаревшими, эти цели .done всегда нуждаются в обновлении, и рецепты всегда срабатывают.