我有以下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)}
我确定这是一件小事...
答案 0 :(得分:2)
此规则:
%.html : %.Rmd
....
讲述如何从文件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
。