• All Posts
  • Code
  • Design
  • Process
  • Speaking
  • Poetry
  • About
D.

April 24, 2025 [Solved] Ruby Gems will not build natively on MacOS after upgrading XCode to 16 on Sequoia

Warning: After updating XCode remember to accept or re-accept the End User License Agreement (EULA) so that ruby and other downstream tools can properly locate the active C and C++ build chain install directory.

I had a working ruby-build configuration set up on my M1 MacBook installed and managed by the asdf-ruby asdf plugin. This included a working C and C++ build chain based on the XCode build tools so installing gems that had to build natively using C or C++ generally installed smoothly.

Recently I upgraded my Mac to Sequoia and noticed that XCode needed an update so I updated that as well. I must have missed the roadsign that said “now that you have updated XCode you must accept the new EULA”; this will become important later on.

Tonight I sat down to update some ruby dependencies on a project I haven’t worked with in a while and ran into a gem install failure with eventmachine when it failed to build gem native extensions. This was curious to me as I was certain that previous versions of this gem had installed and built just fine.

❯ gem install eventmachine -v '1.2.7'
Building native extensions. This could take a while...
ERROR:  Error installing eventmachine:
	ERROR: Failed to build gem native extension.

    current directory: ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/eventmachine-1.2.7/ext
~/.asdf/installs/ruby/3.3.4/bin/ruby extconf.rb
checking for pkg-config for openssl... ["-I/opt/homebrew/Cellar/openssl@3/3.4.1/include ", "-L/opt/homebrew/Cellar/openssl@3/3.4.1/lib", "-lssl -lcrypto"]
-----
Using OpenSSL from pkg-config -I/opt/homebrew/Cellar/openssl@3/3.4.1/include  && -L/opt/homebrew/Cellar/openssl@3/3.4.1/lib && -lssl -lcrypto
-----
checking for -lcrypto... yes
checking for -lssl... yes
checking for openssl/ssl.h... yes
checking for openssl/err.h... yes
checking for rb_trap_immediate in ruby.h,rubysig.h... no
checking for rb_thread_blocking_region()... no
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for rb_thread_fd_select()... yes
checking for rb_fdset_t in ruby/intern.h... yes
checking for rb_wait_for_single_fd()... yes
checking for rb_enable_interrupt()... no
checking for rb_time_new()... yes
checking for inotify_init() in sys/inotify.h... no
checking for __NR_inotify_init in sys/syscall.h... no
checking for writev() in sys/uio.h... yes
checking for pipe2() in unistd.h... no
checking for accept4() in sys/socket.h... no
checking for SOCK_CLOEXEC in sys/socket.h... no
checking for sys/event.h... yes
checking for sys/queue.h... yes
checking for clock_gettime()... yes
checking for CLOCK_MONOTONIC_RAW in time.h... yes
checking for CLOCK_MONOTONIC in time.h... yes
CXXFLAGS=-fdeclspec
creating Makefile

current directory: ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/eventmachine-1.2.7/ext
make DESTDIR\= sitearchdir\=./.gem.20250424-42033-rwg762 sitelibdir\=./.gem.20250424-42033-rwg762 clean

current directory: ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/eventmachine-1.2.7/ext
make DESTDIR\= sitearchdir\=./.gem.20250424-42033-rwg762 sitelibdir\=./.gem.20250424-42033-rwg762
compiling binder.cpp
make: *** [binder.o] Error 1

make failed, exit code 2

Gem files will remain installed in ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/eventmachine-1.2.7 for inspection.
Results logged to ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/extensions/arm64-darwin-24/3.3.0/eventmachine-1.2.7/gem_make.out
~/dev/personal/blog main !3 ?5 ❯

I found some blog posts suggesting that I uninstall and reinstall ruby, but after doing so installing gems with native build dependencies continued to fail.

Eventually I discovered the root cause; the reinstalled ruby tools cannot find the updated C++ compiler:

❯ ruby -rrbconfig -e 'puts RbConfig::CONFIG["CC"]'
clang
❯ ruby -rrbconfig -e 'puts RbConfig::CONFIG["CXX"]'
false
❯

That false value for the CXX config setting means that when Ruby was installing it tried to invoke xcode (likey using xcode-select -p) to locate the path to the XCode-installed build tools, including the C++ compiler. In my case that command returned false instead of a valid path to the C++ compiler because I had not yet accepted the EULA for the updated XCode bits.

Solution

  1. Accept the update xcode-license:

     ❯ sudo xcodebuild -license accept
     Password:
     ❯
    
  2. verify that xcode-select -p works properly now:

    ❯ xcode-select -p
    /Applications/Xcode.app/Contents/Developer
    ❯
    
  3. verify the version of XCode:

     ❯ pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
     package-id: com.apple.pkg.CLTools_Executables
     version: 16.3.0.0.1.1742442376
     volume: /
     location: /
     install-time: 1745185641
     ❯
    
  4. uninstall the version of ruby which is broken:

     ❯ asdf uninstall ruby 3.3.4
     ❯ asdf which ruby
     No preset version installed for command ruby
     Please install a version by running one of the following:
        
     asdf install ruby 3.3.4
        
     or add one of the following versions in your config file at ./.tool-versions
     ruby 2.7.6
     ❯
    
  5. reinstall ruby, giving it a chance to find the C++ compiler now that xcode-select -p works properly:

     ❯ asdf install ruby 3.3.4
     ==> Downloading ruby-3.3.4.tar.gz...
     -> curl -q -fL -o ruby-3.3.4.tar.gz https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.4.tar.gz
       % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                      Dload  Upload   Total   Spent    Left  Speed
     100 21.0M  100 21.0M    0     0  18.8M      0  0:00:01  0:00:01 --:--:-- 18.8M
     ==> Installing ruby-3.3.4...
     ruby-build: using libyaml from homebrew
     ruby-build: using gmp from homebrew
     -> ./configure "--prefix=$HOME/.asdf/installs/ruby/3.3.4" --enable-shared --with-libyaml-dir=/opt/homebrew/opt/libyaml --with-gmp-dir=/opt/homebrew/opt/gmp --with-ext=openssl,psych,+ --with-openssl-dir=/opt/homebrew/opt/openssl@1.1
     -> make -j 8
     -> make install
     ==> Installed ruby-3.3.4 to ~/.asdf/installs/ruby/3.3.4
     asdf: Warn: You have configured asdf to preserve downloaded files (with always_keep_download=yes or --keep-download). But
     asdf: Warn: the current plugin (ruby) does not support that. Downloaded files will not be preserved.
     ❯
    
  6. confirm that ruby 3.3.4 found the C++ compiler properly:

     ❯ ruby -rrbconfig -e 'puts RbConfig::CONFIG["CXX"]'
     clang++
     ❯
    
  7. verify that installing a gem which usees C++ to compile native extensions works again:

     ❯ gem install eventmachine -v '1.2.7'
     Fetching eventmachine-1.2.7.gem
     Building native extensions. This could take a while...
     Successfully installed eventmachine-1.2.7
     Parsing documentation for eventmachine-1.2.7
     Installing ri documentation for eventmachine-1.2.7
     Done installing documentation for eventmachine after 2 seconds
     1 gem installed
     ❯
    

Success!


back to top

© David Alpert 2025