Как указать (не 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 выполнял поиск в моем локальном пути к 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")
но это не так, как указано выше.
4 ответа
Обычно 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 есть несколько полезных разделов.
Вы запускаете код в 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, и ошибка должна быть исправлена.
Эти библиотеки действительно должны быть стандартными для системы, основанной на RH, и должны быть найдены.
Если вы должны добавить их в R, вы должны сделать это, прежде чем запустить R. Один путь через LD_LIBRARY_PATH
лучше отредактировать файл в /etc/ld.so.conf.d/
(при условии, что RH/CentOS тоже это имеют). Остальное может быть через /etc/environment
,
Изменить: если /etc/
вне досягаемости, вы можете сделать все ниже $HOME
, Стандартная реализация оболочки работает, а R имеет свою собственную .Rprofile
а также .Renviron
, Вы можете иметь те ниже $HOME
для всех ваших проектов и / или в каталоге для каждого проекта --- см. help(Startup)
,
Я положил export LD_LIBRARY_PATH=...
заявления в файл ~/.profile
. Таким образом, как командная строка R, так и RStudio Server смогут найти общую библиотеку.
В моем случае я пытался получить Rglpk
пакет, чтобы найти libglpk.so
файл. Согласно записи в блоге Стефана Липпена,.profile
файл является предпочтительным местом для таких конфигураций, не связанных строго с bash
.
Вы устанавливали R через rpm или сами его компилировали?
решение 1
Если у вас есть разрешение на изменение исполняемого файла R (сценария оболочки), вы можете попробовать это:
редактировать ~/.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