概要
これらの記事の続きです。
簡単な共有ライブラリと共有ライブラリを呼び出すプログラムを(Windows10 の VirtualBox の)Debian 上でビルドして、Raspberry Pi で動かしてみます。
環境
ホスト: Debian 10.6.0 < Virtual Box 6.1 < WIndows10
ターゲット: Raspberry Pi 3 Model A+
前回の Raspberry Pi Zero から Raspberry Pi 3 に変わってます。
なぜかというと Raspberry Pi Zero の ARM v6系 CPU向けのクロスコンパイルがうまく動かなかったからです。
Raspberry Pi 3 の ARM v8系 CPU向けの方はあっさり通りました。
コンパイラのバグのような気がするけど、何が悪いかご存じの方がいらっしゃいましたら教えてください。
今回のプログラム
全然中身はないですが、お試し用のプログラムはこんな感じにしました。
#ifndef TEST_SO_LIB_H
#define TEST_SO_LIB_H
void print_hoge (int num);
#endif
#include <stdio.h>
#include "test_so_lib.h"
void
print_hoge (int num)
{
int i;
for (i = 0; i < num; i++) {
printf("hogehoge\n");
}
}
#include "test_so_lib.h"
int
main (void)
{
print_hoge(5);
return 0;
}
これを普通にビルドして動かすとこんな感じ。
$ 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 向けの方の話を手短に、、
ビルド環境は 前回の記事 の通りです。その環境でこんな感じ、、
$ 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 にコピーして、実行してみると、、
$ ./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向けのクロスコンパイラを使います。
前回の記事 で armel
って書いてあるところを armhf
に修正してこんな感じ。
armhfクロスコンパイラのインストール
$ sudo apt install crossbuild-essential-armhf
アーキテクチャの追加
$ sudo dpkg --add-architecture armhf
$ sudo nano /etc/apt/sources.list
deb [arch=armel,armhf] http://ftp.jp.debian.org/debian buster main
今回は armel は使いませんが両方使いたいなら書き方はこんな感じでいいはず。
$ sudo apt update
$ sudo apt install libusb-dev:armhf
$ sudo apt install libjpeg-dev:armhf
ちなみに、今回は自作の共有ライブラリ以外は使わないので、crossbuild-essential-armhf
のインストールだけすれば大丈夫です。
(ここまで書いたのは自分用のメモ)
ビルド
-march
で指定するアーキテクチャを armv8-a
にしています。
(armv8
というのは指定できないらしい)
$ 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 にコピーして、実行。
$ ./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
自体がちょっと怪しいのかなと思ったりしている。
もしかすると何かビルド時にオプションが必要とか環境が足りてないとかあるのかもしれないけど、よく分からなかったので、もし分かる方がいらっしゃったら教えてください。