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