R 命令构建。失败:"argument is of length zero"

R CMD build . fails: "argument is of length zero"

R CMD build . 我的包裹失败,并出现以下无用的输出:

* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘myPackage’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
Error in if (dep$op != ">=") next : argument is of length zero
Execution halted

RStudio 也给出无用的输出:

ERROR: The build directory does not contain a DESCRIPTION file so cannot be built as a package.

Build directory: ~/myPackage

DESCRIPTION 文件显然存在)

这是我的 DESCRIPTION 文件:

Package: myPackage
Version: 0.1.0
Title: This is my package
Author: Michael Chirico
Maintainer: Michael Chirico <my_email@gmail.com>
Depends: R
Description: My package is great!
Imports: Rcpp (>= 1.0.0)
LinkingTo: Rcpp

我的包结构有什么问题?

更新2020-04-27

从当前的 svn 修订版 (78311) 开始,这个问题已过时——如果未给出 >=,内部函数 tools:::.split_description 现在会简单地删除 R 依赖。

这是此错误报告的结果:

https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17768


与 R 版本 4.0.0 及更早版本相关

Depends: R 必须 具有 R 版本依赖性:

Depends: R (>= 3.0.0)

(或任何合适的)

这在Writing R Extensions中有说明:

It makes no sense to declare a dependence on R without a version specification, nor on the package base: this is an R package and package base is always available.

所以,我也可以只删除这一行(如果我的包没有其他依赖项)。

有了这个,构建马上就完成了。

虽然回想起来很清楚,但也许找出问题所在的途径也可以说明问题(因为这个特定的错误消息没有给我任何搜索结果):

Error in if (dep$op != ">=") next : argument is of length zero

当然看起来像 R 代码一样熟悉——显然 dep$op(无论是什么)出于某种原因被声明为 missing/not。不清楚的是 executed/what 函数的什么代码产生了这个错误。

但是,不管是什么代码,都必须在the R source里面,所以我们可以:

  1. 试试我们在 GitHub 的存储库中搜索消息的运气(可能很难匹配,因为 delimiters/other 字符通常从网络搜索中删除)
  2. 克隆 repo 并在源代码中使用 grep(等)(更灵活,但如果您还没有,则需要下载完整的 R 源代码)

今天,我有幸在两个文件中得到了一个hit on GitHub for "if (dep$op != ">=") next"src/library/tools/R/build.R 看起来像在鼻子上。

这是找到该片段的区域:

ixup_R_dep <- function(pkgname, ver = "2.10")
    {
        desc <- .read_description(file.path(pkgname, "DESCRIPTION"))
        Rdeps <- .split_description(desc)$Rdepends2
        for(dep in Rdeps) {
            if(dep$op != '>=') next
            if(dep$version >= package_version(ver)) return()
        }

这在 tools 包中,因此可以使用辅助函数,例如tools:::.read_description.

有了这个,很容易看出 Rdeps 正在捕获 DESCRIPTIONDepends: R 部分,并且它也希望找到版本标签; dep$op 是应用于 dependency 的 operator。