そのブログ投稿はかなり不正確です。
私の知る限り、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)は、アップストリームのFSF 4.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
)
-static-libstdc++
オプションに意味がないことを意味する場合は、使用するだけです-static