0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【devbox×Rails】bundle installで初手エラー!yaml.h not foundの正体はNixの出力システムだった話

0
Posted at

はじめに

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 foundchecking 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.

根本原因

問題の詳細

  1. psych gemの依存関係

    • psych gemはYAMLパーサーのネイティブC拡張
    • ビルドにはyaml.hヘッダーファイル(libyaml)が必須
  2. devboxの自動生成の制限

    • devbox.jsonにlibyaml@latestを指定しても、デフォルトではランタイムライブラリのみがインストールされる
    • ネイティブエクステンションのビルドに必要な**開発用ヘッダーファイル(dev出力)**が含まれない
  3. Nixの出力システム
    Nixパッケージは複数の「出力」を持つ:

    • out(デフォルト): ランタイムライブラリ(.dylibなど)
    • dev: 開発用ヘッダーファイル(.h)とpkg-config設定
    • 通常、devboxはout出力のみをフェッチする

なぜ以前の試みが失敗したか

過去のコミット履歴から、複数の修正が試みられましたが失敗しています:

  • fix:bundle installエラー解消 (2ae6908)
  • fix:devbox.json修正 (ea2a96d)

これらが失敗した理由:

  • devbox.jsonにlibyaml@latestpkg-config@latestを追加しても、dev出力が自動的に選択されない
  • 自動生成された.devbox/gen/flake/flake.nixout出力のみがフェッチされる
  • 結果としてyaml.hヘッダーファイルがビルド環境に存在しない

解決方法

ステップ1: libyamlのdev出力を明示的に追加

以下のコマンドを実行して、libyamlの開発用出力を追加します:

devbox add libyaml@latest -o dev

このコマンドは:

  1. devbox.jsonにlibyaml.devを追加
  2. devbox.lockにlibyaml.devのエントリを作成
  3. 次回の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"
      ]
    }
  }
}

重要なポイント

  1. libyaml.devを明示的に指定: これにより開発用ヘッダーファイルが含まれる
  2. init_hookにハードコードされたパスは不要: devboxが自動的にpkg-configのパスを設定
  3. ポータブル: 他の開発者も同じ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)と共同で作成しました。問題の根本原因の特定から解決策の実装、ドキュメント化までの一連の流れを記録しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?