【问题标题】:Makefile does not find targetMakefile 找不到目标
【发布时间】:2019-04-24 03:34:18
【问题描述】:

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

我相信这是一件小事......

【问题讨论】:

  • 您没有声明help 是假的有什么原因吗?
  • 我有“帮助”目标吗?
  • 抱歉,我的意思是 html(我经常将虚假的 help 目标作为我的默认目标)。
  • 这正是我不想要的。但感谢您指出 =at 选项。

标签: makefile directory target


【解决方案1】:

这条规则:

%.html : %.Rmd
        ....

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

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

如果你想为docs/foo.html 编写一个从source/foo.Rmd 构建的模式,你必须这样写:

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

这样匹配模式%的部分是相同的。

ETA 其他一些注意事项:您应该将:=wildcard 函数一起使用,因为它的性能要好得多。此外,您不应在此处使用 subst,因为它会替换 所有 出现的字符串,如果您的任何 .Rmd 文件包含字符串 source (例如,@987654341 @. 用patsubst 写得更好,如:

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

最后,您没有显示clean 目标的作用,但clean 目标依赖于all 是不寻常的。通常它是一个单独的目标,仅在您需要时调用,例如 make clean

【讨论】:

  • 有道理。但是我现在按照建议更改了 Makefile,但我仍然得到同样的错误。我将其作为要点发布在gist.github.com/rkrug/f060bab62b3b0c1b20a7360e86cd0652
  • 这是因为我在示例模式规则中错误地使用了变量SOURCE,而您使用的变量是SRCDIR,而您盲目地复制了我的错误:)。未知变量扩展为空字符串,因此您的模式规则是 docs/%.html : /%.Rmd,这当然行不通。
  • 谢谢。现在完美地工作。
猜你喜欢
  • 2015-10-11
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
相关资源
最近更新 更多