Dockerを使ってMacでRaspberry Pi用のアプリをビルドする

Toolchainをあれこれしてクロスコンパイル環境を作るより圧倒的に簡単！

## 環境 ##
* Mac
* Raspberry Pi 5

WindowsとかLinuxでもできると思う。知らんけど。

## JUCEでプロジェクト作成 ##
PluginのBasicでプロジェクト SynthTest をホームに作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107818/bfffa269-9880-623b-60f9-7d02958f2d7a.png)

モジュールの設定で Set copy-mode for all modules...で、Set all modules copy locallyをしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107818/d2a94eb6-fef2-4640-10a1-a0e1d3c32406.png)

ExporterにLinux Makefileを追加して保存したらこんな感じになるかと。
```
~/SynthTest/
├── Builds/
│   ├── MacOSX/
│   └── raspi/
│       ├── make_helpers/
│       └── Makefile
├── JuceLibraryCode/
├── Source/
├── JuceLibraryCode/
└── SynthTest.jucer
```

## Dockerをインストール ##
ここからダウンロード。
https://www.docker.com/products/docker-desktop/

実行したらアカウント云々言われるので指示に従って終わらせる。ボクはGitのアカウントでログインした。

## Docker の設定 ##

ターミナルでDocker用のフォルダを作る。~/SynthTestの中にDockerというフォルダを作成。さらにその中にraspiを作成。こういう風に。
```
~/SynthTest/
├── Builds/
├── Docker
│   └── raspi/
├── JuceLibraryCode/
├── Source/
├── JuceLibraryCode/
└── SynthTest.jucer
```

Dockerfileという名前のファイルをDocker/raspiの中に下記の内容で作成する。
```Dockerfile
FROM arm64v8/ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    build-essential \
    cmake \
    git \
    gcc-arm-linux-gnueabihf \
    g++-arm-linux-gnueabihf \
    libsdl2-dev \
    pkg-config \
    libfreetype6-dev \
    libcurl4-openssl-dev \
    libwebkit2gtk-4.0-dev \
    libgtk-3-dev \
    libjack-jackd2-dev && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app/SynthTest/Builds/raspi
```

Dockerイメージをビルド。結構時間かかる。なんかエラーが出たらログをコピペしてChatGPTに聞いて直し方教わればOK。
```sh
docker build -t synthtest-builder ~/SynthTest/Docker/raspi
```

ビルドできたら実行
```
docker run -it synthtest-builder
```


シンセをビルドするスクリプトをbiuld.shとして作成。-j12の部分は並列コンパイルの指定なので、使ってるCPUのコアに合わせて適宜変える。
```build.sh
#!/bin/bash
docker run --rm -it \
  -v ~/SynthTest:/app/SynthTest \
  -w /app/SynthTest/Builds/raspi \
  synthtest-builder make CONFIG=Release -j12
```
何をやっているかというと、
* -v ~/SynthTest:/app/SynthTest: ホストの ~/SynthTest をコンテナ内の /app/SynthTest にマウント。
* -w /app/SynthTest/Builds/raspi: 作業ディレクトリを Builds/raspi に設定。

Cleanするスクリプトも作成。
```clean.sh
#!/bin/bash
docker run --rm -it \
  -v ~/SynthTest:/app/SynthTest \
  -w /app/SynthTest/Builds/raspi \
  synthtest-builder make clean
```
実行属性をつける。
```sh
chmod +x build.sh clean.sh 
```

## ビルド ##
ターミナルで
```sh
./build.sh
```
するだけ。SynthTestという拡張子がないものが実行ファイル。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107818/e851c095-e09b-35aa-a56f-ae516a24fb67.png)


実行ファイルをラズパイにコピーして動作確認。scpでもsambaでもなんでもいい。
![IMG_7435.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107818/089c23e6-3249-ef23-537b-4a02287193ee.jpeg)

## おまけ: Dockerのコンテナとイメージの削除 ##
実行中のコンテナを確認
```sh
docker ps
```
表示例
```
CONTAINER ID   IMAGE             COMMAND    STATUS         PORTS    NAMES
abc123456789   raspberry-pi-app  "make"    Up 2 minutes            clever_pike
```
コンテナを停止
```sh
docker stop <CONTAINER ID>
```

全てのコンテナを削除
```sh
docker ps -aq | xargs docker rm
```

イメージを削除
```sh
docker images
```
表示例
```
REPOSITORY           TAG       IMAGE ID       CREATED        SIZE
raspberry-pi-app     latest    abc123456789   5 minutes ago  123MB
```
イメージを削除
```
docker rmi <IMAGE ID>
```
すべての未使用イメージを一括削除する場合
```sh
docker image prune -a
```