仮想環境のLinuxでCのプログラムを書いて、実機のLinuxにコピーして実行してみると
「bash: ./a.out: バイナリファイルを実行できません」
と表示されてしまいました。
1ワードが32ビットと64ビット
ちょっと調べてみて、ワード長が違うことにようやく気づきました。
仮想環境のLinuxは1ワード64bitに対して、実機のLinuxは1ワード32bitでした。
OSのビットの違いを普段あまり意識していないので忘れていました。
C言語のような高級言語上では同じ様に書かれていても、ワード長が違う環境で動かすので機械語で見ると違ってくるんですね。
どうりで実機で再コンパイルすれば実行できるわけですね、納得です。
64ビット環境で32ビット用にコンパイル
では、64ビット版Linuxで32ビット用にコンパイルするにはどうすればいいのか、調べて実践してみました。
最終的にはgccのオプションに-m32を追加してコンパイルするだけですが、64ビットの環境では32ビット版のパッケージがインストールされていないそうなので、端末からインストールします。
sudo apt-get install libc6-dev-i386
32bit版のパッケージがインストールできたら、-m32オプションを付けてコンパイルするだけです。
gcc -m32 hello.c -o hello
バイナリファイルが何ビット向けにコンパイルされているかは、fileコマンドから確認できます。
hiyoshimaru@ubuntu: ~/Documents$ file a.out a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=127c7fc18629f51472cf8848c306cfd1707d73cd, not stripped hiyoshimaru@ubuntu: ~/Documents$ file a.out a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=d33d16f6cc88ff2133b8951b25325abfe78b314e, not stripped
32bit用にコンパイルするのもオプションを付けるだけなので手間もかからず簡単ですね。
この記事を読んだ人はこんな記事も読んでいます。
Linuxのgccで32ビット用のバイナリにコンパイルする方法