これはちょっと楽しい試練ですが、古いLinuxシステムではプログラムをコンパイルするのが難しくありませんか?c/C++アプリケーションを従来のlinuxカーネルバージョンに移植する方法
私はすべてのLinuxを実行しているいくつかの古代のシステムにアクセスできますし、負荷の下でどのように動作するかは興味深いかもしれません。例として、Eigenを使用して線形代数を実行したいとします。これは素晴らしいヘッダー専用ライブラリです。ターゲットシステムでコンパイルする機会はありますか?
[email protected]:~ $ uname -a
Linux local 2.2.16 #5 Sat Jul 8 20:36:25 MEST 2000 i586 unknown
[email protected]:~ $ gcc --version
egcs-2.91.66
多分、今のシステムでそれをコンパイルしましょう。以下は主に失敗した試みです。これ以上のアイデアは大歓迎です。
-m32 -march=i386 -static
と-m32 -march=i386
[email protected]:~ $ ./a.out BUG IN DYNAMIC LINKER ld.so: dynamic-link.h: 53: elf_get_dynamic_info: Assertion `! "bad dynamic tag"' failed!
コンパイルとコンパイル:すべてのかなり最近のバージョンのカーネルで動作しますが、彼らはよく知られているエラーメッセージ
と少し古い場合失敗し[email protected]:~ $ ./a.out FATAL: kernel too old Segmentation fault
この
glibc
エラーです。これは、それがサポートする最小のカーネルバージョンを持っています。私のシステム上のカーネル2.6.4:$ file a.out a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.4, not stripped
コンパイル
glibc
私自身は、可能な最も古いカーネルをサポートしました。 This post最も重要なのは、32ビットは(残念ながら-march=i386
ベイルを構築-m32 -march=i486
用コンパイラフラグの使用を強制することです、より詳細にそれを説明したが、本質的にそれは--with-cpu
と--host
オプションは何をすればわからないこのwget ftp://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.bz2 tar -xjf glibc-2.14.tar.bz2 cd glibc-2.14 mkdir build; cd build ../configure --prefix=/usr/local/glibc_32 \ --enable-kernel=2.0.0 \ --with-cpu=i486 --host=i486-linux-gnu \ CC="gcc -m32 -march=i486" CXX="g++ -m32 -march=i486" make -j 4 make intall
のようになりますしばらくするとエラーが出る)と
--enable-kernel=2.0.0
を使用して、古いカーネルと互換性のあるライブラリにします。 Incidentially、configure
時に私はまだ許容可能である警告WARNING: minimum kernel version reset to 2.0.10
を持って、私は考えます。異なるカーネルで変更されるもののリストについては、
./sysdeps/unix/sysv/linux/kernel-features.h
を参照してください。新しくコンパイルglibc
ライブラリに対するオクラホマので、聞かせてのリンク、少し汚いが、ここでは行く:
私たちは、静的コンパイルをやっているlink orderが重要であるともいくつかの試行錯誤が必要になる場合がありますので$ export LIBC_PATH=/usr/local/glibc_32 $ export LIBC_FLAGS=-nostdlib -L${LIBC_PATH} \ ${LIBC_PATH}/crt1.o ${LIBC_PATH}/crti.o \ -lm -lc -lgcc -lgcc_eh -lstdc++ -lc \ ${LIBC_PATH}/crtn.o $ g++ -m32 -static prog.o ${LIBC_FLAGS} -o prog
しかし、基本的に我々はオプション
gcc
がリンカに与えるものから学ぶ:私は男のための必要はありませんでしたcrtbeginT.o
とcrtend.o
もリンクされて、それに対して$ g++ -m32 -static -Wl,-v file.o
注意を、私はそれらを放棄した。出力には、ライブラリ間の依存関係を示す
--start-group -lgcc -lgcc_eh -lc --end-group
のような行も含まれます(this postを参照)。私はちょうど-lc
をgcc
コマンドラインで2回言いました。これも相互依存関係を解決します。右、私は今、古いシステム上でそれを試してみてください、と思ったハードワークが報われたと今、私はブリリアント
$ file ./prog ./prog: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.0.10, not stripped
を得る:
[email protected]:~ $ ./prog set_thread_area failed when setting up thread-local storage Segmentation fault
これ、再び、
glibc
エラーですメッセージは./nptl/sysdeps/i386/tls.h
です。私は細部を理解してあきらめない。新しいシステム
g++ -c -m32 -march=i386
でコンパイルし、古いものをリンクします。うわー、それは実際にCや単純なC++プログラム(C++オブジェクトを使用しない)で動作します。これはあまりにも驚くべきことではありませんから、libc
はprintf
(そして多分いくつかの数学)ですが、そのインターフェイスは変更されていませんが、libstdc++
へのインターフェイスは非常に異なっています。古いLinuxシステムとgccバージョン2.95の仮想ボックスをセットアップします。 gccバージョン4.x.xをコンパイルしてください...残念ですが、その時点ではあまりにも怠惰です...
???
コンパイル?ヘッダーのみのテンプレートライブラリですか? –
このテンプレートライブラリを使用するテストプログラムをコンパイルします。これは、古いgccバージョンのためにターゲットマシンでコンパイルされないコードの単なる例です。 – user1059432
ああ、大丈夫です。申し訳ありませんが、誤解しました。 –