当安装程序运行加载测试时,尝试在R中编译readxl
或haven
(tidyverse
的依赖关系)时,我一直收到以下错误:
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '<my_lib_Path>/readxl/libs/readxl.so':
<my_lib_path>/readxl/libs/readxl.so: undefined symbol: libiconv
Error loading failed
我在libiconv.so
中包含的本地lib路径(不适用于R包)中有LD_LIBRARY_PATH
,我在我的R会话中验证Sys.getenv("LD_LIBRARY_PATH")
有该目录。
为什么R的动态库加载器不能找到这个共享对象? 我需要定义一个不同的特定于R的环境变量来让R中的动态库加载器搜索我的本地lib路径吗?
请注意,这不是R库路径的问题,而是R包具有的非R依赖性。如果我正在编译和链接C ++代码,gcc
将使用ld
,因此LD_LIBRARY_PATH
将跟踪动态依赖关系。 R似乎不尊重这种相当常见的方法,我似乎无法找到有关如何管理这些更细粒度的依赖性问题的任何文档。
!> sessionInfo()
R version 3.3.3 (2017-03-06)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
>
我之前编译过libiconv
,因为它是对其他东西的依赖(不记得现在的东西 - 可能不是R包给出当前的问题)。我尝试重新安装它,但没有任何区别。
我还尝试在安装之前手动加载库:
> dyn.load(".local/lib/libiconv.so")
> is.loaded("libiconv")
[1] TRUE
> install.packages("tidyverse")
但它如上所述失败。
答案 0 :(得分:9)
通常情况下,iconv
方法是从glibc
中获取的,iconv
是在构建相关R包时链接的。但是,无论出于何种原因,libiconv
在这种情况下会被解析为libiconv
,但在构建期间它不会被R包链接。
通过将以下行添加到haven/src/Makevars
源文件
PKG_LIBS=-liconv
R CMD INSTALL haven
然后让您从源Makevars
安装。但是,编辑软件包感觉很麻烦,而且每次升级都需要这样做,这听起来很麻烦。
另一种选择是使用withr::with_makevars
,它允许用户暂时控制withr::with_makevars(c(PKG_LIBS="-liconv"), install.packages("haven"), assignment="+=")
内容。使用这种技术,可以直接从repo安装:
readxl.so
信用:@ knb建议我使用ldd
检查-liconv
,结果证明这是非常有用的,因为它显示共享对象不是甚至尝试链接到 libiconv 。知道了,我意识到我可以通过{{1}}标志手动添加引用。谢谢@knb!
在包装方面,可以在the guide for building libraries中找到有关将库连接到R包的相关详细信息。在系统配置方面,the R-admin guide有一些有用的部分。
答案 1 :(得分:2)
您是否在RStudio Server中运行代码?如果是这样,这里的答案可能会有用。
我在加载动态库时遇到了类似的错误。该库位于LD_LIBRARY_PATH
中包含的路径中。当我在R控制台中运行代码时,它可以正确加载动态库。但是当我在RStudio中运行它时,你的帖子中出现了同样的错误。
原因是RStudio Server有自己的库搜索路径环境。您应该在/etc/rstudio/rserver.conf
中指定以下配置:
rsession-ld-library-path=/usr/lib64/:/usr/local/lib/:OTHER_PATH_OF_YOUR_LIB
重新启动RStudio Server,错误应该修复。
答案 2 :(得分:2)
这些库确实应该是基于RH的系统的标准,并且可以找到。
如果必须将它们添加到R,则必须在启动R 之前执行。一种方法是通过LD_LIBRARY_PATH
,更好的方法是在/etc/ld.so.conf.d/
中编辑文件(假设RH / CentOS也有)。否则可以通过/etc/environment
。
修改:如果/etc/
无法访问,您可以执行$HOME
以下的所有操作。标准shell实例化有效,R有自己的.Rprofile
和.Renviron
。对于所有项目,和/或每个项目目录,您可以拥有$HOME
以下的项目 - 请参阅help(Startup)
。
答案 3 :(得分:0)
我将export LD_LIBRARY_PATH=...
语句放入文件~/.profile
中。
这样,命令行R和RStudio服务器都能够找到共享库。
就我而言,我试图获取Rglpk
软件包来定位libglpk.so
文件。
根据{{3}},对于与.profile
不严格相关的这些类型的配置,bash
文件是首选位置。
答案 4 :(得分:-1)
您是通过rpm安装R还是自己编译?
如果您有权修改R可执行文件(shell脚本),可以试试这个:
修改~/.local/bin/R
或/usr/local/bin/R
或/usr/bin/R
#!/bin/bash
# Shell wrapper for R executable.
export LD_LIBRARY_PATH="<my_lib_Path>/readxl/libs/"
R_HOME_DIR=...
...
...
或者你可以vim ~/.local/bin/R
#!/bin/bash
# Shell wrapper for R executable.
export LD_LIBRARY_PATH="<my_lib_Path>/readxl/libs/"
/usr/bin/R
然后将~/.local/bin
添加到您的PATH