rustのコンパイルがつらいので、分散ビルドすることにした

# 本題
皆さん、普段の開発なら鯖を用いて開発していると思いますが、音声やアプリを扱うなど、鯖を使えないこともあります。
そして、耐えられなくなったので分散ビルドの環境を作ることにしました。

なお、Rustを使っている人ならわかるだろうということで、細かい解説は書きません。

# WSLの用意
普段使わないPCのWindowsでビルド用サーバを用意する気だったのだが、Linuxのみ対応とのことだったので。

```powershell
wsl --install
```

ついでに、ストアからUbuntu24.04LTSをインストール

# ツールのインストール
今回はsccacheを用いてビルドするため、sccache-distをリリースからゲットします。

ついでに、rust関係もインストール。

# 設定

https://github.com/mozilla/sccache/blob/main/docs/Distributed.md

https://github.com/mozilla/sccache/blob/main/docs/DistributedQuickstart.md

の通りに進めていく。

まずはスケジューラを立てます。
適当に、`./sccache-dist auth generate-jwt-hs256-key`でsecret keyを生成する。
そして、`scheduler-config.toml`に追記する。

```toml:scheduler-config.toml
# The socket address the scheduler will listen on. It's strongly recommended
# to listen on localhost and put a HTTPS server in front of it.
public_addr = "0.0.0.0:10600"

[client_auth]
type = "token"
token = "oligami's token"

[server_auth]
type = "jwt_hs256"
secret_key = "############################"
```

この後、サーバを立てます。
```bash
./sccache-dist scheduler --config scheduler-config.toml
```

次にビルドサーバを立てていきます。

トークンを生成
```bash
./sccache-dist auth generate-jwt-hs256-server-token --config scheduler-config.toml --server 100.98.151.25:10501
```

```toml:server-config.toml
# This is where client toolchains will be stored.
cache_dir = "/tmp/toolchains"
# The maximum size of the toolchain cache, in bytes.
# If unspecified the default is 10GB.
# toolchain_cache_size = 10737418240
# A public IP address and port that clients will use to connect to this builder.
public_addr = "100.98.151.25:10501"
# The URL used to connect to the scheduler (should use https, given an ideal
# setup of a HTTPS server in front of the scheduler)
scheduler_url = "http://100.98.151.25:10600"

[builder]
type = "overlay"
# The directory under which a sandboxed filesystem will be created for builds.
build_dir = "/tmp/build"
# The path to the bubblewrap version 0.3.0+ `bwrap` binary.
bwrap_path = "/usr/bin/bwrap"

[scheduler_auth]
type = "jwt_token"
# This will be generated by the `generate-jwt-hs256-server-token` command or
# provided by an administrator of the sccache cluster.
token = "##########################"
```

これで、ビルド用サーバを起動する
```bash
sudo apt install bubblewrap
nohup sudo ./sccache-dist server --config server-config.toml &
```

# クライアント
自分のPCに戻り、下記を作成
```toml:~/AppData/Roaming/Mozilla/sccache/config/config
[dist]
# The URL used to connect to the scheduler (should use https, given an ideal
# setup of a HTTPS server in front of the scheduler)
scheduler_url = "http://100.98.151.25:10600"
# Used for mapping local toolchains to remote cross-compile toolchains. Empty in
# this example where the client and build server are both Linux.
toolchains = []
# Size of the local toolchain cache, in bytes (5GB here, 10GB if unspecified).
toolchain_cache_size = 5368709120

[dist.auth]
type = "token"
# This should match the `client_auth` section of the scheduler config.
token = "oligami's token"
```

接続すると、こうなる。
```bash
sccache --stop-server
sccache --start-server
sccache --dist-status

> {"SchedulerStatus":["http://100.98.151.25:10600/",{"num_servers":1,"num_cpus":6,"in_progress":0}]}
```

# Windows用
次に、Windows向けにサーバでビルドする準備を行います。
仕組み的にはクロスコンパイルしてる感じですね。

サーバと同じ環境（サーバでも可）で必要な環境（rustup target add etc.）を用意します。

その後、このコマンドで環境をキャプチャします。

```bash
sccache --package-toolchain ~/.cargo/bin/rustc rust_toolchain.tar.gz
```

次に、クライアントの`C:\toolchains`などに持ってきて、configをこのような感じに書き直します。
```toml:config
[dist]
# The URL used to connect to the scheduler (should use https, given an ideal
# setup of a HTTPS server in front of the scheduler)
scheduler_url = "http://100.98.151.25:10600"
# Size of the local toolchain cache, in bytes (5GB here, 10GB if unspecified).
toolchain_cache_size = 5368709120

[dist.auth]
type = "token"
# This should match the `client_auth` section of the scheduler config.
token = "oligami's token"

# Used for mapping local toolchains to remote cross-compile toolchains. Empty in
# this example where the client and build server are both Linux.

[[dist.toolchains]]
type = "path_override"
compiler_executable = "C:/Users/nziq5/.rustup/toolchains/stable-x86_64-pc-windows-msvc/bin/rustc.exe"
archive = "C:/toolchains/rust_toolchain.tar.gz"
archive_compiler_executable = "/bin/rustc"

[[dist.toolchains]]
type = "path_override"
compiler_executable = "C:/Users/nziq5/.rustup/toolchains/nightly-x86_64-pc-windows-msvc/bin/rustc.exe"
archive = "C:/toolchains/rust_toolchain.tar.gz"
archive_compiler_executable = "/bin/rustc"

[[dist.toolchains]]
type = "path_override"
compiler_executable = "C:/Users/nziq5/.cargo/bin/rustc.exe"
archive = "C:/toolchains/rust_toolchain.tar.gz"
archive_compiler_executable = "/bin/rustc"
```

なお、dylibとかが入ってくると、ローカルにフォールバックします

# 自動起動
systemdを使う。

```:/etc/systemd/system/sccache-server.service
[Unit]
Description=sccache-dist server
Wants=network-online.target sccache-scheduler.service
After=network-online.target sccache-scheduler.service

[Service]
ExecStartPre=/bin/sleep 10
ExecStart=/home/oligami/sccache/sccache-dist-v0.8.2-x86_64-unknown-linux-musl/sccache-dist server --config /home/oligami/sccache/sccache-dist-v0.8.2-x86_64-unknown-linux-musl/server-config.toml

[Install]
WantedBy=multi-user.target
```

スケジューラは勝手にデーモン化するが、面倒なので無効化してsystemdを使う

```:/etc/systemd/system/sccache-scheduler.service
[Unit]
Description=sccache-dist scheduler
Wants=network-online.target
After=network-online.target

[Service]
Environment="SCCACHE_NO_DAEMON=1"
ExecStart=/home/oligami/sccache/sccache-dist-v0.8.2-x86_64-unknown-linux-musl/sccache-dist scheduler --config /home/oligami/sccache/sccache-dist-v0.8.2-x86_64-unknown-linux-musl/scheduler-config.toml


[Install]
WantedBy=multi-user.target
```

wslを再起動しても問題なく動作するようになった。

# 計測
現在私が作っているプロジェクトを1からビルドしてみましょう。有りの速度は、6m 41sですね。

そして、無効にした結果、14m 31sかかりました。思ったより効果ありますね。

なお、キャッシュがあった場合の速度は2m 44sです。流石。

# 余談
しかし、私にとって重要なのはtrunkのコンパイル速度。

キャッシュ等も全て空だった場合、7m 57s。妥当な速さ。

なお、trunkの再ビルドでは15sもかかる。dylibにしてもwasmだから意味ないし辛い。

# 参考
https://github.com/mozilla/sccache/blob/main/docs/DistributedQuickstart.md#using-custom-toolchains

https://github.com/mozilla/sccache/blob/main/docs/Distributed.md

https://github.com/mozilla/sccache/issues/694

https://github.com/mozilla/sccache/issues/975

https://github.com/mozilla/sccache/tree/main?tab=readme-ov-file#overwriting-the-cache

https://bugzilla.mozilla.org/show_bug.cgi?id=1664963

https://firefox-source-docs.mozilla.org/build/buildsystem/sccache-dist.html