お仕事でよくラズパイを使うことがあるのですが、開発用のPCに比べるとCPUの性能はそこまで高くないので、 ネイティブ環境でソフトウェアのビルドをすると結構な時間がかかっちゃいます。 仕事ではかなりまえからdockerコンテナでのクロスビルド環境を整えてたのですが、せっかくなので共有しておこうと思います。
いくつかオープンソースのソフトウェアをビルドするスクリプトも含めてます。
# サマリ
このリポジトリのDockerfileをビルドすれば、すぐさまクロス環境ができあがります👌
できること
- ラズパイ用のバイナリをビルドできる
gccを直接実行したり、cmakeやautotools系のビルドシステムでもクロスビルドできます - ラズパイのシステムをqemu(仮想環境)で実行できる
ビルドしたバイナリをそのまま仮想環境で実行できますし、仮想環境内でapt実行してラズパイ用のソフトウェアをインストールしたりできます。 - いくつかのサンプルプログラムやオープンソースソフトウェアをお試しビルドできる
これはクロスビルドを試すために用意したものです。 Python, libmbedなど
補足情報
- 生成するバイナリはRaspberry Pi OS (bullseye)の32bit用のみです。
私がほかの環境を使うことがほぼないため、その他のクロス環境は用意できていません - クロスコンパイラは
ubuntu:22.04(x86_64)コンテナ上に構築されています。 そのためx86_64環境でdockerを実行してください。
# 使い方
イメージの作成
リポジトリをクローンしてきて、docker compose buildしましょう。$ git clone https://xxxx $ cd raspi-cross-toolchain-container $ docker compose buildコンテナ実行
いつも通り、compose up -dとcompose execです。$ docker compose up -d $ docker compose exec raspi-cross /bin/bash root@.....:/opt#コンテナを停止するときは、コンテナのシェルを抜けて、
docker compose downでOKです。サンプルプログラムのビルドと実行
コンテナに入れば、helloworldのサンプルプログラムが用意されています。 makeすればラズパイ用の実行バイナリが生成されます。$ docker compose exec raspi-cross /bin/bash root@.....:/opt# cd build-test/sample_hello/ root@.....:/opt/build-test/sample_hello# make : root@.....:/opt/build-test/sample_hello# ls Makefile hello hello.c hello.o root@.....:/opt/build-test/sample_hello# file hello hello: 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, not strippedあとは生成された実行ファイルを、rsync等でラズパイにコピーすればそこの環境で実行できるはずです。
# CMakeや./configureなどのautotoolsを使ったビルドシステムの場合
多くのソフトウェアはいろいろなライブラリに依存していると思います。
そういうソフトウェアをビルドするときは、ラズパイ上のライブラリやヘッダファイルを参照できるようにする必要があるのですが、
このDockerイメージではラズパイのルートファイルシステムを丸ごと/sysrootに配置しています。(ビルド時にダウンロードして展開)
Makefileだけでビルドするようなソフトウェアや、直接gccやg++を叩くような場合は、上記のmakeファイル内のオプションを参考にすればいいと思います。
CMakeやautotoolsの場合はちょっと設定が必要です。
# CMake
ツールチェインファイルを用意しています。
cmakeのオプションに-DCMAKE_TOOLCHAIN_FILE=/opt/cross-env.cmakeを追加してビルドしてください。
例
cd some_project
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=/opt/cross-env.cmake
make
make install DESTDIR=/opt/sysroot
./build-test/build-mbed.shでは、実際にCMakeをビルドシステムとして使っているオープンソースのlibmbedをビルドする手順が記載されていますので参考になるかもしれません。
# autotools
こちらも環境変数を設定するスクリプト/opt/cross-env.shを用意しています。
自動で読み込まれるようにコンテナ内の.bashrcに追記していますので、あとは環境変数を使うだけです。
例
cd some_project
./configure $CONFIGURE_OPTIONS
make
make install DESTDIR=/opt/sysroot
./build-test/build-cpython.shでは、実際にautotoolsをビルドシステムとして使っているcpythonをビルドする手順が記載されていますので参考になるかもしれません。
# ほかにも
結構いろいろなことができます。いずれまた記事を書こうと思います。
- sysroot内でapt実行
- qemu内で
gdbを使ってデバッグ
# 参考サイト
- raspberry-pi-cross-compilers (opens new window)
ラズパイ用のクロスビルドツールチェインを公開しているプロジェクトです。
多分、ラズパイの公式ではないのですが、詳細までは把握してないです。 - Raspberry Pi OSのルートファイルシステム (opens new window) Docker内に配置するsysrootはRaspberry Pi公式のこちらからダウンロードしています。 新しいイメージがリリースされたら適時パスを変えたほうがいいですね