私が取り組んでいるプロジェクトでは、追加機能を動的に読み込むことができます。そのためにdlopenを使用します。dlopenを使って動的にロードするライブラリを見つけるには
このライブラリを見つけるには、モジュールパスと呼ばれるものがあります。そこには共有ライブラリがあるデフォルトパスがあります(それらの多くは出荷されています)。
現時点では、2つのデフォルトパスがあります。最初に、共有ディレクトリのビルドディレクトリを探し、その後でインストールディレクトリを探します。これは、アプリケーションをインストールせずに実行することも可能でなければならないからです(その場合は、最初にビルドディレクトリを調べる必要があります)。
問題は、ユーザーがアプリケーションをソースからビルドし、それをmake installでインストールすると、ビルドディレクトリのライブラリがデフォルトで読み込まれるということです。これによりクラッシュが発生します。したがって、後でユーザーがビルドディレクトリを削除または名前を変更する場合にのみ機能します。
いいえ質問:アプリケーションがインストールされているかどうかを知るためのトリック(C++またはビルドシステムのいずれか)がありますか。問題は、機能が共有ライブラリに実装されており、モジュールを検索するための実装された方法は、私たちのライブラリにリンクする他のアプリケーション(つまり、実行可能ファイルのパスに依存できない)でも機能することです。 CMakeをビルドシステムとして使用します。
はさらに困難な状況を作るために、解決策は、Windows、Linux、およびMac OS X上で動作するように持ってEDIT:
私はさらに調査し、問題がより複雑です。これは状況です:
- 小さな実行ファイルがさらに「メイン」のライブラリmain.so
- が、その後
- lib.so lib.so動的にロードされるライブラリがそこにありますされていますmain.soとのリンク
問題は、lib.soはrpathのbuildディレクトリにmain.soの絶対パスがあることです。 @MSaltersのヒントのおかげで、私はlib.so(インストールディレクトリにあるもの)の正しいバージョンを確実に読み込めるようにハックすることができましたが、rpathにビルドパスがあるので、間違ったmain .so(実際にはメモリ内にmain.soという2つのコピーがあります - これは物事を混乱させます)。
ライブラリからビルドパスへのこの参照を削除する方法はありますか?私は成功のないrpathに関連するcmakeのすべてのオプションを試しました
代わりにクラッシュを修正する方が簡単でしょうか? – MSalters
問題は、ロードされたライブラリがメインライブラリとリンクしていることです。ビルドディレクトリにあるものはビルドディレクトリにあるものへの完全パスを持ち、インストールされているパスには相対パスがあるので、両方ともロードされます。その後、競合が発生する(または具体的には、シェルトンはライブラリの2番目のコピーで初期化されません)。 –
それは(2番目のライブラリをロードしています)非常に簡単に検出できるもののように聞こえます。それはあなたの質問に対する答えではありませんか? – MSalters