Rust/GoアプリケーションのAWS Lambda向けクロスビルド方法
概要
前回はPythonのデプロイパッケージのクロスビルドを紹介しました。
今回はRustとGoについて、主にLinux向けのクロスビルド方法をまとめます。
これでAWS Lambda向けの開発がはかどりますね。
Rust
Rustのtoolchainに含まれるコンパイラのrustc自体は様々なターゲット向けにコンパイルすることができますが、linkerを含んでいないのとCに依存したRustのライブラリの時にやはりCのコンパイラが必要になるのでRustのtoolchainだけでは完結しません。Linux向けのクロスビルドの環境を構築する最も簡単な方法はZigを使用することです。といってもZig言語とは全く関係なく、もっぱらZigにCのtoolchainを利用するのがポイントになります。Zigに含まれるzigコマンドはCのコンパイラやリンカーとしても使用でき、さらに様々なターゲット向けのヘッダーファイルも含んでいるのです。
そしてZigをRustのinnkerやCのコンパイラとしてCargoに統合する拡張がcargo-zigbuildです。
クロスビルドの環境構築と実際の手順をまとめると以下の通りになります。
- Rustのtargetを追加する
rustup target add [x86_64|aarch64]-unknown-linux-[gnu|musl]
- Zigを公式サイトからダウンロードしてPATHを通す。
- cargo-zigbuildをGitHubのリリースページからダウンロードしてPATHを通す。
cargo zigbuild --release --target x86_64|aarch64]-unknown-linux-[gnu|musl]
Go
GoはRustとは異なり、toolchain自体にlinkerも含んでいますので大抵は
GOOS=linux GOARCH=[amd64|arm64] go build
で事足りますが、一部のDBのドライバーなど一部のライブラリはCを含んでいてCGO_ENABLED=1
を指定する必要があります。そしてこの時にはCのコンパイラとlinkerが必要になってきます。ここでも最も簡単な方法はZigを利用することです。
上記の記事をまとめますと手順としてはRustの時と同様にZigをインストールし、
CGO_ENABLED=1 GOOS=linux GOARCH=[amd64|arm64] CC='zig cc -target [x86_64|aarch64]-linux-[gnu|musl]' go build
とするだけです。いくつかの記事ではmuslを使用する場合にはさらに-ldflags='-linkmode=external'
が必要と書かれてありますが、私がgo1.25.1で試した限りではおそらくautoになっているのか必要な場合には自動的にlinkmode=externalになってextldにzig cc -target ..
が入っていました。もちろんlinkmode=internal
を明示的に指定するとエラーになります。
Discussion