如何为R中的动态库加载指定(非R)库路径? [英] How to specify (non-R) library path for dynamic library loading in R?
问题描述
当安装程序运行加载测试时,尝试在R(tidyverse
的两个依赖项)中安装readxl
或haven
时,仍然出现以下错误:
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屋!