Raspberry Pi Picoの自前リポジトリ(プロジェクト)を新規作成する(Windows環境)

## はじめに
Raspberry Pi Pico + MicroPythonで開発していたのですが、かゆいところに手が届かなさ過ぎてC/C++で開発することにしました。  

サンプルはコンパイルできましたが、いざプロジェクトを新規に作ろうとして使ったpico-project-generatorは、文字化けしたエラー吐きながら中途半端な出力しかできず…
https://github.com/raspberrypi/pico-project-generator?tab=readme-ov-file
何かコツがあるんですかね？

ということで手堅く所望のリポジトリが作れるように自分用のメモを兼ねて残しておくことにします。

## 最終目標
以下のディレクトリ構成をもったオーソドックスなリポジトリを作りたいと思います。
GitHub Actionsでビルドもできるようにしておきます。

```sh: リポジトリ構成
/
├── src/                    # ソースファイル (.cppファイル)
│   ├── main.cpp            # メインプログラム
│   └── ...
├── tests/                  # テストコード
│   ├── test_main.cpp
│   └── ...
├── docs/                   # ドキュメント
│   └── ...
├── lib/                    # 外部ライブラリ
│   └── ...
├── CMakeLists.txt          # ルートのCMake設定ファイル
├── pico_sdk_import.cmake   # SDKをリンクするためのCMakeスクリプト
├── build/                  # ビルドファイル（CMakeビルドディレクトリ）
├── .gitignore              # 構成管理からの除外設定
├── .vscode/                # VSCode設定ディレクトリ
│   ├── c_cpp_properties.json # ツールチェーンの設定
│   ├── cmake-kits.json     # CMakeの設定
│   ├── extensions.json     # 導入拡張機能
│   ├── settings.json       # VSCodeの設定
│   ├── launch.json         # デバッグ設定
│   └── tasks.json          # ビルドタスク設定
├── .github/                # github設定ディレクトリ
│   └── workflows/          # github actions workflow格納ディレクトリ
│       └── release-build.yml # リリースビルドを行うためのWorkflow
└── README.md               # プロジェクトのREADMEファイル
```

ヘッダファイルやCMake設定の構成はいろいろ流儀があるかもしれないですね。
時と場合に合わせて組み直していただければいいのかなと思います。

## 環境準備
Pico SDK v1.5.1 を前提に進めていきます

### [Step1] ツールチェーンのインストール
以下で配布されている最新のリリースを持ってきてインストールします
https://github.com/raspberrypi/pico-setup-windows?tab=readme-ov-file

:::note info
幾つかのソフトウェアがインストールされますが、すでにインストールされている場合はスキップされる様子。その場合は、バージョンが古くてうまくいかないなど出てくるので、手動でバージョンアップが必要になります。
:::

CMakeとかは最新版を手動で入れておく方が無難かも
https://cmake.org/download/

### [Step2] 環境変数を設定する
| 変数                  |値(設定例)                      |
| -                     | -                             |
| Pathに追加             | `C:\Program Files\CMake\bin` |
| `PICO_SDK_PATH`       | `C:\Program Files\Raspberry Pi\Pico SDK v1.5.1\pico-sdk`  |
| `PICO_TOOLCHAIN_PATH` |  `C:\Program Files\Raspberry Pi\Pico SDK v1.5.1\gcc-arm-none-eabi`  |
| `PICO_INSTALL_PATH`   | `C:\Program Files\Raspberry Pi\Pico SDK v1.5.1` |

CMakeのパスは通していない人だけ対応ですね。

### [Step3] 必要なファイルをコピーしてくる
プロジェクトのフォルダを作っていくつかファイルを集めてきます

#### [1] pico_sdk_import.cmakeをコピー
SDKのインストールディレクトリがデフォルトの場合の前提で、
`C:\Program Files\Raspberry Pi\Pico SDK v1.5.1\pico-sdk\external\pico_sdk_import.cmake`
のファイルをコピーしてきます

#### [2] VSCodeの設定類をコピー
これらのファイルはCMakeの引数を始め色々含まれているので必要になります。
まず、以下のファイルを任意の場所に展開します。
`C:\Program Files\Raspberry Pi\Pico SDK v1.5.1\pico-examples.zip`

その中の、以下のvscode設定ファイルのディレクトリを丸々コピーしてきます
`./pico-examples/pico-examples/.vscode`

### [Step4]setting.jsonの修正
初期設定で動いていてくれない…ので、手直しします。
1行だけ追加しています。

```jsonc: setting.json
{
  "cmake.statusbar.advanced": {
    "debug": {
      "visibility": "hidden"
    },
    "launch": {
      "visibility": "hidden"
    },
    "build": {
      "visibility": "hidden"
    },
    "buildTarget": {
      "visibility": "hidden"
    }
  },
  "cmake.buildBeforeRun": true,
  "cmake.configureOnOpen": true,
  "cmake.configureSettings": {
    "CMAKE_MAKE_PROGRAM": "${env:PICO_INSTALL_PATH}/ninja/ninja.exe",    //この1行を追加
    "CMAKE_MODULE_PATH": "${env:PICO_INSTALL_PATH}/pico-sdk-tools"
  },
  "cmake.generator": "Ninja",
  "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}
```

私はこの方法で回避しましたが、もっとスマートな方法ありますかね？

### [Step5] CMakeLists.txtを作る
削ろうと思えばもっと削れる思います。
個人のプロジェクトなので適当なところがあります。

```cmake:CMakeLists.txt
# CMakeの最小バージョンを指定(SDK 1.5.1では3.12以上を指定しているので。)
cmake_minimum_required(VERSION 3.12)

# pico_sdk_import.cmakeスクリプトを含める
# この処理はproject()を実行する前に設定する
include(pico_sdk_import.cmake)

project(sample C CXX ASM)        # プロジェクト名「sample」
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# SDK初期化
pico_sdk_init()

# 対象ファイルの追加
# srcフォルダおよびそのサブディレクトリ内のすべての.cppファイルを再帰的に検索
file(GLOB_RECURSE MY_SOURCES "src/*.cpp")  
add_executable(object ${MY_SOURCES})

# ライブラリをリンク（必要に応じて追加）
target_link_libraries(object
    pico_stdlib
    hardware_pwm
    hardware_adc
    )

# stdioをUSBで使う設定（必要に応じて設定）
pico_enable_stdio_usb(object 1)
pico_enable_stdio_uart(object 0)

# pico-exampleからのコピーです
# コンパイルオプションの設定（必要に応じて変更）
add_compile_options(-Wall
        -Wno-format          # int型とint32_t型が別物なので警告を抑制する(int32_tはlong int扱い)
        -Wno-unused-function # 未使用関数警告の抑制
        )
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
    add_compile_options(-Wno-maybe-uninitialized)  # 未初期化変数警告の抑制
endif()

# ELFファイルの他に、binとuf2ファイルを生成
pico_add_extra_outputs(object)
```

上記の設定では、`./build/object.uf2`が書き込み用バイナリとして生成されます
`object`のところを`${PROJECT_NAME}`に差し替えると、プロジェクト名でバイナリが生成されるようになります。

### [Step6] .gitignoreを設定する
大した内容ではないので畳んでおきます
ニーズに合わせて修正して使いましょう。

<details><summary>.ignoreの設定内容</summary>

```cmake:.gitignore
.idea
.vscode
_deps
cmake-*
build
.DS_Store

# VSCode設定
# この設定だけは、最低限必要なファイルをpushした後に行うのがいいかも
.vscode/
```

</details>

### [Step7] GitHub Actionsでビルドできるようにする
公式ドキュメントとか見ながら作ってみました。
以下のworkflowでとりあえず動きました。

```yaml:.github/workflows/release-build.yml
name: Release Build    # 任意の名称

on:
  workflow_dispatch:   # 手動トリガ

jobs:
  release-build:
    runs-on: ubuntu-latest

    steps:
    # リポジトリをチェックアウト
    - uses: actions/checkout@v4

    # ビルドツールの導入
    - name: Install prerequisites
      run: |
          sudo apt update
          sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential

    # SDKの導入と環境変数の設定
    - name: Checkout Pico SDK and submodules
      run: |
          git clone --depth 1 --branch master https://github.com/raspberrypi/pico-sdk.git
          echo "PICO_SDK_PATH=$(pwd)/pico-sdk" >> $GITHUB_ENV
          git -C pico-sdk submodule update --init

    # プロジェクトの構成
    - name: Configure CMake
      run: |
          mkdir build
          cd build
          cmake ..

    # ビルド
    - name: Build
      run:  |
          cd build
          make

    # 成果物をアップロード
    - uses: actions/upload-artifact@v4
      with:
        name: uf2_object
        path: build/*.uf2

```

とりあえず手動で動いてくれれば、トリガ条件とかは後から何とかなりますね。

生成されたuf2ファイルはartifactsのところにzip圧縮されてUPされます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248663/c2ff2830-814b-7835-996c-67ffaf2c5c4e.png)


## まとめ

テストフレームワークを組み合わせたりとか不足していますが、とりあえずコンパイルできるという最低限？のリポジトリのつくりかたを記載しました。
別の機会になりますが、個人的にはGitHub Actionsで自動テストとかも作っておきたいですね

今回の記事はいろいろ修正や改善できるところが残っている気がしています。時間見つけて少しずつなおしていこうと思います。

私と同じように困っている人の助けになれば幸いです。
ここまで読んでいただきありがとうございました。