如何为R中的动态库加载指定(非R)库路径? [英] How to specify (non-R) library path for dynamic library loading in R?

查看:527
本文介绍了如何为R中的动态库加载指定(非R)库路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I keep getting the following error when attempting to install readxl or haven in R (both dependencies of tidyverse) post-compilation, when the installer runs the loading test:

** 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

我在LD_LIBRARY_PATH中包含的本地lib路径(不是R包)中有libiconv.so,并且我已经在我的R会话中验证Sys.getenv("LD_LIBRARY_PATH")具有该目录. 为什么R的动态库加载器找不到此共享库? 是否需要定义其他特定于R的环境变量,以使R中的动态库加载器搜索我的本地lib路径?

I have libiconv.so in a local lib path (not for R packages) that is included in LD_LIBRARY_PATH and I've verified in my R session that Sys.getenv("LD_LIBRARY_PATH") has that directory. Why can't R's dynamic library loader find this shared object? Is there a different R-specific environment variable I need to define to have the dynamic library loader in R search my local lib path?

请注意,这不是R库路径的问题,而是R包具有的非R依赖项.如果我正在编译和链接C ++代码,则gcc将使用ld,因此将使用LD_LIBRARY_PATH来跟踪动态依赖关系. R似乎并不尊重这种相当普遍的方法,而且我似乎找不到任何有关如何管理这些更细粒度的依赖关系问题的文档.

Please note that this is not an issue with an R library path, but instead for a non-R dependency that an R package has. If I were compiling and linking C++ code, gcc would use ld, and hence LD_LIBRARY_PATH to track down dynamic dependencies. R doesn't appear to respect this rather common approach, and I can't seem to find any documentation on how to manage these more fine-grained dependency issues.

!> 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包).我尝试重新安装它,但没有区别.

I had previously compiled libiconv because it was a dependency for something else (don't recall what now - likely not an R package given current problems). I tried reinstalling it, but made no difference.

我还尝试过在安装之前手动加载该库:

I have also tried manually loading the library prior to installation:

> dyn.load(".local/lib/libiconv.so")
> is.loaded("libiconv")
[1] TRUE
> install.packages("tidyverse")

但它如上所述失败.

推荐答案

通常,iconv方法是从glibc中拾取的,该方法在构建相关R软件包的过程中与之链接.但是,无论出于何种原因,在这种情况下,iconv都将解析为libiconv,但是在构建过程中,R程序包并未将其链接.

Normally, the iconv method is picked up from glibc, which is linked to during build of the R packages in question. For whatever reason, however, iconv is getting resolved to libiconv in this case, but it is not linked by the R packages during build.

可以通过在haven/src/Makevars源文件中添加以下行来明确链接到libiconv

One can make the linking to libiconv explicit by adding the following line to the haven/src/Makevars source file

PKG_LIBS=-liconv

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

which then let's you install from source R CMD INSTALL haven. However, editing packages feels hacky, plus this is something that will need to be done every upgrade, which sounds like a hassle.

另一种选择是使用 withr::with_makevars ,这使您可以临时控制Makevars内容.通过这种技术,可以直接从存储库中进行安装:

Another option is to use withr::with_makevars, which allows one to temporarily control Makevars content. With this technique, one can install directly from the repo:

withr::with_makevars(c(PKG_LIBS="-liconv"), install.packages("haven"), assignment="+=")


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


Credit: @knb suggested that I inspect the readxl.so with ldd and this turned out to be super useful because it showed that the shared object wasn't even trying to link to libiconv. Knowing that, I realized I could manually add the reference via the -liconv flag. Thanks @knb!

在包方面,有关将库连接到R包的相关详细信息可以在 R-管理指南有一些有用的部分.

On the package side of things, relevant details about connecting libraries to R packages can be found in the guide for building libraries. On the system configuration side, the R-admin guide has some useful sections.

这篇关于如何为R中的动态库加载指定(非R)库路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆