Как указать (non-R) путь библиотеки для загрузки динамической библиотеки в R?
При попытке установить readxl
или haven
в R (обе зависимости 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 находил мой локальный путь?
Обратите внимание, что это не проблема с пулом R-библиотеки, а вместо этого для не-R-зависимости, которую имеет пакет R. Если бы я компилировал и связывал код С++, 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")
но это не так, как указано выше.
Ответы
Ответ 1
Обычно метод 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
, и это оказалось очень полезным, потому что оно показало, что общий объект даже не пытался ссылаться на libiconv. Зная это, я понял, что могу вручную добавить ссылку через флаг -liconv
. Спасибо @knb!
Дополнительная информация
На стороне пакета вещей соответствующие сведения о подключении библиотек к пакетам R можно найти в руководстве для создания библиотек. На стороне конфигурации системы руководство R-admin содержит несколько полезных разделов.
Ответ 2
Эти библиотеки действительно должны быть стандартными для системы на основе RH и быть найдены.
Если вы должны добавить их в R, вы должны сделать это, прежде чем запускать R. Один из способов - через LD_LIBRARY_PATH
, лучший способ - отредактировать файл в /etc/ld.so.conf.d/
(при условии, что RH/CentOS тоже есть), Возможно, через /etc/environment
.
Изменить: Если /etc/
находится вне досягаемости, вы можете сделать все ниже $HOME
. Работает стандартная оболочка, и R имеет свои собственные .Rprofile
и .Renviron
. Вы можете иметь те, которые ниже $HOME
для всех ваших проектов, и/или в каталоге для каждого проекта --- см. help(Startup)
.
Ответ 3
Запускаете ли вы код на 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, и ошибка должна быть исправлена.
Ответ 4
Вы установили R через rpm или скомпилировали его самостоятельно?
решение 1
Если у вас есть разрешение на изменение исполняемого файла R (shell script), вы можете попробовать следующее:
Изменить ~/.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=...
...
...
Решение 2
Или вы можете 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