3

プログラムをソース コード形式ではなく、バイナリとして配布したいと考えています。古い Linux (openSUSE 11.2 with glibc 2.10) と最近の LinuxMint 13 with glibc 2.15 の 2 つのテスト システムがあります。LinuxMint システムで glibc 2.15 を使用してプログラムをコンパイルし、openSUSE システムで glibc 2.10 を使用してバイナリを起動しようとすると、次の 2 つのエラーが発生します。

./a.out: /lib/libc.so.6: version 'GLIBC_2.15' not found (required by ./a.out)
./a.out: /lib/libc.so.6: version 'GLIBC_2.11' not found (required by ./a.out)

ここで私を混乱させているのはこれです:「glibc 2.11が見つかりません」というエラーがここでも発生するのはなぜですか? このプログラムは glibc 2.15 でコンパイルされているため、glibc 2.15 が必要になると思います。プログラムが glibc 2.11 も探しているのはなぜですか? これは、私のプログラムが両方の glibc バージョン、つまり 2.15 と 2.11 で動作するということですか? 少なくとも2.11が必要ですか?それとも、いずれにしても 2.15 が必要ですか?

別の質問: glibc は上位互換性があるが下位互換性はないという仮定は正しいですか? たとえば、glibc 2.10 でコンパイルされたプログラムは、glibc の将来のどのバージョンでも問題なく動作することが保証されていますか? その場合、PATH_MAX のような定数が将来変更された場合はどうなりますか? 現在は 4096 に設定されており、PATH_MAX 定数を使用して realpath() POSIX 関数にバッファーを割り当てています。将来、この定数が 8192 に引き上げられた場合、私のプログラムは 4096 バイトしか割り当てないため、問題が発生する可能性があります。それとも、ここで何かを誤解しましたか?

説明ありがとう!

4

1 に答える 1

7

libc はシンボルのバージョン管理を使用します。かなり高度な魔法ですが、基本的に各シンボルには、それが登場したバージョンに応じたタグが付けられています。セマンティクスが変更された場合、2 つのバージョンがあります。1 つは最初に表示されたバージョンの古いセマンティクス用で、もう 1 つは新しいセマンティクスとそれが表示されたバージョンのバージョンです。ローダーは、プログラムが実際に要求するシンボルについてのみ文句を言います。それらのいくつかはたまたま 2.15 で導入され、いくつかはたまたま 2.11 で導入されました。

これの要点は、glibc の下位互換性を維持することです。多くのパッケージ化されたソフトウェアがあり、すべてが動的にリンクされており、すべてを再コンパイルするには非常に時間がかかるため、これは非常に重要です。ソースが利用できないソフトウェアもたくさんあり、libc の古いビルドは新しいカーネルや新しいものでは動作しない可能性があります。

そうです、glibc は下位互換性があります。前方互換性がない (そしてできない) ため、実行に必要な最も古いバージョンに対してコンパイルするようにしてください。

Ad PATH_MAX: そのような変更が行われた場合、glibc は、新しい値を使用する新しいバージョンのシンボルと、古い値に対してコンパイルされたコードで動作する適切なセーフガードを備えた古いバージョンのシンボルをエクスポートするだけです。それがすべての魔法の要点です。

于 2012-10-01T15:01:56.483 に答える