2011-07-15 10 views
3

私が取り組んでいるプロジェクトでは、追加機能を動的に読み込むことができます。そのために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のすべてのオプションを試しました

+0

代わりにクラッシュを修正する方が簡単でしょうか? – MSalters

+0

問題は、ロードされたライブラリがメインライブラリとリンクしていることです。ビルドディレクトリにあるものはビルドディレクトリにあるものへの完全パスを持ち、インストールされているパスには相対パスがあるので、両方ともロードされます。その後、競合が発生する(または具体的には、シェルトンはライブラリの2番目のコピーで初期化されません)。 –

+0

それは(2番目のライブラリをロードしています)非常に簡単に検出できるもののように聞こえます。それはあなたの質問に対する答えではありませんか? – MSalters

答えて

1

実行ファイル自体がどこにあるか確認できませんか?ビルドディレクトリにある場合は、ビルドライブラリを使用します。インストールされている場合は、installを使用しますか?

getcwd()は、これらすべてのプラットフォームで同等の機能を備えていますが、実行可能ファイルをどのように実行するかによって異なります。

プロセスの場所を特定するのはシステム固有のものですが、それを包むのは難しいことではありません。

+0

私もこれについて考えました。問題は、私たちにライブラリがあり、そのライブラリに対して別の実行可能ファイルがリンクされている場合(たとえば、テスト用に別のライブラリが実行されている場合)、もう動作しません。 –

0

インストールされているバージョンでは、rpathにビルドディレクトリがありません。

リンクを2回(ビルドバージョンでは1回、インストールバージョンでは1回)することができます。通常、* nixシステムでは、インストールされたバイナリにはプラグインを探す静的パスがあります。いくつかの環境変数(またはコマンドライン引数)を定義してビルド実行のためにオーバーロードすることができます(また、ビルド環境でラッパースクリプトを使用して設定することもできます)。

いくつかのプロジェクト(Firefoxなど)でどのように解決されているか確認してください。

私はWindowsシステムについてよく知らないけど、これを実行する標準的な方法は、実行可能ファイルと同じディレクトリ内のプラグインを検索することだと思います。

関連する問題