protoc-gen-grpc-webをZigでビルドする
https://4.bp.blogspot.com/-j51sNQsrAKM/WASJNj7xjvI/AAAAAAAA_AY/6RcMkjnT_pEM9gUCyuG5dlA-d1FsRxlzQCLcB/s400/lizard_futoagohigetokage.png
はじめに
正式なリリースがまだだが、1.3.2 相当のバージョンがリリースされるタイミングで提供されるものと思われる。
諸事情で先んじてバイナリが必要になったので、自前でビルドすることにした。
Dockerfileを作る
code:Dockerfile
FROM ubuntu:latest as build-env
ENV VERSION=1.3.1-dev
WORKDIR /opt/grpc-web
COPY . /opt/grpc-web/
RUN apt update -qqy && apt install -qqy curl xz-utils
RUN mkdir -p $HOME/.local/bin $HOME/.local/zig \
&& ln -s $HOME/.local/zig/zig $HOME/.local/bin/zig
RUN export PATH=$PATH:$HOME/.local/bin \
&& cd javascript/net/grpc/web/generator \
&& zig build -Drelease-fast
FROM ubuntu:latest
WORKDIR /opt/protoc-gen-grpc-web
COPY --from=build-env /opt/grpc-web/javascript/net/grpc/web/generator/zig-out/bin/protoc-gen-grpc-web-* ./
CMD bash
ビルド対象を確認する
確認時点のリビジョンでは意図的に arm64 のみをビルドするようになっていた。
今回は linux/arm64 に加え、 linux/x86_64 が必要であったためビルド設定を以下のように変更した。
Zig のビルド設定は build.zig によって定義されているので、必要なものに合うように変更した。 https://gyazo.com/16c7343546da49f4ddde438a2837b5c6
ビルドして手元に持ってくる
Dockerfile に閉じ込めた状態でビルドを行う。Zig がクロスコンパイルをしてくれるので、ビルドに使うのは手元のアーキテクチャと合わせたコンテナイメージを元にして良い。 code:sh
# ビルド (※1500秒くらいかかる)
docker build -t grpc-web:debug .
出力結果は以下のようにして取得した。マルチステージビルドを使って、最終的なイメージのWORKDIRにコピーするようにしてあったので、ホストのディレクトリをマウントしてコピーする。
code:sh
# コピー
docker run -it --rm -v $(PWD):/host grpc-web:debug bash -c 'cp -vip ./* /host/'
'./protoc-gen-grpc-web-1.3.1-dev-linux-aarch64' -> '/host/protoc-gen-grpc-web-1.3.1-dev-linux-aarch64'
'./protoc-gen-grpc-web-1.3.1-dev-linux-x86_64' -> '/host/protoc-gen-grpc-web-1.3.1-dev-linux-x86_64'
念の為アーキテクチャをfileコマンドで確認しておく
code:sh
# file ./protoc-gen-grpc-web-1.3.1-*
./protoc-gen-grpc-web-1.3.1-dev-linux-aarch64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped
./protoc-gen-grpc-web-1.3.1-dev-linux-x86_64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
おわりに
g++ で構成されていた元のビルドシステムが上手く動かない中祈るような気持ちで Zig のビルドを通したところうまく行ったので本当に助かった。 C++ で作られたコードに互換性があるというのはこういうときに非常に役に立つ特性だと思ったので Rust と同じく触れる機会を見つけて試していきたいと思った