このセクションでは、実行時サポートに関連する問題について説明します。
コンパイラは必要に応じて libgcc を自動的にリンクしますが、何か不具合があった場合に、ライブラリが何をするためのものかを知っておくと便利なことがあります。gcc サポートライブラリ (libgcc) には、libgcc.a と呼ばれるアーカイブライブラリと libgcc_s.so と呼ばれる共有ライブラリの形式の、さまざまなヘルパールーチンがあります。libgcc には、例外をサポートするルーチンと、現在のアーキテクチャーでは直接的な命令がない場合がある整数と浮動小数点演算をサポートするルーチンが含まれています。ライブラリの機能については、gcc ドキュメントのGCC 低レベル実行時ライブラリに関するセクションに記載されています。
gcc コンパイラを使用して作成される実行可能ファイルは、libgcc.a に対してリンクされ、libgcc_s.so に対する動的依存関係はありません。g++ コンパイラを使用して作成される実行可能ファイルは代わりに libgcc_s.so を使用し、これに対する動的依存関係があります。
Oracle Developer Studio の C コンパイラによって生成されたコードは libgcc に対する依存関係がありません。
Oracle Developer Studio C++ コンパイラによって生成されたコードは Sun モード (–compat=5) でビルドされる場合は libgcc に依存しませんが、GNU 互換モード (–compat=g–std=c++03、–std=c++11、または –std=c++14) でビルドされる場合はそのような依存関係を持ちます。
Oracle Linux の場合、libc_supp.a という名前の類似のライブラリが Oracle Developer Studio に含まれています。
Oracle Developer Studio C++ コンパイラによってコンパイルされたソースファイルは、正しい実行時ライブラリ、CRT ファイル、およびリンカーオプションが使用されるようにするために、Oracle Developer Studio C++ コンパイラを使用してリンクされる必要があります。g++ オブジェクトファイルは g++ でリンクする必要があります。互換性のない多くの実装の詳細がオブジェクトファイル内で使用されているため、Oracle Developer Studio C++ コンパイラおよび g++ コンパイラからのオブジェクトファイルを同じ実行可能ファイルまたは共有ライブラリに混在させることはサポートされていません。
Oracle Developer Studio C++ によって GNU 互換モード (オプション –compat=g、–std=c++03、–std=c++11、または –std=c++14 を使用して) で作成された共有ライブラリは、g++ コンパイラによって作成された共有ライブラリと混在させて、いずれかのコンパイラによって作成された主プログラムにリンクさせることができますが、これらは同じバージョンの g++ ABI を使用する必要があります。
GNU 互換モードで動作するとき、Oracle Developer Studio C++ コンパイラは、ライブラリインタフェース、名前符号化、および標準ライブラリオブジェクトのバイナリレイアウトの領域で、g++ コードとバイナリレベルで互換性があります。ただし、実装のほかの多くの基本的な側面では、別のメカニズムを使用します。外部インライン関数、テンプレートインスタンス、RTTI レコード、および例外範囲情報は、COMDAT を使用して異なる方法で実装されます。例外範囲情報は Studio 固有の方法でフォーマットされます。このため、Oracle Developer Studio C++ でコンパイルされたオブジェクトファイルやアーカイブライブラリと、g++ でコンパイルされたオブジェクトファイルやアーカイブライブラリの間で実行できる混在の量が制限されます。
GNU C++ ABI のバージョン 4.x と 5.x の間の互換性のない変更により、g++ でコンパイルされた実行可能ファイルとライブラリが正しく動作するには、これらが 1 つの ABI を一貫して使用する必要があります。5.x GNU C++ ライブラリは両方の ABI をサポートしますが、コンパイラ (GCC または Oracle Developer Studio) は一度に 1 つの ABI のみを生成できます。g++ コンパイラは、デフォルトで 5.x ABI を指定します。4.x ABI を選択するには、–D_GLIBCXX_USE_CXX11_ABI=0 を指定してコンパイルします。
Oracle Developer Studio 12.5 C++ コンパイラは 4.x ABI のみを実装します。共有ライブラリと実行可能ファイルを混在させるには、上記のオプションを使用して g++ 部分をビルドします。この問題についての g++ のドキュメントは、https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html にあります。
技術的に、4.x ライブラリまたは実行可能ファイルが 5.x ライブラリまたは実行可能ファイルと一緒に使用されるのを止める方法はありませんが、これらは 2 つの ABI の異なるライブラリクラスを使用して相互に呼び出すことはできません。これらのクラスの一部は (文字列クラスのように) 一般的によく使用されるため、2 つの ABI を混在させてもたいした効果は得られません。
C++ の main 関数にはいくつかの追加メカニズムがあります。いずれのコンパイラを使用してオブジェクトファイルをコンパイルする場合であっても、実行可能ファイルをリンクするために main も使用するべきです。コンパイラドライバによって使用される crt オブジェクトファイルは、オブジェクトファイル main に組み込まれたメカニズムと一致します。
GNU モードでコードをコンパイルするとき、Oracle Developer Studio C++ コンパイラは GNU C++ ライブラリを使用しますが、さらに RTTI のサポート機能、例外、およびその他の言語機能を提供するために、libCrunG3.so と呼ばれる追加ライブラリをリンクする必要があります。このライブラリは、Sun モード (–compat=5) で使用される libCrun.so ライブラリに対応します。
Oracle Developer Studio 12.5 C++ コンパイラ (GNU 互換モード) は 5.1.x バージョンの GNU C++ ライブラリを使用します。異なるバージョンの GNU C++ ライブラリを使用してビルドされた共有ライブラリおよびアプリケーションを混在させることができますが、メインアプリケーションをビルドおよびリンクするために使用されるコンパイラは、いずれかの共有ライブラリを作成するために使用されるコンパイラと同じかそれより新しいバージョンである必要があります。いずれかの共有ライブラリが Oracle Developer Studio C++ でビルドされた場合、メインアプリケーションは、Oracle Developer Studio C++ コンパイラまたは 5.1.x GNU C++ ライブラリをサポートする g++ コンパイラのいずれかを使用してビルドされる必要があります。
C++ 実行時ライブラリはさまざまな場所にあります。
次の Sun モード (–compat=5) C++ ライブラリは、Oracle Solaris では /usr/lib にありますが、Oracle Linux にはありません。
libCstd.so
libCrun.so
libdemangle.so
libiostream.so
libstdcxx.so
次の GNU モード C++ ライブラリは、Oracle Solaris では /usr/lib にありますが、Oracle Linux にはありません。
libCrunG3.so (ただし、Oracle Solaris パッケージ SUNWlibC のパッチが必要になることがあります)
libdemangle.so
ほかのすべての C++ 実行時ライブラリはコンパイラのインストールディレクトリにあります。
Oracle Developer Studio C++ コンパイラは、Oracle Developer Studio にバンドルされているすべての共有ライブラリに対してリンクするとき、通常は、実行時にライブラリを見つけるために必要な RPATH 設定を実行可能ファイルに追加します。この動作を防ぐことは可能で、–xnorunpath オプションを追加して適切な –R オプションを追加することで、RPATH 設定を自分で構成できます。
ソースコードを –xopenmp でコンパイルすると、システムライブラリへの実行時依存関係が生成され、これは Oracle Developer Studio コンパイラの場合は libmtsk ライブラリです。Oracle Solaris では、このライブラリは /usr/lib にあります。Oracle Linux では、このライブラリはコンパイラのインストールディレクトリにあります。スレッド管理はプロセス全体の動作であるため、1 つのプログラム内で使用する OpenMP 実装は 1 つのみとしてください。共有ライブラリが OpenMP を使用する場合、メインアプリケーションは異なる OpenMP 実装を使用できません。OpenMP の Oracle Developer Studio 実装は、OpenMP の GCC 実装との互換性がありません。
不可分機能は、オペレーティングシステムからの実行時サポートを必要とする C 2011 および C++ 2011 規格の新しい言語機能です。Oracle Developer Studio コンパイラは、一部のバージョンの GCC 実行時ライブラリと互換性のある事前バンドル済み実行時ライブラリによってこの機能をサポートするため (Oracle Developer Studio 12.5: C++ ユーザーズガイド の バンドルされている不可分ライブラリを参照)、–xatomic オプションを使用して、プログラムとライブラリをリンクするときに使用する実行時ライブラリを選択できます。
GCC コンパイラおよび Oracle Developer Studio コンパイラは、OS ABI (Oracle Solaris または Oracle Linux) に準拠する方法でスレッドローカルデータ (__thread declarations) を実装するため、Oracle Developer Studio コンパイラおよび GCC コンパイラによってコンパイルされたコードの機能には互換性があります。スレッドローカルデータについての Oracle Solaris ABI の詳細については、Oracle Solaris 11.3 リンカーとライブラリガイドを参照してください。