ほとんど意味のないクロスコンパイラをつくる
スペックの高いPCなどで、非力なCPU搭載マシン用のバイナリをつくるために、用いられるものがクロスコンパイラの通常のあり方。ここでは、その逆を実行した記録。
具体的には
大昔に購入した「Raspberry Pi 1 Model B+」(ARM環境)にて、インテルx64用のクロスコンパイラを作成する。今となっては、相当非力なRasberryPiである。
準備
クロスコンパイラ作成には、crosstool-ngが有名どころ。まずは、よくあるケースである、Linux上でRasberryPi用のクロスコンパイラを作ってみた。
RasberryPi向けクロスコンパイラ
こちらの記事に従って作成。ただし、ターゲットとして「armv6-rpi-linux-gnueabi」を選択。「Raspberry Pi 1 Model B+」向けには、これを使うようだ。
$ ./ct-ng armv6-rpi-linux-gnueabi
なお、ターゲット一覧は、
$ ./ct-ng list-samples
で確認できる。
作成時のログ
[INFO ] Finalizing the toolchain's directory: done in 2.70s (at 31:27)
[INFO ] Build completed at 20210724.092548
[INFO ] (elapsed: 31:26.00)
[INFO ] Finishing installation (may take a few seconds)...
私のPC上のLubuntuでは、このクロスコンパイラ作成に31分かかる。(数値は本題の比較対象。)
ここからが本題(意味のないクロスコンパイラ)
x64用クロスコンパイラを、RaspberryPi上に作成する。先ほど同じ記事に従って進める。ターゲットは「x86_64-unknown-linux-gnu」。
$ ./ct-ng x86_64-unknown-linux-gnu
その他設定。
$ ./ct-ng menuconfig
- Version of Linux:5.4.21(Kernel version:確認するLinux distributionのバージョンに近いものを選択)
- Log level:EXTRAのまま
- Debug facility:gdbを外す
Build。
$ ./ct-ng build
つまづき
数回試したが、ほぼ毎回、
[ALL ] make[1]: Leaving directory '/home/pi/proj/x64/crosstool-ng/.build/x86_64-unknown-linux-gnu/build/build-binutils-host-armv6l-
build_unknown-linux-gnueabihf'
[ERROR]
[ERROR] >>
[ERROR] >> Build failed in step 'Installing binutils for host'
[ERROR] >> called in step '(top-level)'
[ERROR] >>
[ERROR] >> Error happened in: CT_DoExecLog[scripts/functions@376]
[ERROR] >> called from: do_binutils_backend[scripts/build/binutils/binutils.sh@209]
[ERROR] >> called from: do_binutils_for_host[scripts/build/binutils/binutils.sh@70]
[ERROR] >> called from: main[scripts/crosstool-NG.sh@695]
とエラー。たまたまであるが、Raspbianあたりの記事で、スワップのことを見かけたので、スワップサイズを増やしてみた。
スワップサイズ拡大
2GBに設定してみる。
$ cat /etc/dphys-swapfile
CONF_SWAPSIZE=2048
$ sudo service dphys-swapfile start
$ swapon -s
Filename Type Size Used Priority
/var/swap file 1890300 0 -2
実際のサイズは2GBとなっていないが、とりあえず気にしないこととした。
Build再開(&成功&ログ)
スワップサイズ拡大後、Build成功。
[INFO ] Finalizing the toolchain's directory: done in 147.12s (at 4273:39)
[INFO ] Build completed at 20210804.172628
[INFO ] (elapsed: 4273:26.70)
[INFO ] Finishing installation (may take a few seconds)...
4273分!(さらにこの事前準備に3−5時間かかっている。)
PC上でRaspberryPi向けクロスコンパイラを作成した時(31分)と比べて100倍以上の時間を要す。
サイズ情報
$ du -s -m x-tools
315 x-tools
$ du -s -m proj/x64
8621 proj/x64
クロスコンパイラ自体は315MB程度だが、作業領域に8GB以上も必要であった。
実験
対象ソースコード
$ cat a.c
# include <stdio.h>
main() {
printf("test111\n");
}
RaspberryPi上でコンパイルなど
$ uname -a
Linux raspberrypi 5.10.17+ #1421 Thu May 27 13:58:02 BST 2021 armv6l GNU/Linux
$ gcc a.c -o abin
$ x86_64-unknown-linux-gnu-gcc a.c -o xbin
$
$ ls
a.c abin xbin
$ file abin xbin
abin: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=6aaff9cd19a25f22a56a36b5dceb86b58e016bb5, not stripped
xbin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped
x64用のバイナリ「xbin」が生成されている(「abin」はARM用のバイナリ)。RasberryPi上で実行。
$ ./abin
test111
$ ./xbin
-bash: ./xbin: バイナリファイルを実行できません: 実行形式エラー
当然の結果。
Linux(x64)上で実行
scpなどで上記で作成した「xbin」をLinux(x64)上にコピーして実行する。
$ uname -a
Linux Ariana 5.4.0-80-generic #90~18.04.1-Ubuntu SMP Tue Jul 13 19:40:02 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$
$ file xbin
xbin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped
$ ./xbin
test111
成功。
最後に
時間がものすごくかかったが、できることがわかった。