假设我有一个项目,我已经开发了一个R包。层次结构可能看起来像这样。
/project
---Makefile
---workflow.R
---test.R
---/mypackage
---DESCRIPTION
---NAMESPACE
---/R
---func1.R
---func2.R
workflow.R
取决于正在安装的mypackage
的最新版本。但是,我只想重新构建包,如果其中的任何文件已被修改。
目前,在我的Makefile中,我有:
PACKAGE=$(wildcard mypackage/**/*)
all: install test workflow
install: $(PACKAGE)
R CMD INSTALL mypackage
workflow: install
Rscript workflow.R
test: install
Rscript test.R
但是,每次运行make test
时,这都将重新安装包,即使包中没有任何内容发生更改。是否有一种干净的方法来避免这种情况?
答案 0 :(得分:3)
install
规则不会在当前目录中创建名为install
的文件,因此每次尝试重新创建它。这看起来应该是.PHONY
目标,但它本身不会解决问题,因为它仍然会执行配方。
一种解决方案是使用另一个创建存根文件的规则:
.PHONY: all install test workflow
all: install test workflow
install: install.done
install.done: $(PACKAGE)
R CMD INSTALL mypackage
touch $@
或者您可以只将install
存根文件本身设为非.PHONY
规则。
答案 1 :(得分:0)
听起来您想将安装视为中间步骤。您可以通过添加
.INTERMEDIATE: install
到您的makefile。
制造手册说明(link):
如果普通文件b不存在,并且make考虑依赖于b的目标,则它总是创建b,然后从b更新目标。但是,如果b是一个中间文件,那么make可以单独放置。除非更新b的某些先决条件或有其他原因更新该目标,否则不会麻烦更新b或最终目标。