はじめに
Alpine Linux では Rustup が パッケージ として提供されています。Rust もあります。
Docker で Alpine Linux 上に Rust の開発環境を構築しました。
そしてその過程においてですが、以下のようなエラーが発生しました。cargo プロジェクトを試験的に動かした時のことです:
$ cargo run
出力は以下の通りでした:
Compiling alpine-rust-example v0.1.0 (/(...)/alpine-rust-example)
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: could not compile `alpine-rust-example` due to previous error
こちらの修正方法について記述します。
環境
解決の流れ
* 以下、doas
の代わりに sudo
を使っても大丈夫です。
Docker コンテナの起動
Dockerfile 例:
FROM alpine:3.17
# ports published
EXPOSE 80
EXPOSE 443
# packages base
RUN apk update --no-cache
RUN apk upgrade --no-cache
RUN apk add --no-cache openrc
# rust
RUN apk add --no-cache rustup
# [ init system - activate OpenRC ]
ENTRYPOINT ["/sbin/init"]
Docker コマンド例:
$ # Dockerfile のあるディレクトリでビルド
$ docker build .
$ # image id 取得
$ docker image ls
$ # コンテナ起動
$ docker start $IMAGE_ID
$ # container id 取得
$ docker container ls
$ # vm 操作
$ docker exec -it $CONTAINER_ID sh
Rust を Rustup でインストール
$ doas apk add rustup
出力は以下の通りでした:
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz
(1/6) Installing ca-certificates (20220614-r3)
(2/6) Installing brotli-libs (1.0.9-r9)
(3/6) Installing nghttp2-libs (1.51.0-r0)
(4/6) Installing libcurl (7.87.0-r0)
(5/6) Installing libgcc (12.2.1_git20220924-r4)
(6/6) Installing rustup (1.25.1-r0)
Executing busybox-1.35.0-r29.trigger
Executing ca-certificates-20220614-r3.trigger
OK: 18 MiB in 24 packages
続いてこちらを実行します:
$ rustup-init
以下のようにたずねられるでしょう。デフォルトの選択肢のままで進んで OK です:
Welcome to Rust!
This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.
Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:
/(...)/.rustup
This can be modified with the RUSTUP_HOME environment variable.
The Cargo home directory is located at:
/(...)/.cargo
This can be modified with the CARGO_HOME environment variable.
The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:
/(...)/.cargo/bin
This path will then be added to your PATH environment variable by
modifying the profile file located at:
/(...)/.profile
You can uninstall at any time with rustup self uninstall and
these changes will be reverted.
Current installation options:
default host triple: x86_64-unknown-linux-musl
default toolchain: stable (default)
profile: default
modify PATH variable: yes
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>
出力は以下の通りでした:
info: profile set to 'default'
info: default host triple is x86_64-unknown-linux-musl
info: syncing channel updates for 'stable-x86_64-unknown-linux-musl'
info: latest update on 2022-12-15, rust version 1.66.0 (69f9c33d7 2022-12-12)
info: downloading component 'cargo'
(...)
info: downloading component 'clippy'
(...)
info: downloading component 'rust-docs'
(...)
info: downloading component 'rust-std'
(...)
info: downloading component 'rustc'
(...)
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
(...)
info: installing component 'rust-std'
(...)
info: installing component 'rustc'
(...)
info: installing component 'rustfmt'
info: default toolchain set to 'stable-x86_64-unknown-linux-musl'
stable-x86_64-unknown-linux-musl installed - rustc 1.66.0 (69f9c33d7 2022-12-12)
Rust is installed now. Great!
To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).
To configure your current shell, run:
source "$HOME/.cargo/env"
最後に以下を実行して $PATH
を更新します:
$ source "$HOME/.cargo/env"
これで Rust の環境ができました :)
cargo プロジェクトを作成 (そしてその後にビルドで失敗)
サンプルプロジェクトをつくりましょう:
$ cargo new alpine-rust-example
出力は以下の通りでした:
Created binary (application) `alpine-rust-example` package
中に入ります:
$ cd alpine-rust-example
そこで実行します:
$ cargo run
以下の通り失敗するはずです:
Compiling alpine-rust-example v0.1.0 (/(...)/alpine-rust-example)
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: could not compile `alpine-rust-example` due to previous error
修正
build-base
パッケージをインストールすればエラーは解消します:
# apk add build-base
# #apk add gcc # 別の方法 (非推奨)
出力は以下の通りでした:
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz
(1/19) Installing libstdc++ (12.2.1_git20220924-r4)
(2/19) Installing binutils (2.39-r2)
(3/19) Installing libmagic (5.43-r0)
(4/19) Installing file (5.43-r0)
(5/19) Installing libgomp (12.2.1_git20220924-r4)
(6/19) Installing libatomic (12.2.1_git20220924-r4)
(7/19) Installing gmp (6.2.1-r2)
(8/19) Installing isl25 (0.25-r0)
(9/19) Installing mpfr4 (4.1.0-r0)
(10/19) Installing mpc1 (1.2.1-r1)
(11/19) Installing gcc (12.2.1_git20220924-r4)
(12/19) Installing libstdc++-dev (12.2.1_git20220924-r4)
(13/19) Installing musl-dev (1.2.3-r4)
(14/19) Installing libc-dev (0.7.2-r3)
(15/19) Installing g++ (12.2.1_git20220924-r4)
(16/19) Installing make (4.3-r1)
(17/19) Installing fortify-headers (1.1-r1)
(18/19) Installing patch (2.7.6-r8)
(19/19) Installing build-base (0.5-r3)
Executing busybox-1.35.0-r29.trigger
OK: 254 MiB in 43 packages
備考: なぜ gcc
では無く build-base
を使うのか
最小限のインストールにとどめるのであれば gcc
で十分なはずです。これは build-base
の一要素です。
gcc
だけでも本記事の問題ならば解決できるでしょう。
しかしながら gcc
だけをインストールするというのは、推奨されていません。というのも musl-dev
と libc-dev
のいずれかが、きっとすぐに追加で必要になるからです。
一例ですが、Actix Web というアクターモデルを採用している Rust の Web フレームワークがあります。こちらのサーバーを立てようとする時などは build-base
が必要になります。
おわりに
それでは cargo run
(あるいは cargo build
) を再度実行してみましょう:
# cargo run
先ほどよりも良いことが訪れるのでは無いでしょうか :)
Compiling alpine-rust-example v0.1.0 (/(...)/alpine-rust-example)
Finished dev [unoptimized + debuginfo] target(s) in 0.15s
Running `target/debug/alpine-rust-example`
Hello, world!