【问题标题】:Rcpp fails to compile c++ code after series of updates在一系列更新后,rcpp 无法编译 c++ 代码
【发布时间】:2020-12-31 01:50:52
【问题描述】:

我想让我的操作系统、R 和 R 软件包保持最新。通过升级到 OSX 10.15.6 并升级到 R 4.0.2,我在不知不觉中陷入了困境。目前,Rcpp 无法编译 c++ 代码,我认为这会导致某些软件包的 CRAN 安装失败(例如glmmTMB),并且还会导致从源代码安装失败。我将描述我所做的事情,希望有人能阐明解决方案。


大致来说,这是我所做的:

  1. 已安装 OSX 10.15.6

我不记得日期,但它是最近的。我不知道这与问题的关系有多密切,我在安装之前需要Rcpp 的其他 R 包(例如rstan)时遇到问题。

  1. 在尝试运行一些旧的 glmmTMB 模型时遇到问题

确切的错误与this issue 相同。我按照该线程上的各种解决方案无济于事。也许最令人沮丧的是尝试从源代码安装时,然后无法编译某些 c++。

这不是我第一次看到类似的错误。当我尝试安装rstan 时发生了类似的事情,所以我在a similar issue 下寻求他们的repo 帮助。没有任何帮助。

这是在 R 3.6 上,所以我认为也许值得更新 R 和 glmmTMB。在执行此操作之前,我想安装 Xcode,而不仅仅是命令行开发人员工具,希望安装能够确保我将所有与 clang 和 c++ 编译器相关的东西都放在一边。

  1. 安装 Xcode 以帮助设置基线 C++ 环境

相对轻松,能够构建和编译相当简单的 c++ 项目。

  1. 已安装 R 4.0.2

从 r-project 站点,我安装了 R-4.0.2.pkg 没有问题,并使用默认安装设置。根据the R project Tools site 的说法,我对安装 Xcode 感到放心,并继续安装 GNU Fortran 8.2 安装程序。

  1. 按照@coatless 的 Rcpp 安装指南进行操作

发现了this guide,并遵循了每一步,除了那些与xcode-select相关的步骤。

  1. 根据指南测试 Rcpp 和 RcppArmadillo

最后一步是使用简单的helloworld.cpp 测试来测试安装。失败并出现此错误(为清楚起见进行了删节):

> Rcpp::sourceCpp("~/Documents/BergenLab/nlp_cancer_metaphor/helloworld.cpp")
In file included from helloworld.cpp:1:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/RcppArmadillo/include/RcppArmadillo.h:31:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/RcppArmadillo/include/RcppArmadilloForward.h:26:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include/RcppCommon.h:29:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include/Rcpp/r/headers.h:67:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include/Rcpp/platform/compiler.h:100:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:317:9: error: no member named 'signbit' in the global namespace
using ::signbit;
      ~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [helloworld.o] Error 1
clang++ -mmacosx-version-min=10.13 -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I../inst/include   -I"/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/4.0/Resources/library/RcppArmadillo/include" -I"/Users/alex/Documents/BergenLab/nlp_cancer_metaphor" -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include   -fPIC  -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -c helloworld.cpp -o helloworld.o
Error in Rcpp::sourceCpp("~/Documents/BergenLab/nlp_cancer_metaphor/helloworld.cpp") : 
  Error 1 occurred building shared library.
  1. 尝试调试Rcpp无济于事

发现了一些有些相关的报道,例如Packages cannot build from source due to math.h not foundRcpp doesn't under macOS, math.h not foundSource Cpp file failed due to math.h not foundCannot compile R packages with c++ code after updating to macOS Catalina

这些答案中的任何解决方案都没有任何帮助。给我反馈的唯一解决方案是使用installer 安装macOS_SDK_headers_for_macOS_10.14.pkg,随后给了我installer: Error - the package path specified was invalid(不知道这意味着什么)。

  1. 从源安装 glmmTMB 失败

上述glmmTMB 问题的解决方案之一建议从源代码安装。这是我尝试的错误:

* installing *source* package ‘glmmTMB’ ...
** package ‘glmmTMB’ successfully unpacked and MD5 sums checked
** using staged installation
** libs
clang++ -mmacosx-version-min=10.13 -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG  -I'/Library/Frameworks/R.framework/Versions/4.0/Resources/library/TMB/include' -I'/Library/Frameworks/R.framework/Versions/4.0/Resources/library/RcppEigen/include' -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include   -fPIC  -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -c glmmTMB.cpp -o glmmTMB.o
In file included from glmmTMB.cpp:1:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/TMB/include/TMB.hpp:53:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/RcppEigen/include/Eigen/Dense:1:
In file included from /Library/Frameworks/R.framework/Versions/4.0/Resources/library/RcppEigen/include/Eigen/Core:96:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/complex:245:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:317:9: error: no member named 'signbit' in the global namespace
using ::signbit;
      ~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
13 warnings and 20 errors generated.
make: *** [glmmTMB.o] Error 1
ERROR: compilation failed for package ‘glmmTMB’
* removing ‘/Library/Frameworks/R.framework/Versions/4.0/Resources/library/glmmTMB’
* restoring previous ‘/Library/Frameworks/R.framework/Versions/4.0/Resources/library/glmmTMB’
Warning in install.packages :
  installation of package ‘glmmTMB’ had non-zero exit status

总的来说,我仍然无法运行我的glmmTMB 模型(而且我认为也无法构建rstan)。我的 c++ 编译器必须关闭,但我是 c++ 初学者,不确定如何解释我遇到的错误。头文件有问题,但似乎不是因为缺少math.h(就像大多数其他帖子一样)。不言而喻,但任何帮助将不胜感激!


编辑 1

我已尝试缩小错误范围,因此按照@coatless 指南中的每一步操作,完全按照那里列出的内容和 R 安装文档进行操作。我的具体步骤:

  1. 删除gfortran 8.2。删除了 ~/.Renviron~/.R/Makevars。使用unlink()从Rstudio取消链接这两个文件。

  2. 运行xcode-select --install,返回“使用“软件更新”安装更新。”因此,softwareupdate --list 估计没有什么需要更新的。无论如何,我使用sudo rm -rf /Library/Developer/CommandLineTools 卸载了命令行工具,并使用xcode-select —install 安装了命令行工具。到目前为止,一切都按预期工作。 gccclang++ 正在编译小型 c++ 程序而没有问题。

  3. 根据R手册,从https://mac.r-project.org/libs-4/,我安装了pcre2-10.34-darwin.17-x86_64.tar.gzxz-5.2.4-darwin.17-x86_64.tar.gz,和readline-5.2.14-darwin.17-x86_64.tar.gz/usr/local。这里没有大问题,虽然我不确定如何验证这些是否按预期工作。

  4. 在 RStudio 中重新启动 R 会话。

  5. 使用install.packages(c(‘Rcpp’, ‘RcppArmadillo’)) 安装了 Rcpp 和 RcppArmadillo

  6. 使用 cmets 中提到的幻灯片 15 中的代码创建了一个 ~/helloworld.cpp

  7. 运行 Rcpp::sourceCpp("~/helloworld.cpp") 失败,并出现帖子正文中提到的确切错误。同样,evalCpp() 失败并出现类似错误。

【问题讨论】:

  • 这似乎发生在每个 macOS 更新上,并且每次推荐的课程操作似乎(重新)安装一些组件为 generally outlined on James's site - 但我不知道任何细节,因为我做我的生活更轻松,只需在 Linux 上运行,即使我们升级...
  • 另外,你确实需要分解。我不知道你为什么说“除了一个步骤外,所有步骤都遵循@coatless 指南”。这些通常不是可选的。安装 Rcpp 后,检查 Rcpp 是否正常工作。 Rcpp犰狳。 glmmTMBrstan 都比较复杂,但不能正常工作,因为基础很糟糕。一。步。在。答:时间。并测试测试测试。
  • 嗨@DirkEddelbuettel,我感谢您的回复,即使它有点反手。这是我第一次使用 Rcpp 及其生态系统,所以让我们在这里一起工作:只是无法使用 Rcpp 编译您在幻灯片 15 上的 dirk.eddelbuettel.com/papers/rcpp_rfinance_may2017.pdf 找到的测试代码。cppFunction()cppEval() 也失败了。我看到了与我的观点 (6) 相同的错误。我会回到詹姆斯的指南并报告。
  • 是的!很容易陷入复杂的境地。最简单的测试仍然是Rcpp::evalCpp("2+2")。如果 4 没有返回,那么您就有问题了。 (遗憾的是,RcppArmadillo 是下一个,它对你有更多的 macOS 特定要求,我对 Linux 用户知之甚少。)分层确实是关键。分解。检查每个部分。
  • 我们可以删除 rstan 标签,因为这不是 stan 或 rstan 特定的吗?

标签: r macos clang


【解决方案1】:

经过一番挖掘,结果证明问题既不是glmmTMBRcpp,也不是任何高级别的问题。据我了解:当 R 使用 Rcpp 编译 c++ 代码时,一组参数被传递给系统 c++ 编译器。就我而言,这个编译器是 clang++,因为我刚刚安装了 Xcode。 c++ 编译器依赖于一组c++ header files 以正确的顺序包含在完全中。似乎我的顺序不正确,因此导致了一系列关于“缺少模板定义”的错误。

我考虑更改包含的顺序,但找不到任何简单的解决方案。我知道Rcpp 正在为 clang++ 调用一组非常具体的参数,所以我研究了如何阐明答案。我查看了 clang++ 的手册以了解 -isysroot-I 的含义,并且觉得它们可能在重新配置系统头文件的编译方式方面发挥了作用。从下面的一个线程中,我发现了$(R RHOME)/etc/Makeconf Makefile 并着手将 OSX SDK 的目录从我认为的命令行工具路径更改为 Xcode 路径。这似乎解决了问题。

我曾经找到这个解决方案的一些线程:Cannot compile R packages with c++ code after updating to macOS CatalinaCatalina C++: Using <cmath> headers yield error: no member named 'signbit' in the global namespace

什么对我有用:

  1. 注意当前头文件搜索

来自clang++ -Wp,-v -E -

#include <...> search starts here:
 /usr/local/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
  1. 注意 OSX SDK 路径

来自xcrun --show-sdk-path

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
  1. 修改 R 配置

使用vim $(R RHOME)/etc/Makeconf,将CPPFLAGS 标志更改为:

CPPFLAGS = -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -I/usr/local/include

注意这个 SDK 目录是如何在步骤 2 中找到的。这显然清理了 SDK 头文件包含的位置和顺序。

  1. 从源重新安装glmmTMB

我在尝试安装 glmmTMB 模型时仍然看到 FreeADFunObject 错误,所以我回到 this GH thread 并遵循第一个建议:从源重新安装。这以前不起作用,因为我需要正确设置 c++ 配置,我在最后两个步骤中修复了它。

因此,install.packages("glmmTMB", type="source") 安装没有问题,我现在可以构建和安装 glmmTMB 模型。


为了后代:

> sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

【讨论】:

  • 在主动语态中使用 Rcpp 并不完全正确。是 R 做所有的调用。我们只是提供一些参数,主要包括目录。
猜你喜欢
  • 2018-02-02
  • 2020-02-07
  • 1970-01-01
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
  • 2015-07-23
  • 2017-08-25
相关资源
最近更新 更多