[英]Makefile for building an R package linked to an analysis
Suppose I have a project for which I have developed an R package.假设我有一个项目,我已经为其开发了一个 R 包。 The hierarchy might look something like this.层次结构可能看起来像这样。
/project
---Makefile
---workflow.R
---test.R
---/mypackage
---DESCRIPTION
---NAMESPACE
---/R
---func1.R
---func2.R
workflow.R
depends on the latest version of mypackage
being installed. workflow.R
mypackage
取决于正在安装的最新版本的mypackage
。 However, I only want to re-build the package if any file inside of it has been modified.但是,如果包中的任何文件已被修改,我只想重新构建包。
Currently, in my Makefile, I have:目前,在我的 Makefile 中,我有:
PACKAGE=$(wildcard mypackage/**/*)
all: install test workflow
install: $(PACKAGE)
R CMD INSTALL mypackage
workflow: install
Rscript workflow.R
test: install
Rscript test.R
However, this will re-install the package every time I run make test
, even if nothing inside the package has changed.但是,每次运行make test
时,这都会重新安装包,即使包内没有任何更改。 Is there a clean way to avoid this?有没有干净的方法来避免这种情况?
The install
rule does not create a file named install
in the current directory, so make tries to remake it each time. install
规则不会在当前目录中创建名为install
的文件,因此每次都会尝试重新制作它。 This looks like it should be a .PHONY
target, but that itself won't fix the issue as it will still execute the recipes.这看起来应该是一个.PHONY
目标,但它本身并不能解决问题,因为它仍然会执行配方。
One solution is to have another rule that creates a stub file:一种解决方案是使用另一个规则来创建存根文件:
.PHONY: all install test workflow
all: install test workflow
install: install.done
install.done: $(PACKAGE)
R CMD INSTALL mypackage
touch $@
Or you could just make install
the stub file itself and make it a non- .PHONY
rule.或者您可以只install
存根文件本身并使其成为非.PHONY
规则。
It sounds like you want to treat the installation as an intermediate step.听起来您想将安装视为中间步骤。 You can do this by adding您可以通过添加来做到这一点
.INTERMEDIATE: install
to your makefile.到你的makefile。
The make manual explains ( link ):制作手册解释( 链接):
If an ordinary file b does not exist, and make considers a target that depends on b, it invariably creates b and then updates the target from b.如果一个普通文件 b 不存在,并且 make 考虑一个依赖于 b 的目标,它总是创建 b,然后从 b 更新目标。 But if b is an intermediate file, then make can leave well enough alone.但是如果 b 是一个中间文件,那么 make 可以很好地保持原样。 It won't bother updating b, or the ultimate target, unless some prerequisite of b is newer than that target or there is some other reason to update that target.它不会更新 b 或最终目标,除非 b 的某些先决条件比该目标更新或有其他原因更新该目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.