Как избежать запуска всех целей при каждом запуске make-файла? - PullRequest
0 голосов
/ 12 апреля 2019

Как я могу избежать восстановления целей каждый раз, даже если в них нет изменений?Я посмотрел на эти ответы: answer1 , answer2 , answer3 , но я все еще не мог решить свою проблему.Я думаю, что я концептуально понимаю, почему эта проблема возникает.Просто я не смог применить решения к моему делу.

Вот мой make-файл:

.PHONY: all dircreate dircreate_sub

# Create shortcuts to directories ##############################################
DAT4 = data/4-Year/
RES4 = data/results/4-Year/
FIG4 = figures/4-Year/
DAT2 = data/2-Year/
RES2 = data/results/2-Year/
FIG2 = figures/2-Year/
DEPVARS = \
    ret.1st.2nd.term.left \
    ret.1st.2nd.year.left \
    ret.1st.7th.year.grad \
    ret.1st.5th.year.grad

# Create directories ###########################################################
dircreate:
    mkdir -p \
    data/ \
    data/4-Year/ \
    data/2-Year/ \
    data/results/ \
    data/results/4-Year \
    data/results/2-Year \
    figures/ \
    figures/4-Year/ \
    figures/2-Year/

dircreate_sub:
    for d in $(DEPVARS); do \
        mkdir -p data/4-Year/$$d ; \
        mkdir -p data/2-Year/$$d ; \
        mkdir -p data/results/4-Year/$$d ; \
        mkdir -p data/results/2-Year/$$d ; \
        mkdir -p figures/4-Year/$$d ; \
        mkdir -p figures/2-Year/$$d ; \
    done;

#TARGETS_DATAPREP := \
#$(foreach dat, $(DAT4) $(DAT2), $\
#   $(foreach filename, \
#           train_index_outer.RDS \
#           train_outer.RDS \
#           train_inter_outer.RDS, $\
#               $(foreach depvar, $(DEPVARS),$(dat)$(depvar)/$(filename))))

# Data prep:####################################################################
TARGETS_DATAPREP := \
$(foreach filename, $\
    train_index_outer.RDS \
    train_outer.RDS \
    train_inter_outer.RDS \
    entire_data.RDS \
    entire_inter_data.RDS, $\
        $(foreach depvar, $(DEPVARS),$(DAT4)$(depvar)/$(filename)))

$(TARGETS_DATAPREP): \
    dataprep.R \
    funcs.R \
    ../core/data/analysis.data.RDS
    Rscript $<

# benchmark:####################################################################
DEPENDENCIES_BENCHMARK := \
$(foreach filename, $\
    train_index_outer.RDS \
    train_outer.RDS \
    train_inter_outer.RDS \
    entire_data.RDS \
  entire_inter_data.RDS, $\
        $(foreach depvar, $(DEPVARS),$(DAT4)$(depvar)/$(filename)))

TARGETS_BENCHMARK := \
$(foreach filename, $\
    logreg_inner.RDS \
    l1logreg_inner.RDS \
    l1logreg.int_inner.RDS \
    rf_inner.RDS \
    xgb_inner.RDS \
    logreg_outer.RDS \
    l1logreg_outer.RDS \
    l1logreg.int_outer.RDS \
    rf_outer.RDS \
    xgb_outer.RDS, $\
        $(foreach depvar, $(DEPVARS),$(RES4)$(depvar)/$(filename)))

$(TARGETS_BENCHMARK): \
    benchmark.R \
    funcs.R \
    $(DEPENDENCIES_BENCHMARK)
    Rscript $<

# Process:######################################################################
TARGETS_PROCESS := \
$(foreach filename, $\
    processed_inner.RDS \
    processed_inner_outer.RDS, $\
        $(foreach depvar, $(DEPVARS),$(RES4)$(depvar)/$(filename)))

$(TARGETS_PROCESS): \
    process.R \
    funcs.R \
    $(TARGETS_BENCHMARK)
    Rscript $<

# Graphs:#######################################################################
TARGETS_GRAPHS := \
$(foreach filename, $\
    ave_auc_inner.png \
    ave_ppv10_inner.png \
    dist_auc_inner.png \
    dist_ppv10_inner.png \
    roc_inner.png \
    ave_auc_outer.png \
    ave_ppv10_outer.png \
    dist_auc_outer.png \
    dist_ppv10_outer.png \
    roc_outer.png \
    ave_auc_ppv10_inner_outer.png \
    roc_inner_outer.png \
    thresh_inner_outer.png, $\
        $(foreach depvar, $(DEPVARS),$(FIG4)$(depvar)/$(filename)))

$(TARGETS_GRAPHS): \
    graphs.R \
    funcs.R \
    $(TARGETS_PROCESS)
    Rscript $<

# Make all
all: $(TARGETS_PROCESS)



Итак, make -nd говорит мне, что dircreate нужно каждый раз переделывать.Вот почему я также попытался добавить переменную, скажем, OUTDIRS, а также создал для нее правило.Итак, вместо dircreate я добавил этот бит:

OUTDIRS: $(DAT4) $(RES4) $(FIG4) $(DAT2) $(RES2) $(FIG2)
OUTDIRS := \
for d in $(DEPVARS); do \
    $(DAT4)$$d ; \
    $(DAT2)$$d ; \
    $(RES4)$$d ; \
    $(RES2)$$d ; \
    $(FIG4)$$d ; \
    $(FIG2)$$d ; \
done;

$(OUTDIRS):
  mkdir -p $@

Но на этот раз я получаю ошибку отсутствующего разделителя в $(OUTDIRS): mkdir -p $@, которая, я знаю, не связана с основным вопросом, ноМне интересно, если мой путь, по крайней мере, на правильном пути?

1 Ответ

0 голосов
/ 13 апреля 2019

Предположим, у вас есть

DIRS := 2-Year 4-Year
DEPVARS := term year

и вы хотите построить:

2-Year/term 2-Year/year 4-Year/term 4-Year/year

Вы можете сделать это следующим образом:

OUTDIRS := $(foreach d,$(DIRS),$(addprefix $(d)/,$(DEPVARS)))

И как только вы получитечто работая, вы можете абстрагировать его в функцию:

Multiply= $(foreach d,$(1),$(addprefix $(d)/,$(2)))

OUTDIRS:=$(call Multiply, $(DIRS), $(DEPVARS))

И у вас есть , которая работает , вы можете использовать ее для построения своих деревьев:

DIRS := data data/results figures
DIRS := $(DIRS) $(call Multiply, $(DIRS), 4-Year 2-Year)

DEPVARS := $(addprefix ret.1st., 2nd.term.left 2nd.year.left 7th.year.grad 5th.year.grad)

OUTDIRS:=$(call Multiply, $(DIRS), $(DEPVARS))

$(OUTDIRS):
    mkdir -p $@

Обратите внимание, что если вы хотите, чтобы Make создавал те каталоги, которые не существуют, вы должны добавить еще одно правило до правило $(OUTDIRS):

.PHONY: all-dirs
all-dirs: $(OUTDIRS)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...