🐶
【Rails/Docker CE】CMake を Docker にインストールする【Gem::Ext::BuildError】
WSL docker CE(Ubuntu 22.04) で Rails 開発環境を構築しています。
ある gem を Gemfile に追記し、bundle install
を実行したところ、Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
というエラーが発生してインストールを完了することができませんでした。
原因の調査と対応を残しておきます。
該当のエラーメッセージ
$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
-----中略-----
Fetching h3 3.7.2 <- 該当の gem
Installing h3 3.7.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native
extension.
-----中略-----
cd src; cmake . -DBUILD_SHARED_LIBS=true -DBUILD_FILTERS=OFF
-DBUILD_BENCHMARKS=OFF; make
/bin/sh: 1: cmake: not found
make[1]: Entering directory
'/usr/local/bundle/gems/h3-3.7.2/ext/h3/src'
make[1]: *** No targets specified and no makefile found. Stop.
make[1]: Leaving directory
'/usr/local/bundle/gems/h3-3.7.2/ext/h3/src'
make: *** [Makefile:2: make] Error 2
make failed, exit code 2
要約
- 追加しようとした gem は、ネイティブ拡張を用いて C 言語や C++ などで作成されたライブラリを利用するものだった
- 作成した環境に、それらをビルドするための CMake がインストールされていなかった
- dockerfile に CMake をインストールするためのコマンドを追記し、再ビルドしたところ
bundle install
に成功した
経緯
- h3 という地理空間を扱うための gem の install を試みた
-
bundle install
に失敗し、冒頭のエラーメッセージに遭遇
Gem::Ext::BuildError: と cmake not found
冒頭のエラーメッセージの、Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
と cmake: not found
という部分に着目しました
前半で、ネイティブ拡張のビルドに失敗したこととその理由が、後半で、CMake がインストールされていないことによるものであるためであると類推することができます
実際に、h3_ruby
のリポジトリを確認すると、README.md
を確認すると C言語で構築されたライブラリに ffi を用いてアクセスしている旨が記されています。
This gem uses FFI to link directly into the H3 library (written in C).
CMake を install する
開発環境に CMake を導入するために、dockerfile に追記を行いました
また、バージョンはこちらで確認しました
RUN apt-get update && \
apt-get -y install build-essential && \
apt-get install -y wget && \
wget https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1-linux-x86_64.sh -q -O /tmp/cmake-install.sh && \
chmod u+x /tmp/cmake-install.sh && \
mkdir /opt/cmake-3.28.1 && \
/tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-3.28.1 && \
rm /tmp/cmake-install.sh && \
ln -s /opt/cmake-3.28.1/bin/* usr/local/bin
再ビルドして bundle install
$ docker compose build --no-cache
$ docker compose up -d
$ docker compose exec [コンテナ] /bin/bash
$ bash: # bundle install
-> Bundle complete! xx Gemfile dependencies, xx gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
参考
Discussion