OpenBSD 7.5でBazelをビルドする

# はじめに

最後に記事を書いてからかなり時間が空いてしまいましたが久しぶりに投稿していきます。

記事を書けていない間色々ありましたが、大きく変わったこととしてOpenBSDに入門して私用端末をOpenBSDに一部切り替えたというのがあります。このOpenBSDですが、最新のOSSが対応していないことが時たまありまして、自力でパッチを作って対応する、といったことを楽しくやらせてもらってます。
今回の記事では、mozcをビルドするために必要なBazel 7.3.0をOpenBSDの中で動かすためにやったことを扱います。

# Bazelとは

https://bazel.build/?hl=ja

BazelはGoogleが開発したビルドツールで、makeに置き換わるツールです。特徴としては、デフォルトで様々なプログラミング言語のビルドルールを提供、プロジェクトディレクトリを汚染しないビルド、並列化などが挙げられます。そして、OpenBSDに最新バージョンが対応していないソフトウェアは大抵Bazelでのビルドが必要だったりします（体感）。
そしてそうしたソフトウェアが、OpenBSDが対応していない最新バージョンのBazelを必要としている場合、Bazelをいちからビルドする必要があります。ちなみに現在OpenBSD 7.5でインストールできるBazelのバージョンは6.9.2です。**mozcのビルドに必要なバージョンは7.3.0**なのであとひとつ足りないといった感じですね。

Bazelの詳細については[他の方の記事](https://knowledge.sakura.ad.jp/6174/)に任せるとして、本題に入っていきましょう。

# Bazelのビルド

本題のOpenBSDでのBazelのビルドですが、基本的には公式ドキュメントに従いビルドしていきます。

https://bazel.build/install/compile-source?hl=ja

ビルドの仕方は大きく分けて以下の２つありますが、今回は２つ目の「Bazel をゼロからビルドする」方法をとりました。

- [Bazel を使用して Bazel をビルドする](https://bazel.build/install/compile-source?hl=ja#build-bazel-using-bazel)
- [Bazel をゼロからビルドする](https://bazel.build/install/compile-source?hl=ja#bootstrap-bazel)

ただ、これに従ってもOpenBSDにおいてはビルドエラーが発生します。今回の記事の主題はこれを解決するプロセスにあります。（※ビルドエラーの詳細については煩雑になるため本記事では省略します）

## ビルドエラーの原因

ビルドエラーの原因は、Bazelが依存するいくつかのライブラリがOpenBSDに対応したコードになっていないことにあります。今回問題になった依存ライブラリは以下のものです。

- [abseil-cpp 20230125.1](https://github.com/abseil/abseil-cpp/tree/20230125.1)
- [c-ares 1.15.0](https://github.com/c-ares/c-ares/tree/cares-1_15_0)
- [grpc 1.48.1](https://github.com/grpc/grpc/tree/v1.48.1)
- [upb 0.0.0-20220923-a547704](https://github.com/protocolbuffers/upb)

これらのライブラリの中身のコードをOpenBSD向けに書き換えることができればビルドエラーは解消できます。

## ビルドエラーの解決

さて、これらのライブラリは直接Bazelのコードに埋め込まれているわけではありません。`MODULE.bazel`に記述されたライブラリの依存関係に基づき、決められたリポジトリから引っ張ってきているだけです。

### Bazel Central Registry

依存ライブラリの置かれている場所はhttps://registry.bazel.build/ という形でBazel公式が提供しています。ちなみにこの中身はhttps://github.com/bazelbuild/bazel-central-registry のmodules/以下に存在します。更にその中身は下図のように、ライブラリリスト→バージョンリスト→コードの参照先、bazel向けパッチリスト等コード情報、として階層構造で保存されています。

![Screenshot from 2024-09-01 22-10-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568499/969a9356-2c87-619a-8b7f-fdd8b112f8c0.png)

Bazelは依存を引っ張ってくるとき、ただ引っ張ってくるだけでなく、レジストリに存在しているパッチも当てるのです。このパッチリストにOpenBSD向けの必要なパッチを追加することさえできれば、ビルドエラーも解消できるはずです。

### レジストリの変更

レジストリへパッチの追加をしなければならない、ということですが、https://github.com/bazelbuild/bazel-central-registryにプルリクを送るのはマージされて使えるようになるまで少々時間がかかってしまいます。
ではどうするか。実はBazelは参照先のレジストリをBazel Central Registryから別のものに変えることができます。

https://bazel.build/external/registry?hl=ja

今回はhttps://github.com/bazelbuild/bazel-central-registry をフォークして、https://github.com/asuka1975/bazel-central-registry にパッチを追加していくようにしました。レジストリの指定については`scripts/bootstrap/bootstrap.sh`にビルドの引数を指定する部分があるのでそちらに`--registry=https://raw.githubusercontent.com/asuka1975/bazel-central-registry/main/`を追加します。

### パッチの追加

パッチは通常のパッチファイルの形式で記述すればよいです。
パッチファイルの置く場所は`modules/<ライブラリ>/<バージョン>/patches/`です。注意点としては、`modules/<ライブラリ>/<バージョン>/source.json`に追加したパッチのチェックサム情報も含めてパッチ情報を追加する必要があります。
チェックサムの計算方法についてはhttps://github.com/bazelbuild/bazel/issues/17124 のイシューが参考になるかと思います。


今回Bazel 7.3.0のビルドのために追加したパッチは以下になります。今後Bazelが対応していないPlatformでビルドする方はご参考にしてください。
https://github.com/bazelbuild/bazel-central-registry/compare/790b36c07b4cad4ea52d67fb249476c628f4ed5c...asuka1975:bazel-central-registry:main

### パッチ追加の反映

前述の作業に加えて、ローカルのビルドキャッシュをクリアする必要があります。方法は簡単で、ルートに存在する`MODULE.bazel.lock`を削除すれば良いです。

## ビルド成功

上記のやり方でOpenBSDにおけるBazelのビルドに成功しました。

![Screenshot_2024-09-01_22-51-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568499/84c0dfb1-6ac3-28f4-1f7a-79dce19d4a1d.png)


# まとめ

今回はOpenBSDにおけるBazel自体のビルドについて扱いました。
基本的には下記３つを行えばほとんどの環境でビルドができるかと思います。

- レジストリのフォーク
- レジストリの変更
- パッチの追加
- ビルドキャッシュの削除と再ビルド


次は本丸のmozcビルドをやっていきましょうかね