rustup が "error: linker `cc` not found" で失敗 - Alpine Linux 3.17 (Rust 1.66)

作成
( 更新 )
@nabbisen

はじめに

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

こちらの修正方法について記述します。

環境

  • Alpine Linux 3.17
  • Rust 1.66
  • Rustup 1.25

解決の流れ

* 以下、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-devlibc-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!

Series

Rust on Alpine Linux
  1. rustup が "error: linker `cc` not found" で失敗 - Alpine Linux 3.17 (Rust 1.66)

Comments or feedbacks are welcomed and appreciated.