The Embedonomiconでハマったことあれこれ(3章まで)
はじめに
これからThe Embedonomiconを始める方々へ
こちらのはてなブログをベースに進めていくことを推奨します。本家はクセが強い(これから書くソースコードを、編集後のファイルをcat、head、tail、sedで表示する形で表すのはどこぞのコミュニティでのデファクトスタンダードなのか?最初、はて?となってしまった)上に致命的なミスが放置されているせいか、その置き換えを狙ったのではないかと思うほどよく書かれているし、問題が発生する箇所のフォローもしている。実行環境の構築は本家を参照し、それ以降はこのブログで読み進めつつ本家の内容を確認する方法が、スムーズに進めるためには良いと思う。
この文章へのモチベーション
ひょんなことからマイコンボードをいじるをことになったのだが、せっかくなのでRustでコーディングしてみようと思い、Rust組み込み開発におけるARMマイコンボード周りのソフトウェア実装者が最初に参照するであろうThe Embedonomiconを始めてみた。が、やはりというか何と言うか、うまくいかないことが多々あった。ネット上を調べてもズバリの回答が見当たらず辟易したので、それらについて書き残すことにした。同様の出来事にぶつかり、諦めてしまう人が一人でも減れば幸いである。
(蛇足)3章までである理由
単純にそれまで上述のブログを知らずに進めていたこと、AVR(Arduino UNO)でもRustで開発できることを知らなかったこと(今やりたいことはArduino UNOで十分)、個人的に高い関心があったのは4章までの内容だったこと(4章はハマるところがなかった)、等による。
使用環境
- Ubuntu-22.04LTS on WSL2(Windows11)
- rustc 1.80.1 (2024/08/17時点でのstable)
現象と対応
Preface (序章)
現象:"$ cargo install cargo-binutils"でエラー発生
設定例の情報をもとに環境構築を進めるが上記エラーが発生する場合がある。これは単にcargo installに必要な環境がインストールされていないことによる。なので以下のコマンドでGNU開発環境をインストールする。
$ sudo apt install build-essential
WSLにUbuntu等をセットアップしてすぐに始めた人はこれに当たる可能性が高いと思われる。
The smallest #![no_std] program (最小限の#![no_std]プログラム)
現象:"$cargo size --target thumbv7m-none-eabi --bin app"でコンパイルエラー発生
これに当たる人は少ないと思うが、状況によって複数のコンパイルエラーが発生するようだ(詳細不明)。stable以外のrustc(1.30.0)をoverrideした状況で発生した。以下のコマンドでoverrideをunsetしたところ、現象を回避することができた。
$ rustup override unset
現象:"$ cargo nm -- target/thumbv7m-none-eabi/debug/deps/app-.o | grep '[0-9] [^N] '"でコンパイルエラー発生
"error: Failed to parse crate metadata"、原因不明。2022年3月にusers.rust-lang.orgでトピックが立っていたが有耶無耶のまま終了。このエラーが資料を読み進めるにあたって致命的なものではないのでスルーする、ゴメンナサイ。
追記:ごにょごにょやっていたらコンパイルは終了するが特定のオブジェクトファイルが見つからない、というエラーに変わった。正直訳がわからない。もっと詳細を勉強しないと分からないだろう。実際にシンボルテーブルの内容を確認する必要があるような開発を手掛けるか分からないので当面は調査するつもりはない。
(おまけ)現象:ファイル".cargo/config"でビルドのターゲットを指定してcargo buildすると警告が出る
これは警告内容を読めば分かることだが、cargo 1.38以降はconfigではなくconfig.tomlを読み出すようになった。警告を気にするならファイル名をconfigからconfig.tomlに変更する
Memory layout (メモリレイアウト)
現象:"$ cargo rustc -- -C link-arg=-Tlink.x"でエラー発生
このエラーが出た場合、恐らく既に何かビルド環境がおかしくなっていると思われる。プロジェクトまたはビルド環境の再構築を推奨する。これについて2019年11月にusers.rust-lang.orgで言及されているが、根本的な解決策ではなかった。
※再現方法が分からなくなってしまったので検証してません、すみません。。。
現象:"$ arm-none-eabi-gdb -q target/thumbv7m-none-eabi/debug/app"でエラー発生(arm-none-eabi-gdb: command not found)。
あなたはここでかすかに残る記憶を呼び戻す必要がある。Preface (序章)のExample setup(設定例)には以下の記述がある。
#gdb-multiarch -- use
gdb-multiarch
when you wish to invoke gdb
そう、あなたは'"arm-none-eabi-gdb'の代わりに'gdb-multiarch'を呼び出さなければなりません。
$ gdb-multiarch -q target/thumbv7m-none-eabi/debug/app
※いかにもプログラマが書いた不案内なドキュメントだよねぇ。。。書いている本人はDRYの原則に則っているつもりなのかもしれないが、それを読む人たちはDoRY、と。
A main interface (mainインタフェース)
現象:"$ cargo new --edition 2018 --bin app"でエラー発生
前章までに作成したappクレートをrtクレートに変更したのに、ディレクトリ名を変更していないためエラーとなる。なので、appディレクトリの名前を変更する。具体的には、新たにアプリケーションを作成するbashコマンドのところを以下のようにする。変更するディレクトリ名はクレート名に合わせてrtとする(以降、ドキュメント内もその前提となっている)。
$ cd ..
$ mv app rt # <-これを追加
$ cargo new --edition 2018 --bin app
$ cd app
Discussion