意味のないクロスコンパイラ

# ほとんど意味のないクロスコンパイラをつくる

スペックの高いPCなどで、非力なCPU搭載マシン用のバイナリをつくるために、用いられるものがクロスコンパイラの通常のあり方。ここでは、その逆を実行した記録。

## 具体的には
大昔に購入した「Raspberry Pi 1 Model B+」（ARM環境）にて、インテルx64用のクロスコンパイラを作成する。今となっては、相当非力なRasberryPiである。

## 準備
クロスコンパイラ作成には、[crosstool-ng](https://crosstool-ng.github.io)が有名どころ。まずは、よくあるケースである、Linux上でRasberryPi用のクロスコンパイラを作ってみた。

### RasberryPi向けクロスコンパイラ
[こちらの記事](https://qiita.com/nanbuwks/items/e19887e6a66262d325ca)に従って作成。ただし、ターゲットとして「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上に作成する。[先ほど同じ記事](https://qiita.com/nanbuwks/items/e19887e6a66262d325ca)に従って進める。ターゲットは「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
```

成功。

## 最後に
時間がものすごくかかったが、できることがわかった。