Makefile не находит цель - PullRequest
       45

Makefile не находит цель

0 голосов
/ 21 ноября 2018

У меня есть следующий Makefile, но он не работает.Когда я звоню

make html

, я получаю ошибку

make: *** No rule to make target `docs/index.html', needed by `html'.  Stop.

, хотя я думаю, что я ее определил.

SRCDIR = source
OUTDIR = docs

RMD = $(wildcard $(SRCDIR)/*.Rmd)

TMP  = $(RMD:.Rmd=.html)
HTML = ${subst $(SRCDIR),$(OUTDIR),$(TMP)}


test:
    echo $(RMD)
    echo $(TMP)
    echo $(HTML)


all: clean update html

html:   $(HTML)

%.html: %.Rmd
    echo $(HTML)
    @Rscript -e "rmarkdown::render('$<', output_format = 'prettydoc::html_pretty', output_dir = './$(OUTDIR)/')"

update:
    @Rscript -e "devtools::load_all(here::here()); microcosmScheme:::updateFromGoogleSheet(token = './source/googlesheets_token.rds')"


## from https://stackoverflow.com/a/26339924/632423
list:
    @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs

.PHONY: update clean cleanhtml all list

Переменные кажутся правильными:

15:21 $ make test
echo source/index.Rmd
source/index.Rmd
echo source/index.html
source/index.html
echo docs/index.html
docs/index.html

Если я изменю его следующим образом, он работает, но цель указывает на SRCDIR, но я хочу, чтобы он указал на OUTDIR:

RMD = $(wildcard $(SRCDIR)/*.Rmd)

HTML  = $(RMD:.Rmd=.html)
# HTML = ${subst $(SRCDIR),$(OUTDIR),$(TMP)}

Я уверен, что этоэто маленькая вещь ...

1 Ответ

0 голосов
/ 21 ноября 2018

Это правило:

%.html : %.Rmd
        ....

указывает make для создания файла foo.html из файла foo.Rmd или файла source/foo.html из файла source/foo.Rmd или файла docs/foo.html из файла docs/foo.Rmd.

Он не указывает make для создания файла docs/foo.html из файла source/foo.Rmd, поскольку основа, соответствующая шаблону %, не совпадает.

Если вы хотите написать шаблон для docs/foo.html, который будет построен из source/foo.Rmd, вы должны написать его так:

$(OUTDIR)/%.html : $(SRCDIR)/%.Rmd
      ....

, чтобы часть, соответствующая шаблону% идентичен.

ETA Некоторые другие примечания: вы должны использовать := с функцией wildcard, так как она намного эффективнее.Также вы не должны использовать subst здесь, потому что он заменяет все вхождения строки, которые могут привести к поломке, если любой из ваших .Rmd файлов содержит, например, строку source (например, source/my_source_file.RmdЭто гораздо лучше написано с помощью patsubst, например:

RMD := $(wildcard $(SRCDIR)/*.Rmd)
HTML := $(patsubst $(SRCDIR)/%.Rmd,$(OBJDIR)/%.html,$(RMD))

Наконец, вы не показываете, что делает цель clean, но это необычно, когда цель clean зависит отall. Обычно это отдельная цель, которая вызывается только тогда, когда вы этого хотите, например make clean.

...