はじめに
devboxでRails 8.1環境を構築中、bundle installでpsych gemのビルドに失敗しました。エラーはyaml.h not found。
結論
# これで解決!
devbox add libyaml@latest -o dev
devbox.jsonにlibyaml@latestを追加しても、デフォルトではランタイムライブラリのみがインストールされます。ネイティブエクステンションのビルドには開発用ヘッダーファイル(dev出力) が必要で、これを明示的に指定する必要がありました。
対象読者
- devboxでRuby/Rails環境を構築している方
-
yaml.h not foundやchecking for yaml.h... noエラーに遭遇した方 - ネイティブエクステンションを持つgemのビルドに失敗している方
- Nixの出力システムについて理解を深めたい方
検証環境
- OS: macOS 14.x (Darwin 24.5.0) on Apple Silicon (ARM64)
- devbox: 0.16.0
- Ruby: 3.4.8
- Rails: 8.1.1
- psych gem: 5.3.1
- libyaml: 0.2.5
問題の症状
Rails 8.1プロジェクトでbundle installを実行すると、psych gemのネイティブエクステンションビルドに失敗する。
エラーメッセージ
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
checking for yaml.h... no
yaml.h not found
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.
An error occurred while installing psych (5.3.1), and Bundler cannot continue.
根本原因
問題の詳細
-
psych gemの依存関係
- psych gemはYAMLパーサーのネイティブC拡張
- ビルドには
yaml.hヘッダーファイル(libyaml)が必須
-
devboxの自動生成の制限
- devbox.jsonに
libyaml@latestを指定しても、デフォルトではランタイムライブラリのみがインストールされる - ネイティブエクステンションのビルドに必要な**開発用ヘッダーファイル(dev出力)**が含まれない
- devbox.jsonに
-
Nixの出力システム
Nixパッケージは複数の「出力」を持つ:-
out(デフォルト): ランタイムライブラリ(.dylibなど) -
dev: 開発用ヘッダーファイル(.h)とpkg-config設定 - 通常、devboxは
out出力のみをフェッチする
-
なぜ以前の試みが失敗したか
過去のコミット履歴から、複数の修正が試みられましたが失敗しています:
-
fix:bundle installエラー解消(2ae6908) -
fix:devbox.json修正(ea2a96d)
これらが失敗した理由:
- devbox.jsonに
libyaml@latestやpkg-config@latestを追加しても、dev出力が自動的に選択されない - 自動生成された
.devbox/gen/flake/flake.nixでout出力のみがフェッチされる - 結果として
yaml.hヘッダーファイルがビルド環境に存在しない
解決方法
ステップ1: libyamlのdev出力を明示的に追加
以下のコマンドを実行して、libyamlの開発用出力を追加します:
devbox add libyaml@latest -o dev
このコマンドは:
- devbox.jsonに
libyaml.devを追加 - devbox.lockに
libyaml.devのエントリを作成 - 次回の
devbox shell起動時に開発用ヘッダーファイルをダウンロード
ステップ2: devbox shellを再起動
exit # 既存のdevbox shellを終了
devbox shell # 新しい環境で再起動
ステップ3: 動作確認
pkg-configがlibyamlを正しく検出できるか確認:
# libyamlが見つかるか確認
pkg-config --exists yaml-0.1 && echo "Found" || echo "Not found"
# ヘッダーファイルのパスを確認
pkg-config --cflags yaml-0.1
# ライブラリのパスを確認
pkg-config --libs yaml-0.1
期待される出力:
Found
-I/nix/store/.../libyaml-0.2.5-dev/include
-L/nix/store/.../libyaml-0.2.5/lib -lyaml
ステップ4: bundle installを実行
bundle install
ステップ5: psych gemが正しくビルドされたか確認
bundle exec ruby -e "require 'psych'; puts Psych::LIBYAML_VERSION"
libyamlのバージョン(0.2.5)が表示されれば成功です。
最終的なdevbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json",
"packages": [
"ruby@3.4",
"nodejs@24",
"yarn@latest",
"bundler@latest",
"postgresql@17",
"pkg-config@latest",
"libyaml.dev"
],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"dev": [
"./bin/dev"
]
}
}
}
重要なポイント
-
libyaml.devを明示的に指定: これにより開発用ヘッダーファイルが含まれる - init_hookにハードコードされたパスは不要: devboxが自動的にpkg-configのパスを設定
-
ポータブル: 他の開発者も同じdevbox.jsonを使用すれば、
devbox shellを実行するだけで同じ環境が構築される
トラブルシューティング
エラーが継続する場合
既存のビルド成果物をクリーンアップ:
rm -rf .devbox/virtenv/ruby/extensions/arm64-darwin-24/3.4.0/psych-5.3.1
bundle install
環境変数を確認
devbox shellで以下を実行して、環境が正しく設定されているか確認:
echo $PKG_CONFIG_PATH
# /nix/store/.../libyaml-0.2.5-dev/lib/pkgconfig が含まれているはず
参考情報
devbox addコマンドのオプション
devboxでは、dev出力を追加する方法が2つあります:
方法1: -o フラグを使用(推奨)
devbox add <package>@<version> -o <output>
# 例
devbox add libyaml@latest -o dev # dev出力を追加
devbox add nodejs@24 -o out,dev # 複数の出力を指定
方法2: ドット記法を使用
devbox add <package>.<output>
# 例
devbox add libyaml.dev # dev出力を追加
devbox add libxml2.dev libxslt.dev # 複数のパッケージを同時に追加
どちらの書き方でも同じ結果が得られます。ドット記法の方が短く書けるため、複数のパッケージを追加する際は便利です。
Nixパッケージの出力について
Nixパッケージは複数の出力を持つことができ、用途に応じて分離されています:
-
out: デフォルト出力(ランタイムバイナリ、ライブラリ) -
dev: 開発用ヘッダーファイル、pkg-config設定 -
doc: ドキュメント -
man: マニュアルページ
開発環境では、ネイティブエクステンションをビルドする場合、dev出力が必要です。
まとめ
devboxでRuby/Railsプロジェクトを構築する際、ネイティブエクステンションを持つgemは**開発用ヘッダーファイル(dev出力)**が必要です。devbox add <package> -o devコマンドを使用することで、ポータブルかつメンテナンス性の高い解決策を実現できます。
同様の問題は、以下のgemでも発生する可能性があります:
-
nokogiri(libxml2, libxslt) -
mysql2(mysql-client) -
pg(postgresql) -
sqlite3(sqlite)
これらのgemを使用する場合も、同じアプローチで対応できます:
# nokogiri用(-o フラグを使用)
devbox add libxml2@latest -o dev
devbox add libxslt@latest -o dev
# または、ドット記法で短く書く
devbox add libxml2.dev libxslt.dev
# mysql2用
devbox add mysql-client.dev
# pg用
devbox add postgresql.dev
# sqlite3用
devbox add sqlite.dev
devbox楽そうだけどちょこちょこ詰まって大変devねぇ...
この記事は、実際に発生したエラーの調査・解決プロセスをもとに、AI(Claude)と共同で作成しました。問題の根本原因の特定から解決策の実装、ドキュメント化までの一連の流れを記録しています。