【问题标题】:Portable Makefiles that call Rscript调用 Rscript 的便携式 Makefile
【发布时间】:2017-02-14 06:11:06
【问题描述】:

我正在编写一个生成Makefiles 的R 包,我需要编写一个调用RscriptMakefile,然后再制作目标。问题的 MWE 如下。由于.INIT 的右侧未执行,因此错误退出。为file.rds 写食谱不符合我的需要。

a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`

all: file2.rds

file2.rds: file.rds
        cp file.rds file2.rds

clean:
        rm file.rds file2.rds

我能做些什么来修复这个Makefile 并保持它的便携性?在 R 扩展手册中,我无法使用 $(shell 来完成我想要完成的任务。


编辑

从@Spacedman 的第一个答案中,我了解到.INIT 是“扩展”/执行的,当且仅当它在某处用作变量时。太棒了! @Spacedman,我邀请您将以下 Makefile 复制到您自己的答案中,这样我就可以给您信用。

a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`

all: file2.rds

file2.rds:
        echo "file.rds should not have been built."

file3.rds:
        echo -n $(.INIT)
        cp file.rds file3.rds

clean:
        rm file.rds file2.rds

下面展示了我所希望的结果。

$ make file2.rds
echo "file.rds should not have been built."
file.rds should not have been built.
$ ls file.rds
ls: cannot access file.rds: No such file or directory
$ make file3.rds
echo -n `Rscript -e 'saveRDS('1', "file.rds")'`
cp file.rds file3.rds
$ ls file.rds
file.rds

【问题讨论】:

  • 什么错误?您是否希望 Makefile 在将其视为 file2.rds 的依赖项之前通过 .INIT 创建 file.rds
  • 是的,完全正确。我知道这很荒谬,但实际用例的不同足以让人说得通。
  • 如果你不能使用 $(shell 并且你不能使用食谱,我怀疑你已经吃饱了。我没有看到其他运行外部命令的方法。
  • 便携是什么意思?是否需要与 BSD make 一起使用?
  • BSD make, dmake, etc. 这是一个R package,所以它需要遵循Writing R Extensions guidelines

标签: r makefile rscript r-package


【解决方案1】:

我认为您需要使用:=$(shell ...) 因此:

.INIT := $(shell Rscript -e 'saveRDS('$(a)', "file.rds")')

这会生成simply expanded variable 而不是recursively expanded variable。我认为 Make 甚至不会费心查看您对 .INIT 的定义,因为它从未使用过。

反引号在 Make 中不能这样工作,您必须使用 $(shell ...)。你真的可以不用$(shell ...)任何地方吗?

https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html

测试:

$ rm file.rds  file2.rds 
$ make
cp file.rds file2.rds
$ ls file*rds
file2.rds  file.rds

这似乎表明 make 已经通过 R 脚本创建了 file.rds

如果您可以将反引号字符串放入配方中,则可以使其工作(正如您所发现的!)。请注意,我认为您不需要回显字符串,只需将其扩展即可,这似乎可行:

a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`

all: file2.rds

file2.rds:
    echo "file.rds should not have been built."

file3.rds:
    $(.INIT)
    cp file.rds file3.rds

【讨论】:

  • 是的,我真的不能在任何地方使用$(shell ...)
  • 查看我更新的帖子。你给了我解决方案的想法。随意将编辑变成您自己的答案,我会接受。
猜你喜欢
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 2011-02-01
  • 2011-02-20
  • 2016-06-20
  • 2011-03-06
  • 2013-11-24
  • 1970-01-01
相关资源
最近更新 更多