Featured image of post Nix flakesでRaspberry PiのRustクロスコンパイル環境+Debug Probeをつくる

Nix flakesでRaspberry PiのRustクロスコンパイル環境+Debug Probeをつくる

RustでRaspberry Piの開発をするにあたってプロジェクト雛形が欲しいなと思ったので、Nix flakesで作っておこうと思います。

Nix flakesについては以下の記事で導入の紹介をしていますので、そちらを参照ください。

もともとNixpkgsとhome-managerを利用してシェル環境や開発環境を管理していたのですが、昨年末に重い腰を上げてnix flakeに移行しました。\n
home-managerをNix flakesで書き直してdotfiles管理をいい感じにする

Nixpkgsを使ったRustの開発環境自体は以下のChip8エミュレータなどでも使っているように、rustcなどの必要なパッケージを指定すれば比較的簡単に構築できます。

Learning on . Contribute to tomoyukim/chip8-rust development by creating an account on GitHub.
GitHub - tomoyukim/chip8-rust: Learning on https://github.com/aquova/chip8-book

なおNix flakesではtemplate機能があり、 nix flake show templates で公式が配布しているtemplateを参照できます。 これらは、あくまでもサンプル的な位置付けのようですが、 nix flake init --template 'templates#rust' などとするとそれを利用してflake.nixを作成することもできます。

今回はクロスコンパイルでRaspberry Pi Picoに対する開発環境ということで、probe-rsによるDebug Probeの利用、flip-linkをlinkerに利用するなど、組込みクロスコンパイル環境を構築していきます。

以前Rusty Keysプロジェクトを参考に、Rustの開発環境構築をやってみましたが、今回はこれをNix flakesを使ってやってみようと思います。

2023年5月号の「インターフェース」誌には、Rust特集が掲載されています。 その特集の1部2章では、Rusty Keysを使った入門記事が掲載されており、面白そうなので実践してみることにしました。\n
RustyKeysで組込みRust入門:Raspberry Pi 5ホストで開発環境構築からHello Worldまで

Raspberry Pi Debug Probeと環境セットアップ

前回はRaspberry Pi Picoをデバッグプローブとして利用しましたが、今回は「Raspberry Pi Debug Probe」(以下Debug Probe)を利用します。

Debug Probeは公式から2023年2月に発売されたデバッグプローブです。

Figure 1: スイッチサイエンス商品ページより引用

Figure 1: スイッチサイエンス商品ページより引用

Raspberry Pi デバッグプローブ — スイッチサイエンス

機能はPicoで代用している場合と同等ですが、ケース付きでコンパクトになっており、各種ケーブルも同梱されているので私はこちらを利用しています。

公式ドキュメントも充実しており、firmwareも以下のGithubから適宜ダウンロードしてアップデートすることが可能です。

Raspberry Pi Debug Probe - Raspberry Pi Documentation

Contribute to raspberrypi/debugprobe development by creating an account on GitHub.
GitHub - raspberrypi/debugprobe

接続はこのような感じです。

なおホストには以前セットアップしたRaspberry Pi 5を使っています。

日本でもついに待望のRaspberry Pi 5が発売されました。 この最新モデルは、前作のRaspberry Pi 4のスペックを倍以上に引き上げ、2018年のノートPC並みのパフォーマンスを誇ります。 さらに、初めてPCIeが搭載され、NVMe SSD用のHATも登場しました。 これにより、日常的に利用できる超小型コンピューターとしての可能性さえ見えてきました。\n
Raspberry Pi 5をNVMe SSD起動でデスクトップPC化

probe-rsやflip-linkのインストール

RustyKeyでも使っていた probe-rsflip-link はRustプロジェクトのrunnerやlinkerとしてCLIから利用されます。

NixOS環境では実行ファイルはNixのderivationになっている必要があるので、cargo経由でインストールしても実行できません。 他のLinux Distroであればランタイム依存がなければ実行はできますが、Nixで管理しているパッケージとの依存もありますし、Nixのポリシーに従って管理している方が取り回しがよいので、flake.nixでインストールします。

1
2
3
4
5
6
devShells.default = with pkgs; mkShell {
  buildInputs = [
    probe-rs-tools
    flip-link
  ];
};

rust-overlayでrustupの機能を利用する

Nixpkgsを利用していなければrustupでtargetのツールチェインをインストールしますが、Nix環境ではrustupでやっているようなことはNixで処理します。 そのため、rustのツールチェインをカスタマイズするためにoverlayを利用します。

非公式ですが、NixにはRustツールチェインのoverlayがいくつかあります。今回私はrust-overlayを利用します。

Pure and reproducible nix overlay of binary distributed rust toolchains - oxalica/rust-overlay
GitHub - oxalica/rust-overlay: Pure and reproducible nix overlay of binary distributed rust toolchains

rust-overlayでは、rustupが提供している以下のような機能を利用することができます。

overlayを利用して、Pico向けのターゲットである thumbv6m-none-eabi をインストールします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
overlays = [ rust-overlay.overlays.default ];
pkgs = import nixpkgs { inherit system overlays; };
rustToolchain = pkgs.rust-bin.fromRustupToolchain {
  channel = "stable";
  components = [
    "clippy"
    "rustfmt"
    "rust-analyzer"
    "rust-src"
  ];
  targets = [
    "thumbv6m-none-eabi"
  ];
};

ついでに必要となるcomponentもインストールしています。

まとめ

結果的にはrust-overlayを利用することで、シンプルかつ簡単にプロジェクトを構築することができました。

以下のようにNix自体にもRustに限らずクロスコンパイルをするための環境を作る方法があるので、試したりしていたのですがflake.nixが結構複雑になった上に最終的に狙ったように動作させることはできませんでした。

Cross compilation — nix.dev documentation

Rustの場合は自身のエコシステムでクロスコンパイラの提供をしているので、rust-overlayを使っていく方が筋がよかったのだろうと思います。

構築したプロジェクトは以下のようになりました。

A project just to test debugprobe work on rust project - tomoyukim/pi-debugprobe-rust
GitHub - tomoyukim/pi-debugprobe-rust: A project just to test debugprobe work on rust project
Hugo で構築されています。
テーマ StackJimmy によって設計されています。