EarthlyでRaspberryPi向けにビルドする
RaspberryPi向けのビルドとなると依存管理とかが面倒なのでmuslを使いたい。 GNU libcの方がパフォーマンス良いと言ってもRaspberyPiならパフォーマンスとか関係ないし。
ただhyper
とかtokio::net
とか使おうとするとopenssl
やらring
やら(muslでビルドしようとするとaarch64-linux-musl-gcc
を要求される)が引っ付いてきて、
cross
では荷が重く、ローカルに構築するには依存が増えてローカルが汚染される。
Dockerのbuildx
でマルチアーキなビルドが出来ることを利用してクロスコンパイルすると楽だが、やや目的外な雰囲気がある。
Earthly はmake
+ Docker
といったソフトウェアで、Makefile
っぽくDockerイメージのビルドを書ける上、
バイナリのコンパイルのようなDockerだとやや無理矢理感のある事も自然に書ける。VSCode向けのExtension もある。
サンプルはこんな感じ。ほとんど公式サイトに載ってるexampleそのまんま。
Rustをビルドする時はからのmain.rs
を作成してビルドしてからソースコードを運んできてビルドすることで依存を毎回ビルドするのをスキップ出来る。
ここではreqwest
にdefault-features=false, features=["rustls-webpki-roots"]
を使ってopenssl
とca-certificates
への依存を追い出しているが、DockerなのでOpenSSLを持って来ればnative-tls
でのビルドも簡単。
FROM
文でaarch64
向けのイメージのDigestを指定してクロスコンパイルさせている。この例だとバイナリをそのまま出しているが、
大抵の場合はここからDockerイメージをビルドするだろう。
VERSION 0.6
FROM rust:latest@sha256:97fa23369c500e6b41bf9091b4af614e6728498c81a0c1717c73480085eefb9e
WORKDIR /work
all:
BUILD +build
build:
RUN mkdir src
RUN echo "fn main(){}" > src/main.rs
COPY Cargo.toml .
COPY Cargo.lock .
RUN apt-get update && apt-get install -y musl-dev musl-tools
RUN ln -sf $(which musl-gcc) /usr/local/bin/aarch64-linux-musl-gcc
RUN rustup target install aarch64-unknown-linux-musl
RUN cargo build --release --target=aarch64-unknown-linux-musl
COPY src src
RUN cargo build --release --target=aarch64-unknown-linux-musl
SAVE ARTIFACT target/aarch64-unknown-linux-musl/release/something-awesome AS LOCAL something-awesome