自定义 R 在何处查找共享对象?
Customize where R looks for shared objects?
关于 RcppArmadillo,此问题类似于 this previous question。
一些快速上下文:
我目前必须在 CentOS 5 系统上工作。当然,CentOS 5 自带的编译器太旧了,所以我们安装了 gcc-4.8.3。现在,其他人担心与旧编译器的向后兼容性,因此新的 gcc 被放置在 opt
目录中。为了使用升级后的 g++,我必须在 R 中使用 Sys.setenv
设置 LD_LIBRARY_PATH
Sys.setenv(LD_LIBRARY_PATH = "/opt/gcc-4.8.3/rtf/lib:/opt/gcc-4.8.3/rtf/lib64")
现在,我还需要安装一个存档版本的 RcppArmadillo。我从 CRAN 获取存档包并安装:
install.packages("RcppArmadillo_0.3.930.1.tar.gz", repose=NULL, type="source")
这似乎没有问题,但是当我尝试加载库时出现以下错误:
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/usr/lib64/R/library/RcppArmadillo/libs/RcppArmadillo.so':
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /usr/lib64/R/library/RcppArmadillo/libs/RcppArmadillo.so)
据我所知,找到的 libstdc++.so
文件太旧,即不是 opt
目录中的新文件。我认为这可以通过在上面设置 LD_LIBRARY_PATH
来解决,但它似乎仍在寻找 /usr/lib64/
。我有什么办法让 R 在这个其他目录中查找以获取适当的 so
文件?当然,如果我做了一些奇怪的事情会导致这种情况,我愿意接受其他解决方案(除了覆盖旧的 gcc 版本之外)。
编辑
我还注意到在安装时 -shared
再次显示 usr/
路径而不是 opt/
路径。这就是我要更新的内容,因此 R 也会搜索 opt
目录。
* installing *source* package âRcppArmadilloâ ...
** package âRcppArmadilloâ successfully unpacked and MD5 sums checked
* checking LAPACK_LIBS divide-and-conquer complex SVD unavailable via R-supplied LAPACK
* divide-and-conquer algorithm for complex SVD will be redirected to default
** libs
g++ -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/usr/lib64/R/library/Rcpp/include" -I../inst/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c RcppArmadillo.cpp -o RcppArmadillo.o
g++ -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/usr/lib64/R/library/Rcpp/include" -I../inst/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c RcppExports.cpp -o RcppExports.o
g++ -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/usr/lib64/R/library/Rcpp/include" -I../inst/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c fastLm.cpp -o fastLm.o
g++ -shared -L/usr/local/lib64 -o RcppArmadillo.so RcppArmadillo.o RcppExports.o fastLm.o -L/usr/lib64/R/lib -lRlapack -L/usr/lib64/R/lib -lRblas -L/usr/bin/gfortran -L/usr/lib64/R/lib -lR
更新
我还尝试通过设置 PKG_LIBS += -L$(OPT_PATH)
在 .R
目录中创建一个 Makevars
文件来手动附加 opt
目录,其中 OPT_PATH = /opt/gcc-4.8.3/rtf/lib64
。编译期间的 shared
行如下所示:
g++ -shared -L/usr/local/lib64 -o RcppArmadillo.so RcppArmadillo.o RcppExports.o fastLm.o -L/usr/lib64/R/lib -lRlapack -L/usr/lib64/R/lib -lRblas -L/usr/bin/gfortran -L/opt/gcc-4.8.3/rtf/lib64 -L/usr/lib64/R/lib -lR
但我仍然得到同样的错误:
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found
更奇怪的是(至少对我而言)运行 ldd
显示 RcppArmadillo.so
文件指向正确的文件。
ldd /usr/lib64/R/library/RcppArmadillo/libs/RcppArmadillo.so
...
libstdc++.so.6 => /opt/gcc-4.8.3/rtf/lib64/libstdc++.so.6 (0x00002ae950a3d000)
...
确实包含 GLIBCXX_3.4.9
我最终找到了当前系统的解决方案。我需要与我们的 IT 部门协调以获得临时的 sudo 权限。然后,切换到root后,我需要导出以下两个环境变量。
export LD_LIBRARY_PATH=/opt/gcc-4.8.3/rtf/lib:/opt/gcc-4.8.3/rtf/lib64
export LD_RUN_PATH=/opt/gcc-4.8.3/rtf/lib:/opt/gcc-4.8.3/rtf/lib64
然后,我仍然以 root 身份打开 R 并 运行
install.packages('RcppArmadillo')
这在我们的 CentOS 5.8 系统上安装了最新的 RcppArmadillo 软件包,我们的 gcc-4.8.3 编译器位于 opt
的非标准位置。我通过切换到普通用户并成功加载包来验证安装是否有效。
关于 RcppArmadillo,此问题类似于 this previous question。
一些快速上下文:
我目前必须在 CentOS 5 系统上工作。当然,CentOS 5 自带的编译器太旧了,所以我们安装了 gcc-4.8.3。现在,其他人担心与旧编译器的向后兼容性,因此新的 gcc 被放置在 opt
目录中。为了使用升级后的 g++,我必须在 R 中使用 Sys.setenv
LD_LIBRARY_PATH
Sys.setenv(LD_LIBRARY_PATH = "/opt/gcc-4.8.3/rtf/lib:/opt/gcc-4.8.3/rtf/lib64")
现在,我还需要安装一个存档版本的 RcppArmadillo。我从 CRAN 获取存档包并安装:
install.packages("RcppArmadillo_0.3.930.1.tar.gz", repose=NULL, type="source")
这似乎没有问题,但是当我尝试加载库时出现以下错误:
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/usr/lib64/R/library/RcppArmadillo/libs/RcppArmadillo.so':
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /usr/lib64/R/library/RcppArmadillo/libs/RcppArmadillo.so)
据我所知,找到的 libstdc++.so
文件太旧,即不是 opt
目录中的新文件。我认为这可以通过在上面设置 LD_LIBRARY_PATH
来解决,但它似乎仍在寻找 /usr/lib64/
。我有什么办法让 R 在这个其他目录中查找以获取适当的 so
文件?当然,如果我做了一些奇怪的事情会导致这种情况,我愿意接受其他解决方案(除了覆盖旧的 gcc 版本之外)。
编辑
我还注意到在安装时 -shared
再次显示 usr/
路径而不是 opt/
路径。这就是我要更新的内容,因此 R 也会搜索 opt
目录。
* installing *source* package âRcppArmadilloâ ...
** package âRcppArmadilloâ successfully unpacked and MD5 sums checked
* checking LAPACK_LIBS divide-and-conquer complex SVD unavailable via R-supplied LAPACK
* divide-and-conquer algorithm for complex SVD will be redirected to default
** libs
g++ -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/usr/lib64/R/library/Rcpp/include" -I../inst/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c RcppArmadillo.cpp -o RcppArmadillo.o
g++ -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/usr/lib64/R/library/Rcpp/include" -I../inst/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c RcppExports.cpp -o RcppExports.o
g++ -I/usr/include/R -DNDEBUG -I/usr/local/include -I"/usr/lib64/R/library/Rcpp/include" -I../inst/include -fpic -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c fastLm.cpp -o fastLm.o
g++ -shared -L/usr/local/lib64 -o RcppArmadillo.so RcppArmadillo.o RcppExports.o fastLm.o -L/usr/lib64/R/lib -lRlapack -L/usr/lib64/R/lib -lRblas -L/usr/bin/gfortran -L/usr/lib64/R/lib -lR
更新
我还尝试通过设置 PKG_LIBS += -L$(OPT_PATH)
在 .R
目录中创建一个 Makevars
文件来手动附加 opt
目录,其中 OPT_PATH = /opt/gcc-4.8.3/rtf/lib64
。编译期间的 shared
行如下所示:
g++ -shared -L/usr/local/lib64 -o RcppArmadillo.so RcppArmadillo.o RcppExports.o fastLm.o -L/usr/lib64/R/lib -lRlapack -L/usr/lib64/R/lib -lRblas -L/usr/bin/gfortran -L/opt/gcc-4.8.3/rtf/lib64 -L/usr/lib64/R/lib -lR
但我仍然得到同样的错误:
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found
更奇怪的是(至少对我而言)运行 ldd
显示 RcppArmadillo.so
文件指向正确的文件。
ldd /usr/lib64/R/library/RcppArmadillo/libs/RcppArmadillo.so
...
libstdc++.so.6 => /opt/gcc-4.8.3/rtf/lib64/libstdc++.so.6 (0x00002ae950a3d000)
...
确实包含 GLIBCXX_3.4.9
我最终找到了当前系统的解决方案。我需要与我们的 IT 部门协调以获得临时的 sudo 权限。然后,切换到root后,我需要导出以下两个环境变量。
export LD_LIBRARY_PATH=/opt/gcc-4.8.3/rtf/lib:/opt/gcc-4.8.3/rtf/lib64
export LD_RUN_PATH=/opt/gcc-4.8.3/rtf/lib:/opt/gcc-4.8.3/rtf/lib64
然后,我仍然以 root 身份打开 R 并 运行
install.packages('RcppArmadillo')
这在我们的 CentOS 5.8 系统上安装了最新的 RcppArmadillo 软件包,我们的 gcc-4.8.3 编译器位于 opt
的非标准位置。我通过切换到普通用户并成功加载包来验证安装是否有效。