Makefile 没有找到目标

Makefile does not find target

我有以下 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 
list:
    @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($ !~ "^[#.]") {print $}}' | 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)}

我确定这是一件小事...

这条规则:

%.html : %.Rmd
        ....

告诉 make 如何从文件 foo.Rmd 或文件 source/foo.html 或文件 source/foo.Rmd 或文件 docs/foo.html 构建文件 foo.html ] 来自文件 docs/foo.Rmd.

它没有告诉 make 如何从文件 source/foo.Rmd 构建文件 docs/foo.html,因为匹配模式 % 的词干不相同。

如果你想为 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.