私が取り組んでいるプロジェクトでは、追加機能を動的にロードする機能を提供しています。そのために、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のすべてのオプションを試しましたが成功しませんでした