Raspberry PI PICO W SDKの環境構築でハマった話

## VSCode+ Pico SDK でinclude 行のエラー

先日、VSCode + Raspberry pi pico SDKの環境を作ったが、その時にはまった話を恥ずかしいが書いておこうと思う。延べで、８時間以上は悩んだのだが、結果としてはGit の環境が悪かったようで、Gitをインストールしなおしたらあっけなく解決した。


## 現象
VSCodeに、マーケットプレイスから Raspberry pi Pico のSDKをインストール、インストールは何事もなく完了した。

作成した環境で、Raspberry PI pico　(Wなし）のLED 点滅を作りビルドして、まったく問題なく動作を確認した。

この時点で、SDKの環境に問題が無い、と思い込んでしまったのが悪かった。　


次に、Raspberry PI pico Wで、同じ操作を行い、プロジェクトウイザードからLED点滅のコードを作成した。

```
 #include <stdio.h>
 #include "pico/stdlib.h"
 #include "hardware/pio.h"
 #include "pico/cyw43_arch.h"

 #include "blink.pio.h"

void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq) {
    blink_program_init(pio, sm, offset, pin);
    pio_sm_set_enabled(pio, sm, true);
```

すると　```#include "pico/cyw43_arch.h" ```　の行に波線が出て、このヘッダファイルがincludeできないという表記になってしまった。

もちろん、これをビルドしても、このエラーになってしまう。
```
<path>/blink.c:2:10: fatal error: pico/cyw43_arch.h: No such file or directory
    2 | #include "pico/cyw43_arch.h"
      |          ^~~~~~~~~~~~~~~~~~~
```

## 調査
この手のエラーは、C/C++をやっているなら、一度はお目にかかるもので、はじめは大した問題とは思っていなかった。cmakeのファイルやら何やらを見て、includeを追加すればそれで済むと思っていた。

実際、[reddit](https://www.reddit.com/r/raspberrypipico/comments/wg9jr5/pico_w_blink_example_code_error_picocyw43_archh/) や[github](https://github.com/apple/swift-embedded-examples/issues/7)で同じ現象が報告されていた。

これらの記事では、主に次のような提案がされているが、残念ながら解決には至らない。
* target_link_librariesに、pico_cyw43_arch_noneを追加する
* CMAKE に、-DPICO_BOARD=pico_w　を追加して実行する
* c_cpp_properties.jsonのincludePathに追加する
* compile_commands.jsonのコンパイル引数に -i としてインクルードパスを追加する

※後から思えば、「target_link_librariesに、pico_cyw43_arch_noneを追加する」はなかなか近い回答だったと言えるが、その時には正しく追加されているとしか思わなかった。

## 判明

色々調べていると、やはり、 target_link_librariesへのpico_cyw43_arch_noneが追加されていないとこのエラーが出るというのが本命筋に思えてくるため、再度、CMakeのログを確認した。

cmake clean rebuildでcmakeをやり直すと、cyw43-driver が正しく初期化されていない、というメッセージが出ていた。
しかも、「SDKのインストールフォルダで、git submodule update --initを実行しろ」と丁寧に書いてあった。

```
[cmake]   cyw43-driver submodule has not been initialized; Pico W 
wireless support will be unavailable
[cmake]   hint: try 'git submodule update --init' from your SDK directory
```


そこで、言われたとおりに作業すると、次のようなエラーが発生する
```
git submodule update --init

Skipping command-line '"C:\Program Files\Git\usr\usr\bin\..\usr\bin\bash.exe"'
('C:\Program Files\Git\usr\usr\bin\..\usr\bin\bash.exe' not found)
Need a valid command-line; Edit the string resources accordingly

```

果たして、```C:\Program Files\Git\usr\usr\bin\..\usr\bin\bash.exe```というフォルダが存在せず、現在のgit環境がマッチしていない、と言うことになる。


## 解決
この環境のgitはいつ入れたのか覚えていないが、まずは入れなおしてコマンドを再実行したところ、あっさりとコマンドは成功する。

```
git submodule update --init
Submodule 'lib/btstack' (https://github.com/bluekitchen/btstack.git) registered for path 'lib/btstack'
Submodule 'lib/cyw43-driver' (https://github.com/georgerobotics/cyw43-driver.git) registered for path 'lib/cyw43-driver'
Submodule 'lib/lwip' (https://github.com/lwip-tcpip/lwip.git) registered for path 'lib/lwip'
Submodule 'lib/mbedtls' (https://github.com/Mbed-TLS/mbedtls.git) registered for path 'lib/mbedtls'
Submodule 'tinyusb' (https://github.com/hathach/tinyusb.git) registered for path 'lib/tinyusb'
Cloning into 'C:/Users/hisay/.pico-sdk/sdk/2.0.0/lib/btstack'...
Cloning into 'C:/Users/hisay/.pico-sdk/sdk/2.0.0/lib/cyw43-driver'...
Cloning into 'C:/Users/hisay/.pico-sdk/sdk/2.0.0/lib/lwip'...
Cloning into 'C:/Users/hisay/.pico-sdk/sdk/2.0.0/lib/mbedtls'...
Cloning into 'C:/Users/hisay/.pico-sdk/sdk/2.0.0/lib/tinyusb'...
Submodule path 'lib/btstack': checked out '2b49e57bd1fae85ac32ac1f41cdb7c794de335f6'
Submodule path 'lib/cyw43-driver': checked out 'faf36381bad1f668a30172b6336c9a970966ef4c'
Submodule path 'lib/lwip': checked out '0a0452b2c39bdd91e252aef045c115f88f6ca773'
Submodule path 'lib/mbedtls': checked out '5a764e5555c64337ed17444410269ff21cb617b1'
Submodule path 'lib/tinyusb': checked out '4232642899362fa5e9cf0dc59bad6f1f6d32c563'
```

その後、VSCodeを再起動すると、includeの波線も消え、ビルド/実行できた

## 反省点とグチ

VSCodeに機能拡張を追加して最初にプロジェクトを作ったときに、SDKのダウンロードと環境設定が行われる。サブモジュールの初期化は、この時に行われるので、おそらく、この時にログをきちんと見ていれば、 submiduleの初期化が成功していなかったことはわかったはずだった。

また、実際、cmakeのクリーンとビルドは何回か実行したが、cmakeの途中で出ていたSDK サブモジュールのエラーについては、実行ログを読んで見ていなかった。cmakeのビルド成功という、最後のステータスコードだけで、問題が無いと思い込んでいたのも問題だった。

エラーメッセージ（しかも親切にも対処方法まで書いてある）を読んでいない私が悪い、それはわかった上で言わせてもらえば、大量に表示されるログの中の数行のエラー、しかも最終的な実行ステータスは success になっているのを、その場で気づけ、と言うのはかなり厳しい。

最近のビルド環境は、ビルドツールが高度に階層化され、オープンソースのツールが複数組み合わされ、ノータッチで一気に実行できる。各ツールが、何をどの順番で呼び出すのか、何をやっているのか理解せずに開発が始められる。しかし、便利なのは動いているときの話。　ひとたび、どこかに問題が発生すると、見つけるのが難しくなってしまう。　クローズドなIDE/SDK (MPLabXなど）では、環境設定などでの問題はその場でレポートされ解決されることが多く、問題が起こりにくいように思う。