3

私が取り組んでいるプロジェクトでは、追加機能を動的にロードする機能を提供しています。そのために、dlopen を使用します。

このライブラリを見つけるために、モジュール パスと呼ばれるものがあります。そこには、共有ライブラリがあるデフォルトのパスがあります (それらの多くは出荷されています)。

現時点では、2 つのデフォルト パスがあります。最初に共有ライブラリのビルド ディレクトリを検索し、その後でインストール ディレクトリを検索します。これは、アプリケーションをインストールせずにアプリケーションを実行することも可能である必要があるためです (その場合、ビルド ディレクトリを最初に検索する必要があります)。

問題は、ユーザーがアプリケーションをソースからビルドして make install でインストールすると、ビルド ディレクトリのライブラリがデフォルトで読み込まれることです。これにより、クラッシュが発生します。そのため、後でユーザーがビルド ディレクトリを削除または名前変更した場合にのみ機能します。

質問はありません: アプリケーションがインストールされているかどうかを知るための (C++ またはビルド システムによる) トリックはありますか。問題は、機能が共有ライブラリに実装されており、モジュールを検索するために実装された方法が、ライブラリにリンクする他のアプリケーションでも機能する必要があることです (したがって、実行可能ファイルのパスに依存することはできません)。ビルドシステムとして CMake を使用しています。

状況をさらに困難にするために、このソリューションは Windows、Linux、および Mac OS X で動作する必要があります。

編集:

さらに調査したところ、問題はより複雑になりました。これは状況です:

  • 小さな実行可能ファイルがあります
  • さらに、「メイン」ライブラリ main.so があります。
  • 次に、動的にロードされたライブラリ lib.so があります
  • main.so に対する lib.so リンク

問題は、lib.so の rpath にビルド ディレクトリの main.so への絶対パスがあることです。@MSalters のヒントのおかげで、正しいバージョンの lib.so (インストール ディレクトリにあるもの) を確実にロードするようにハックすることができましたが、rpath にビルド パスがあるため、間違ったメインをロードします。 .so (つまり、実際には、メモリ内に main.so の 2 つのコピーがあります。これは混乱を招きます)。

ライブラリからビルド パスへのこの参照を削除する方法はありますか? rpathに関連するcmakeのすべてのオプションを試しましたが成功しませんでした

4

2 に答える 2

1

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

getcwd()これらのすべてのプラットフォームで同等のものがありますが、それはあなたが望むものではないかもしれません-それはあなたが実行可能ファイルを実行する方法に依存します。

プロセスの場所を取得することはシステム固有だと思いますが、それをラップするのはそれほど難しいことではありません。

于 2011-07-15T12:06:27.547 に答える
0

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

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

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

Windows システムについてはよくわかりませんが、これを行う標準的な方法は、実行可能ファイルと同じディレクトリにあるプラグインを検索することだと思います。

于 2011-07-18T15:45:45.830 に答える