Debian上でRaspberry Pi Zero向けクロスコンパイル ～自作の共有ライブラリを作ってみる

# 概要

これらの記事の続きです。

* [Ubuntu上でRaspberry Pi Zero向けクロスコンパイル事始め](https://qiita.com/manontroppo1974/items/a6bcef67285c10edff77)
* [Debian上でRaspberry Pi Zero向けクロスコンパイル ～共有ライブラリを使ってみる](https://qiita.com/manontroppo1974/items/4805047ccc186d729b3b)

簡単な共有ライブラリと共有ライブラリを呼び出すプログラムを（Windows10 の VirtualBox の）Debian 上でビルドして、Raspberry Pi で動かしてみます。

# 環境

ホスト： Debian 10.6.0 < Virtual Box 6.1 < WIndows10
ターゲット： Raspberry Pi 3 Model A+

[前回](https://qiita.com/manontroppo1974/items/4805047ccc186d729b3b)の Raspberry Pi Zero から Raspberry Pi 3 に変わってます。
なぜかというと Raspberry Pi Zero の ARM v6系 CPU向けのクロスコンパイルがうまく動かなかったからです。

Raspberry Pi 3 の ARM v8系 CPU向けの方はあっさり通りました。

コンパイラのバグのような気がするけど、何が悪いかご存じの方がいらっしゃいましたら教えてください。

# 今回のプログラム

全然中身はないですが、お試し用のプログラムはこんな感じにしました。

```C:test_so_lib.h
#ifndef TEST_SO_LIB_H
#define TEST_SO_LIB_H

void print_hoge (int num);

#endif
```

```C:test_so_lib.c
#include <stdio.h>
#include "test_so_lib.h"

void
print_hoge (int num)
{
  int i;
  for (i = 0; i < num; i++) {
    printf("hogehoge\n");
  }
}
```

```C:main.c
#include "test_so_lib.h"

int
main (void)
{
  print_hoge(5);
  return 0;
}
```

これを普通にビルドして動かすとこんな感じ。

```shell
$ gcc -shared test_so_lib.c -o libtestso.so
$ gcc test_so_main.c -o test_so_main -I./ -L./ -Wl,-rpath=./ -ltestso
$ ./test_so_main
hogehoge
hogehoge
hogehoge
hogehoge
hogehoge
```

# クロスコンパイルしてみる
## Raspberry Pi Zero 向け

ダメだった Raspberry Pi Zero 向けの方の話を手短に、、
ビルド環境は [前回の記事](https://qiita.com/manontroppo1974/items/4805047ccc186d729b3b) の通りです。その環境でこんな感じ、、

```shell:Debian
$ arm-linux-gnueabi-gcc -march=armv6 -shared test_so_lib.c -o libtestso_armv6.so
$ arm-linux-gnueabi-gcc -march=armv6 test_so_main.c -o test_so_main_armv6 -I./ -L./ -Wl,-rpath=./ -ltestso_armv6
```

ビルドでできた test_so_main_armv6, libtestso_armv6.so を Raspberry Pi Zero にコピーして、実行してみると、、

```shell:RaspberryPiZero
$ ./test_so_main_armv6
./test_so_main_armv6: error while loading shared libraries: libtestso_armv6.so: cannot open shared object file: No such file or directory
```

なんかエラーが出ました。共有ライブラリ libtestso_armv6.so が見つからないっぽい。原因がよく分かりません。

## Raspberry Pi 3 向け
### ビルド環境

Raspberry Pi 3 の ARM v8系のビルドには armhf向けのクロスコンパイラを使います。
[前回の記事](https://qiita.com/manontroppo1974/items/4805047ccc186d729b3b) で `armel` って書いてあるところを `armhf` に修正してこんな感じ。

armhfクロスコンパイラのインストール

```shell
$ sudo apt install crossbuild-essential-armhf
```

アーキテクチャの追加

```shell
$ sudo dpkg --add-architecture armhf
$ sudo nano /etc/apt/sources.list
```

```shell:/etc/apt/sources.list
deb [arch=armel,armhf] http://ftp.jp.debian.org/debian buster main
```

今回は armel は使いませんが両方使いたいなら書き方はこんな感じでいいはず。

```shell
$ sudo apt update
$ sudo apt install libusb-dev:armhf
$ sudo apt install libjpeg-dev:armhf
```

ちなみに、今回は自作の共有ライブラリ以外は使わないので、`crossbuild-essential-armhf` のインストールだけすれば大丈夫です。
（ここまで書いたのは自分用のメモ）

# ビルド

`-march` で指定するアーキテクチャを `armv8-a` にしています。
（`armv8` というのは指定できないらしい） 

```shell:Debian
$ arm-linux-gnueabihf-gcc -march=armv8-a -shared test_so_lib.c -o libtestso_armv8a.so
$ arm-linux-gnueabihf-gcc -march=armv8-a test_so_main.c -o test_so_main_armv8a -I./ -L./ -Wl,-rpath=./ -ltestso_armv8a
```

ビルドでできた test_so_main_armv8a, libtestso_armv8a.so を Raspberry Pi 3 にコピーして、実行。

```shell:RaspberryPi3
$ ./test_so_main_armv8a
hogehoge
hogehoge
hogehoge
hogehoge
hogehoge
```

あっさり動いた。

# まとめ

`arm-linux-gnueabi-gcc` で `armv6` 向けにビルドして Raspberry Pi Zero で動かなくてしばらく悩んでたのだけど、`arm-linux-gnueabihf-gcc` で `armv8-a` 向けに同じ手順でビルドしてあっさり動いてるところをみると `arm-linux-gnueabi-gcc` 自体がちょっと怪しいのかなと思ったりしている。

もしかすると何かビルド時にオプションが必要とか環境が足りてないとかあるのかもしれないけど、よく分からなかったので、もし分かる方がいらっしゃったら教えてください。