RTF(M|L): Error Installing Ruby 3.3.1 via asdf on MacOS Due to Missing libyaml#

This is the first in a rapid-fire series of howto posts regarding MacOS development environments and common blockers people face when setting them up. It should also serve as your daily reminder to Read the Freaking Manual|Logs[1]! As for Ruby, I needed to set up Ruby 3.3.1 for a new customer engagement. As usual, I started setting it up via asdf-vm; see 🪄 Install asdf: One Runtime Manager to Rule All Dev Environments for the reasoning behind doing so and my view on language runtime management.

Addendum#

psych : Could not be configured. It will not be installed#

After adding asdf’s ruby plugin, I proceed with installing 3.3.1:

1$ asdf plugin add ruby
2updating plugin repository...HEAD is now at 8e311ee feat: add dynatrace-monaco plugin (#951)

Quickly, however, I was stopped dead on my tracks by the Ruby’s build process failing:

 1$ asdf install ruby 3.3.1
 2Downloading ruby-build...
 3ruby-build: using openssl@3 from homebrew
 4==> Downloading ruby-3.3.1.tar.gz...
 5-> curl -q -fL -o ruby-3.3.1.tar.gz https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.1.tar.gz
 6  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 7                                 Dload  Upload   Total   Spent    Left  Speed
 8100 21.0M  100 21.0M    0     0  24.6M      0 --:--:-- --:--:-- --:--:-- 24.5M
 9==> Installing ruby-3.3.1...
10ruby-build: using gmp from homebrew
11-> ./configure "--prefix=$HOME/.asdf/installs/ruby/3.3.1" --with-openssl-dir=/opt/homebrew/opt/openssl@3 --enable-shared --with-gmp-dir=/opt/homebrew/opt/gmp --with-ext=openssl,psych,+
12-> make -j 10
13*** Following extensions are not compiled:
14psych:
15	Could not be configured. It will not be installed.
16	Check /var/folders/3b/pfbk11px0wdf2r5vmvzmbv5c0000gn/T/ruby-build.20240527105321.99261.u0bywS/ruby-3.3.1/ext/psych/mkmf.log for more details.
17
18BUILD FAILED (macOS 14.5 on arm64 using ruby-build 20240517)
19
20You can inspect the build directory at /var/folders/3b/pfbk11px0wdf2r5vmvzmbv5c0000gn/T/ruby-build.20240527105321.99261.u0bywS
21See the full build log at /var/folders/3b/pfbk11px0wdf2r5vmvzmbv5c0000gn/T/ruby-build.20240527105321.99261.log

The error is somewhat cryptic, as the failing configuration and build process shown is for the psych Ruby gem:

https://rubygems.org/gems/psych isn’t very explicit about libyaml needing to be installed separtely, but the keen observer might have already noticed that.

In contrast, https://libraries.io/maven/rubygems:psych does embed the project’s[2] README.md and lists libyaml as a dependency.

Read the Freaking Logs(RTFL)#

In hindsight, reading the actual build logs beyond the immediate reported errors would have been more expedient:

 1$ cat cat /var/folders/3b/pfbk11px0wdf2r5vmvzmbv5c0000gn/T/ruby-build.20240527105321.99261.log
 2
 3DYLD_LIBRARY_PATH=.:../.. "clang -I../../.ext/include/arm64-darwin23 -I../.././include -I../.././ext/psych -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   -fdeclspec -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wmisleading-indentation -Wundef -fno-common -pipe -arch arm64  -c conftest.c"
 4conftest.c:3:10: fatal error: 'yaml.h' file not found
 5#include <yaml.h>
 6         ^~~~~~~~
 71 error generated.
 8checked program was:
 9/* begin */
101: #include "ruby.h"
112: 
123: #include <yaml.h>
13/* end */

The above makes it clear asdf’s build process for Ruby has failed due to yaml.h being missing.

Ruby’s libyaml Dependency#

Ruby’s official documentation on contributing[3] makes it clear libyaml is a required dependency:

Installing via Homebrew#

Those installing Ruby via homebrew will not face these issues, since libyaml is included as a dependency in ruby’s formula [4]:

[...]
  "build_dependencies": [
    "autoconf",
    "pkg-config",
    "rust"
  ],
  "dependencies": [
    "libyaml",
    "openssl@3"
  ],
  "test_dependencies": [],
  "recommended_dependencies": [],
  "optional_dependencies": [],
  "uses_from_macos": [
    "gperf",
    "libffi",
    "libxcrypt",
    "zlib"
  ],
[...]

Solution#

Likely obvious by now, resolving the issue being discussed is one Homebrew formula away:

 1$ brew install libyaml 
 2==> Downloading https://formulae.brew.sh/api/formula.jws.json
 3############################################################################################################################################################################################################################################## 100.0%
 4==> Downloading https://formulae.brew.sh/api/cask.jws.json
 5############################################################################################################################################################################################################################################## 100.0%
 6==> Downloading https://ghcr.io/v2/homebrew/core/libyaml/manifests/0.2.5
 7[...]
 8==> Pouring libyaml--0.2.5.arm64_sonoma.bottle.tar.gz
 9🍺  /opt/homebrew/Cellar/libyaml/0.2.5: 11 files, 354.9KB
10==> Running `brew cleanup libyaml`...
11Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
12Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
13$ 

With that, we can proceed to install Ruby 3.3.1 via asdf:

 1$ asdf install ruby 3.3.1
 2ruby-build: using openssl@3 from homebrew
 3==> Downloading ruby-3.3.1.tar.gz...
 4-> curl -q -fL -o ruby-3.3.1.tar.gz https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.1.tar.gz
 5  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 6                                 Dload  Upload   Total   Spent    Left  Speed
 7100 21.0M  100 21.0M    0     0  38.1M      0 --:--:-- --:--:-- --:--:-- 38.2M
 8==> Installing ruby-3.3.1...
 9ruby-build: using libyaml from homebrew
10ruby-build: using gmp from homebrew
11-> ./configure "--prefix=$HOME/.asdf/installs/ruby/3.3.1" --with-openssl-dir=/opt/homebrew/opt/openssl@3 --enable-shared --with-libyaml-dir=/opt/homebrew/opt/libyaml --with-gmp-dir=/opt/homebrew/opt/gmp --with-ext=openssl,psych,+
12-> make -j 10
13-> make install
14==> Installed ruby-3.3.1 

Which works as expected:

1$ asdf global ruby 3.3.1
2
3$ ruby -e 'puts "Hello, World!"'
4Hello, World!

Final Words#

Quick and easy; hope this post has helped those of you who might be new to the MacOs ecosystem, Ruby, asdf or simply needed to be reminded that build logs are, indeed, sometimes useful.

Stay in touch by entering your email below and receive updates whenever I post something new:

As always, thank you for reading and remember that feedback is welcome and appreciated; you may contact me via email or social media. Let me know if there's anything else you'd like to know, something you'd like to have corrected, translated, added or clarified further.

Footnotes#