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
.
我有以下 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
.