現在のubuntu(12.04)でプログラムをコンパイルする必要があります。このプログラムは、古いカーネル (2.6.18) を使用する CentOS を使用するクラスターで実行する必要があります。残念ながら、クラスターで直接コンパイルすることはできません。プログラムを変更せずにコンパイルしてコピーすると、「カーネルが古すぎます」というエラーメッセージが表示されます。
私が理解した方法では、これの理由はカーネルのバージョンではなく、コンパイルに使用された libc のバージョンです。そこで、クラスターからlibcを動的にリンクし、他のすべてを静的にリンクするプログラムをコンパイルしようとしました。
リサーチ
これについてはすでに多くの質問がありますが、答えはどれも実際にはうまくいきませんでした。だからここにそのトピックに関する私の研究があります:
- この質問は、カーネルが古すぎるというメッセージの理由を説明しています
- この質問は似ていますが、より専門的であり、回答がありません
- クラスターで libc が古すぎるため、ここで提案されている静的リンクは機能しませんでした。1 つの回答では、古い libc を使用してビルドすることについても言及されていますが、これを行う方法については説明していません。
- 1 つの方法は、古い OS を実行している VM でコンパイルすることです。これは機能しましたが、複雑です。また、 libc を静的にリンクしてはならないことも読みました
- どうやら、オプションを使用して別の libc バージョン用にコンパイルすることは可能です
-rpath
が、これは私にとってはうまくいきませんでした (以下を参照)。
現在の状態
次のファイルをクラスターからディレクトリにコピーしました/path/to/copied/libs
- libc-2.5.so
- libgcc_s.so.1
- libstdc++.so.6
オプションでコンパイルしています-nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s
コンパイルされたバイナリに対する ldd の出力は次のとおりです。
mybin: /path/to/copied/libs/libc.so.6: version `GLIBC_2.14' not found (required by mybin)
mybin: /path/to/copied/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mybin)
linux-vdso.so.1 => (0x00007ffff36bb000)
libc.so.6 => /path/to/copied/libs/libc.so.6 (0x00007fbe3789a000)
libstdc++.so.6 => /path/to/copied/libs/libstdc++.so.6 (0x00007fbe37599000)
libgcc_s.so.1 => /path/to/copied/libs/libgcc_s.so.1 (0x00007fbe3738b000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbe37bf3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbe37071000)
正しいパス (つまり、クラスターからの libc) を使用しているにもかかわらず、まだ glibc のバージョンが見つからないというエラーが表示されるため、このエラーに多少混乱しています。クラスターで ldd を実行すると返さnot a dynamic executable
れ、バイナリを実行すると、上記と同じ 2 つのエラーが発生します。また、他のライブラリが含まれているようです (linux-vdso.so.1、ld-linux-x86-64.so.2、および libm.so.6)。それらにも古いバージョンを使用する必要がありますか?
だから今、私は2つの主な質問があります:
- これはここでも正しいアプローチですか?
- はいの場合: 古い libc を正しくリンクするにはどうすればよいですか?