4年ほど前にRaspberry Pi向けのC/C++クロスコンパイル環境を整えたのだけど、当時と今では環境構築の方法が異なるようだ。
ということで、現時点(2022年8月)での「Linux上でRaspberry Pi向けクロスコンパイル環境を構築する方法」についてメモを残しておく。
古い方法:GitHubに公開されているツールチェーンを使う
4年前の時は、https://github.com/raspberrypi/toolsで公開されていたツールチェーンをUbuntuにcloneして使った。
git clone https://github.com/raspberrypi/tools
最近このリポジトリを見たところ「このツールチェーンはもう古いから、別のを使え」との一文が……。
最近の方法:ホスト環境の「公式リポジトリのクロスコンパイル用ツールチェーン」を使う(※ディストロの種類やバージョンに注意)
前項のリポジトリには、代替として「Ubuntuなどの公式リポジトリのクロスコンパイル用ツールチェーン」を使う案が提示されている。
# Raspberry Pi OS 32bit版向けのツールチェーンを入れる場合: sudo apt-get install gcc-arm-linux-gnueabihf # Raspberry Pi OS 64bit版向けのツールチェーンを入れる場合: sudo apt-get install gcc-aarch64-linux-gnu
ただしこの方法には「明示されていない罠」が存在する。少なくとも、ターゲット環境がRaspberry Pi OS (bullseye) であるならば、ホスト環境はUbuntu 20.04ないしDebian 11である必要がある。
例えばUbuntu 22.04にて上記の方法でクロスコンパイル環境を整えた場合、深く考えずに実行ファイルをクロスコンパイルしたならば、十中八九Raspberry Pi OS上で動作しない。
理由はglibcのバージョン違いにある。
Debian 11 (bullseye) のlibc6やlibc6-amd64のバージョンから推測できるが、Raspberry Pi OS (bullseye) のglibcのバージョンは2.31である。
一方でUbuntu 22.04の公式リポジトリからARM向けクロスコンパイル用ツールチェーンをインストールした場合、クロスコンパイル用のglibcは、32bit向けも64bit向けも、バージョンは2.35である。
普通にビルドするとglibcは動的リンクされるので、Ubuntu 22.04でクロスコンパイルすると「実行時にglibc 2.35が動的リンクされる」想定の実行ファイルが生成される。
このファイルをRaspberry Pi OS (bullseye) に持っていって実行しても、実行時にglibc 2.35が見つからず、動的リンクに失敗してしまい、起動できない。
この問題への対策は、2通り考えられる。
1つ目は、ホスト環境として「クロスコンパイル用のglibcのバージョンがRaspberry Pi OS (bullseye) のglibcと同じ2.31となるディストリビューション」を選択する方法である。
Debian 11 (bullseye) なら確実に大丈夫だ。Ubuntuでも20.04ならglibc 2.31なので問題は生じない。
2つ目は、クロスコンパイル時にglibcを静的リンクしてしまう方法である。glibcを動的リンクするのではなく、静的リンクして丸抱えしてしまえば、実行時にバージョン違いの問題に悩まされることはない。
とはいえ静的リンクすると実行ファイルが肥大化するし、glibcにセキュリティ修正などが発生するたびにアプリを再ビルドして「修正済みのglibc」を実行ファイルに同梱しなくてはならなくなる。
そんな訳で、個人的には、静的リンクは「最終手段」として温存しておきたいところである。
ということで、Raspberry Pi OS (bullseye) で動かすソフトウェアをクロスコンパイルするならば、Debian 11 (bullseye) かUbuntu 20.04にクロスコンパイル環境を構築するのがよさそうだ。Windows使いならどちらもWSLでインストールできる。他の仮想環境ないし実機上にホスト環境を用意するなら、今ならRaspberry Pi Desktopもアリかもしれない。
最近の別解:Raspberry Pi GCC Toolchainsを使う
サードパーティ*1になるが、Raspberry Pi GCC Toolchainsという、Raspberry Pi向けに色々とチューニングされたGCCツールチェーンを配布しているプロジェクトがある。
このプロジェクトが配布しているクロスコンパイル用ツールチェーンならば、ある程度はホスト環境について自由が利くようだ。
ただしこのツールチェーンの実績や安定性については不明である。
*1:つまりRaspberry Pi公式のプロジェクトではなさそう。