当安装程序运行加载测试时,尝试在R(readxl的两个依赖项)中安装haventidyverse时,出现以下错误:

** 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 session 中已验证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")

但是失败如上。

最佳答案

通常,从iconv中提取glibc方法,该方法在构建相关R软件包时链接到该方法。但是,无论出于何种原因,在这种情况下,iconv都将解析为libiconv,但是在构建过程中,R软件包并未链接它。

原始解决方法

通过将以下行添加到libiconv源文件中,可以使对haven/src/Makevars的链接的显示明确

PKG_LIBS=-liconv

然后让您从源代码R CMD INSTALL haven安装。但是,编辑软件包感觉很麻烦,而且每次升级都需要完成此操作,这听起来很麻烦。

更清洁的解决方法

另一种选择是使用 withr::with_makevars ,它允许一个人临时控制Makevars内容。使用这种技术,可以直接从仓库中安装:
withr::with_makevars(c(PKG_LIBS="-liconv"), install.packages("haven"), assignment="+=")

信用:@knb建议我使用readxl.so检查ldd,这被证明是 super 有用的,因为它表明共享对象甚至没有试图链接到 libiconv 。知道这一点,我意识到我可以通过-liconv标志手动添加引用。谢谢@knb!

附加信息

在包方面,可以在the guide for building libraries中找到有关将库连接到R包的相关详细信息。在系统配置方面,the R-admin guide有一些有用的部分。

10-07 16:27