そのブログ投稿はかなり不正確です。
私の知る限り、C ++ ABIの変更は、GCCのすべてのメジャーリリース(つまり、異なる第1または第2バージョン番号コンポーネントを持つリリース)で導入されています。
違います。GCC3.4以降に導入された唯一のC++ABIの変更は下位互換性があり、C++ABIはほぼ9年間安定しています。
さらに悪いことに、ほとんどの主要なLinuxディストリビューションはGCCスナップショットを使用したり、GCCバージョンにパッチを適用したりするため、バイナリを配布するときに処理している可能性のあるGCCバージョンを正確に知ることは事実上不可能です。
ディストリビューションのパッチが適用されたバージョンのGCCの違いはわずかであり、ABIは変更されません。たとえば、Fedoraの4.6.3 20120306(Red Hat 4.6.3-2)は、アップストリームFSF4.6.xリリースとほぼ確実に4.6と互換性があります。 x他のディストリビューションから。
GNU / Linuxでは、GCCのランタイムライブラリはELFシンボルバージョン管理を使用するため、オブジェクトやライブラリに必要なシンボルバージョンを簡単に確認できます。libstdc++.so
これらのシンボルを提供するがあれば、それが機能します。パッチが少し異なるバージョンであるかどうかは関係ありません。あなたのディストロの別のバージョンから。
ただし、これが機能する場合は、C ++コード(またはC ++ランタイムサポートを使用するコード)を動的にリンクすることはできません。
これも真実ではありません。
とは言うものの、静的にリンクすることlibstdc++.a
はあなたにとって1つのオプションです。
ライブラリを(を使用して)動的にロードした場合に機能しない理由は、ライブラリdlopen
を(静的に)リンクしたときに、依存するlibstdc ++シンボルがアプリケーションで必要とされなかった可能性があるため、これらのシンボルは実行可能ファイルに存在しません。これは、共有ライブラリを動的にリンクすることで解決できますlibstdc++.so
(これは、共有ライブラリに依存している場合はとにかく正しいことです)。ELFシンボルの挿入は、実行可能ファイルに存在するシンボルが共有ライブラリによって使用されることを意味しますが、他のシンボルは使用されません。実行可能ファイルに存在するものはlibstdc++.so
、リンク先のいずれかにあります。アプリケーションが使用しない場合dlopen
は、それを気にする必要はありません。
別のオプション(および私が好むオプション)はlibstdc++.so
、アプリケーションと一緒に新しいものをデプロイし、デフォルトのシステムの前にそれが見つかるようにすることです。これは、実行時に環境変数をlibstdc++.so
使用して、動的リンカーに適切な場所を探すように強制することで実行できます。$LD_LIBRARY_PATH
時間、またはRPATH
リンク時に実行可能ファイルにを設定することによって。RPATH
アプリケーションが機能するために正しく設定された環境に依存しないため、私は使用することを好みます。アプリケーションをとリンクすると'-Wl,-rpath,$ORIGIN'
(シェルが拡張しようとするのを防ぐために一重引用符に注意してください$ORIGIN
)、実行可能ファイルには、実行可能ファイル自体と同じディレクトリで共有ライブラリを探すようにダイナミックリンカに指示するRPATH
があります。$ORIGIN
あなたが新しいものを置くならlibstdc++.so
実行可能ファイルと同じディレクトリにあり、実行時に検出され、問題が解決されます。(別のオプションは、実行可能ファイル/some/path/bin/
と新しいlibstdc ++。soを入れて、実行可能ファイルまたは他の固定位置/some/path/lib/
にリンクし'-Wl,-rpath,$ORIGIN/../lib'
、RPATHをに相対的に設定することです$ORIGIN
)