[Solved] Ruby Gems will not build natively on MacOS after upgrading XCode to 16 on Sequoia
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
-
Accept the update xcode-license:
❯ sudo xcodebuild -license accept Password: ❯
-
verify that
xcode-select -p
works properly now:❯ xcode-select -p /Applications/Xcode.app/Contents/Developer ❯
-
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 ❯
-
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 ❯
-
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. ❯
-
confirm that ruby 3.3.4 found the C++ compiler properly:
❯ ruby -rrbconfig -e 'puts RbConfig::CONFIG["CXX"]' clang++ ❯
-
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!