現在のubuntu(12.04)でプログラムをコンパイルする必要があります。このプログラムはCentOSと古いKernel(2.6.18)を使用してクラスタ上で実行する必要があります。残念ながら、私はクラスタ上で直接コンパイルできません。変更を加えずにプログラムをコンパイルしてコピーしただけでは、「カーネルが古すぎます」というエラーメッセージが表示されます。古いlibcでコンパイルする(バージョン `GLIBC_2.14 'が見つかりません)
私がそれを理解した理由は、これはカーネルバージョンではなく、コンパイルに使用されたlibcのバージョンです。だから、私は自分のプログラムをコンパイルして、クラスターからlibcを動的にリンクし、他のすべてを静的にリンクしようとしました。
研究
は、SOに、すでにこのことについて多くの質問がありますが、答えのどれも本当に私のために働いていません。そこでここではそのトピックに関する私の研究です:
- This questionが
- This questionは似ていますが、より専門であるカーネルあまりにも古いメッセージの理由を説明し、
- 提案されたように、静的にリンク一切答えを持っていないがhere動作しませんでしたlibcがクラスタ上で古すぎるためです。 1つの答えは、古いlibcを使ってビルドすることにも言及していますが、これを行う方法は説明していません。
- One wayは、古いOSを実行しているVMでコンパイルすることです。これは機能しましたが、複雑です。また、私はコピー
現在の状態をyou should not link libc statically
-rpath
と異なるlibcのバージョン用にコンパイルするが、これは私のために働く(下記参照)しなかったことを読んでクラスタからディレクトリに続くファイル/path/to/copied/libs
- libc-2.5.so
- libgcc_s.so.1が
- のlibstdC++。so.6
とコンパイルされたバイナリ上で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)
あるオプション-nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s
でコンパイルしています正しいパスを使用しているため、エラーによって多少混乱します。クラスタからのlibc)、まだglibcのバージョンがなくなっていると不平を言っています。クラスタ上でlddを実行すると、not a dynamic executable
が返され、バイナリを実行すると上記の2つのエラーが発生します。また、他のライブラリが含まれているようです(linux-vdso.so.1、ld-linux-x86-64.so.2、libm.so.6)。それらの古いバージョンも使うべきですか?
だから今、私は2つの主要な質問があります。
- はここでも正しいアプローチこれですか?
- 「はい」の場合:古いlibcを正しくリンクするにはどうすればよいですか?