Как указать (не 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

Другие вопросы по тегам