web-dev-qa-db-ja.com

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_に含まれるローカルライブラリパス(Rパッケージではない)に_LD_LIBRARY_PATH_があり、RセッションでSys.getenv("LD_LIBRARY_PATH")にそのディレクトリがあることを確認しました。 Rのダイナミックライブラリローダーがこの共有オブジェクトを見つけられないのはなぜですか? 動的ライブラリローダーをRでローカルライブラリパスを検索するために定義する必要がある別のR固有の環境変数はありますか?

これはRライブラリパスの問題ではなく、Rパッケージが持つR以外の依存関係の問題であることに注意してください。 C++コードをコンパイルしてリンクする場合、gccldを使用するため、動的依存関係を追跡するために_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")
_

上記と同じように失敗します。

18
merv

通常、iconvメソッドは、問題のRパッケージのビルド中にリンクされているglibcから取得されます。ただし、何らかの理由で、この場合iconvlibiconvに解決されますが、ビルド中にRパッケージによってリンクされません。

元の回避策

次の行をhaven/src/Makevarsソースファイルに追加することにより、libiconvへのリンクを明示的にすることができます

PKG_LIBS=-liconv

次に、ソースR CMD INSTALL havenからインストールします。ただし、パッケージの編集はハッキーな感じがします。さらに、これはアップグレードのたびに実行する必要がある作業であり、面倒なように思えます。

よりクリーンな回避策

別のオプションは withr::with_makevars を使用することです。これにより、Makevarsコンテンツを一時的に制御できます。この手法では、リポジトリから直接インストールできます。

withr::with_makevars(c(PKG_LIBS="-liconv"), install.packages("haven"), assignment="+=")

Credit:@knbはreadxl.solddで検査することを提案しました。これは、共有オブジェクトがlibiconvにリンクしようとしてもいないことを確認します。それを知って、-liconvフラグを使用して手動で参照を追加できることに気付きました。 @knbありがとう!

追加情報

物事のパッケージ側で、ライブラリをRパッケージに接続することに関する関連詳細は ライブラリ構築のガイド にあります。システム構成側では、 R-adminガイド にいくつかの便利なセクションがあります。

10
merv

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を再起動すると、エラーが修正されます。

5
Shuiping Chen

これらのライブラリは、RHベースのシステムでも標準であり、見つかるはずです。

それらをRに追加する必要がある場合は、追加する必要がありますRを開始する前に。 1つの方法は_LD_LIBRARY_PATH_を使用することです。より良い方法は、_/etc/ld.so.conf.d/_でファイルを編集することです(RH/CentOSにもそれがあると仮定)。それ以外の場合は、_/etc/environment_を使用します。

編集: _/etc/_が届かない場合、_$HOME_以下のすべてを実行できます。標準シェルのインスタンス化が機能し、Rには独自の_.Rprofile_および_.Renviron_があります。すべてのプロジェクトについて、および/またはプロジェクトごとのディレクトリに_$HOME_以下を含めることができます---help(Startup)を参照してください。

2