简体   繁体   English

用于构建链接到分析的 R 包的 Makefile

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM