Ubuntu 上的 Rcpp 库无法构建(找不到编译器)
Rcpp Library Won't Build (Can't find Compiler) on Ubuntu
我有一个依赖于 Rcpp
的包,并使用了从 src/
中的子目录编译的另外两个库。该软件包使用 clang 编译器在 Mac OSX 上构建良好。但是,在 RStudio Ubuntu 服务器上,它无法构建。构建的前两个步骤(在 link 中的子目录中创建静态库)工作正常,我可以看到如下所示的合理构建命令:
g++ -Wall -I../../inst/include/ --std=c++11 -lhts -L../htslib/ -lz -lm -c -o someLibFile.o someLibFile.cpp
然而,在构建过程的最后一步,它尝试构建 Rcpp
代码并绑定到库,由于某种原因,它似乎无法将编译器命令放在前面( g++
) 并且只输出命令的后半部分。
-o mypackage.so RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -L/htslib/ -Lpbbam/ -L/mnt/software/r/R/3.1.1/usr/lib/R/lib -lR
相比之下,在 Mac 上它构建得很好,在这个最终命令前面附加 clang++
和其他标志:
clang++ -std=c++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o pbbamr.so LoadData.o RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -Lhtslib/ -Lpbbam/ -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
如何在这一步使用 Ubuntu 上的 g++ 编译器?我有一个自定义的 Makevars
文件,但它只是为了在子目录中构建依赖项,所以我不知道为什么这会导致任何问题(因为它适用于 Mac OSX).
更多信息
如果我删除 Makevars
文件,似乎可以找到编译器。但是,我正在使用的 Makevars
文件本质上是 R 扩展指南中给出的示例的直接副本,其中添加了一个启用 C++11 的示例:
CXX_STD = CXX11
.PHONY: all mylibs
all: $(SHLIB)
$(SHLIB): mylibs
mylibs:
(cd subdir; make)
删除行 CXX_STD
后,它确实会在命令前面添加一个编译器。
简述:
- 你的 R 安装是什么?您可能应该 运行 迈克尔通过 CRAN 提供的二进制文件;它们基于我的 Debian 上传;我 运行 这些也在一堆机器上
- 原因是 R 'remembers' 其编译时设置通过
$RHOME/etc/Makefconf
。这应该只是 CXX=g+=
.
- 当您安装
r-base-dev
(来自 Ubuntu 或来自 CRAN 的更新版本)时,您还会获得 build-essential
软件包以及所有常见的依赖项。有了这些东西就可以了。
但是,如果您正在做一些特殊的或本地的事情,那么您必须处理本地更改。基本 Ubuntu 设置被成千上万的人和日常工作使用——包括 Travis 为无数 GitHub 回购构建。
这是由于使用 outdated/unusual R 安装导致的,它对 C++11 的支持很差。解决此问题的最佳方法是升级到更新版本的 R,或使用标准 R 安装 (sudo apt-get install r-base-dev
)。下面描述了一个糟糕的解决方法。
问题原因和不好的解决方法
在编写使用 C++11 的 R 扩展时,通常在 Makevars
文件中设置 CXX_STD = CXX11
或在 DESCRIPTION
文件中列出 SystemRequirements: C++11
。这些将触发 R 使用 Makeconf
文件(位于 file.path(R.home(), "etc/Makeconf")
)中的以下标志设置的编译器。
CXX1X
CXX1XFLAGS
CXX1XPICFLAGS
CXX1XSTD
请注意,其中一些可能已在此文件中设置,但并非所有设置都可能表明存在问题。如果这些设置有问题或未设置,R 似乎使用空字符串 "" 作为 C++ 代码的 compiler/linker,导致上面显示的没有给出编译器参数的问题。
如果升级不是一个选项并且您需要在已知机器上部署,一个解决方法是通过制作一个更特殊的 Makevars
文件来手动设置 C++11。例如,您可以:
- 从
Makevars
文件中删除 CXX_STD=CXX11
行。
- 从
DESCRIPTION
文件中删除 SystemRequirements: C++11
。
- 添加
--std=c++11
和 PKG_CPPFLAGS
、PKG_CFLAGS
、PKG_CXXFLAGS
或用于编译代码的任何变量所需的任何其他要求,以手动设置所需的标志(假设机器的编译器确实支持 C++11)。
上述解决方案不是特别可靠,但可以在机器无法升级的情况下用作变通方法。
感谢@DirkEddelbuettel 不仅撰写 Rcpp
而且愿意在 Whosebug 上支持它并帮助解决此类问题。
我有一个依赖于 Rcpp
的包,并使用了从 src/
中的子目录编译的另外两个库。该软件包使用 clang 编译器在 Mac OSX 上构建良好。但是,在 RStudio Ubuntu 服务器上,它无法构建。构建的前两个步骤(在 link 中的子目录中创建静态库)工作正常,我可以看到如下所示的合理构建命令:
g++ -Wall -I../../inst/include/ --std=c++11 -lhts -L../htslib/ -lz -lm -c -o someLibFile.o someLibFile.cpp
然而,在构建过程的最后一步,它尝试构建 Rcpp
代码并绑定到库,由于某种原因,它似乎无法将编译器命令放在前面( g++
) 并且只输出命令的后半部分。
-o mypackage.so RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -L/htslib/ -Lpbbam/ -L/mnt/software/r/R/3.1.1/usr/lib/R/lib -lR
相比之下,在 Mac 上它构建得很好,在这个最终命令前面附加 clang++
和其他标志:
clang++ -std=c++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o pbbamr.so LoadData.o RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -Lhtslib/ -Lpbbam/ -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
如何在这一步使用 Ubuntu 上的 g++ 编译器?我有一个自定义的 Makevars
文件,但它只是为了在子目录中构建依赖项,所以我不知道为什么这会导致任何问题(因为它适用于 Mac OSX).
更多信息
如果我删除 Makevars
文件,似乎可以找到编译器。但是,我正在使用的 Makevars
文件本质上是 R 扩展指南中给出的示例的直接副本,其中添加了一个启用 C++11 的示例:
CXX_STD = CXX11
.PHONY: all mylibs
all: $(SHLIB)
$(SHLIB): mylibs
mylibs:
(cd subdir; make)
删除行 CXX_STD
后,它确实会在命令前面添加一个编译器。
简述:
- 你的 R 安装是什么?您可能应该 运行 迈克尔通过 CRAN 提供的二进制文件;它们基于我的 Debian 上传;我 运行 这些也在一堆机器上
- 原因是 R 'remembers' 其编译时设置通过
$RHOME/etc/Makefconf
。这应该只是CXX=g+=
. - 当您安装
r-base-dev
(来自 Ubuntu 或来自 CRAN 的更新版本)时,您还会获得build-essential
软件包以及所有常见的依赖项。有了这些东西就可以了。
但是,如果您正在做一些特殊的或本地的事情,那么您必须处理本地更改。基本 Ubuntu 设置被成千上万的人和日常工作使用——包括 Travis 为无数 GitHub 回购构建。
这是由于使用 outdated/unusual R 安装导致的,它对 C++11 的支持很差。解决此问题的最佳方法是升级到更新版本的 R,或使用标准 R 安装 (sudo apt-get install r-base-dev
)。下面描述了一个糟糕的解决方法。
问题原因和不好的解决方法
在编写使用 C++11 的 R 扩展时,通常在 Makevars
文件中设置 CXX_STD = CXX11
或在 DESCRIPTION
文件中列出 SystemRequirements: C++11
。这些将触发 R 使用 Makeconf
文件(位于 file.path(R.home(), "etc/Makeconf")
)中的以下标志设置的编译器。
CXX1X
CXX1XFLAGS
CXX1XPICFLAGS
CXX1XSTD
请注意,其中一些可能已在此文件中设置,但并非所有设置都可能表明存在问题。如果这些设置有问题或未设置,R 似乎使用空字符串 "" 作为 C++ 代码的 compiler/linker,导致上面显示的没有给出编译器参数的问题。
如果升级不是一个选项并且您需要在已知机器上部署,一个解决方法是通过制作一个更特殊的 Makevars
文件来手动设置 C++11。例如,您可以:
- 从
Makevars
文件中删除CXX_STD=CXX11
行。 - 从
DESCRIPTION
文件中删除SystemRequirements: C++11
。 - 添加
--std=c++11
和PKG_CPPFLAGS
、PKG_CFLAGS
、PKG_CXXFLAGS
或用于编译代码的任何变量所需的任何其他要求,以手动设置所需的标志(假设机器的编译器确实支持 C++11)。
上述解决方案不是特别可靠,但可以在机器无法升级的情况下用作变通方法。
感谢@DirkEddelbuettel 不仅撰写 Rcpp
而且愿意在 Whosebug 上支持它并帮助解决此类问题。