[Solved] You have to install development tools first.
While updating my Jekyll site to use the latest supported toolset (i.e. jekyll 3.10.0 and ruby 3.3.4) I encountered an odd error scenario while using bundler
to install the site’s gems.
For the last year or so I have used asdf
which simplifies managing multiple versions of ruby on a single machine but can complicate troubleshooting install paths and build failures when building gem native extnsions.
In my case I was able to successfully install ruby 3.3.4
on MacOS Sequoia 15.4.1 on an Apple M1 from 2020, only to run into the following error while running bundle install
in my site directory:
❯ asdf which ruby
~/.asdf/installs/ruby/3.3.4/bin/ruby
❯ bundle instalFetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Using rake 13.2.1
Using base64 0.2.0
Using benchmark 0.4.0
Using bigdecimal 3.1.9
Using bundler 2.3.7
Using connection_pool 2.5.1
Fetching coffee-script-source 1.11.1
Using execjs 2.10.0
Using minitest 5.25.5
Using securerandom 0.4.1
Fetching public_suffix 4.0.7
Using concurrent-ruby 1.3.5
Using drb 2.2.1
Fetching eventmachine 1.2.7
Using http_parser.rb 0.8.0
Using commonmarker 0.23.11
Using simpleidn 0.2.3
Using logger 1.6.6
Using colorator 1.1.0
Using forwardable-extended 2.6.0
Using front_matter_parser 1.0.1
Using gemoji 3.0.1
Using ffi 1.17.2 (arm64-darwin)
Using rexml 3.4.1
Using json 2.10.2
Using mercenary 0.3.6
Fetching rouge 3.26.0
Using liquid 4.0.4
Using rb-fsevent 0.11.2
Using mini_portile2 2.8.8
Using racc 1.8.1
Using jekyll-paginate 1.1.0
Using rubyzip 2.4.1
Using jekyll-swiss 1.0.0
Using unicode-display_width 1.8.0
Using uri 1.0.3
Using jekyll-pagination 0.0.4
Using io-console 0.8.0
Using i18n 1.14.7
Using rainbow 3.1.1
Using jekyll-commonmark 1.4.0
Using tzinfo 2.0.6
Using pathutil 0.16.2
Using ethon 0.16.0
Using rb-inotify 0.11.1
Fetching kramdown 2.3.2
Using safe_yaml 1.0.5
Using dnsruby 1.72.4
Using terminal-table 1.8.0
Using nokogiri 1.18.7 (arm64-darwin)
Using net-http 0.6.0
Using reline 0.6.1
Fetching activesupport 7.2.2.1
Using sass-listen 4.0.0
Using typhoeus 1.4.1
Using listen 3.9.0
Using faraday-net_http 3.4.0
Using highline 3.1.2
Using sass 3.7.4
Using jekyll-watch 2.2.1
Using faraday 2.13.0
Using jekyll-sass-converter 1.5.2
Installing eventmachine 1.2.7 with native extensions
Installing public_suffix 4.0.7
Installing kramdown 2.3.2
Using addressable 2.8.7
Using sawyer 0.9.2
Using octokit 4.25.1
Fetching github-pages-health-check 1.17.9
Using jekyll-gist 1.5.0
Installing coffee-script-source 1.11.1
Using coffee-script 2.4.1
Fetching jekyll-coffeescript 1.1.1
Installing activesupport 7.2.2.1
Installing rouge 3.26.0
Installing jekyll-coffeescript 1.1.1
Using html-pipeline 2.14.3
Installing github-pages-health-check 1.17.9
Using kramdown-parser-gfm 1.1.0l
...
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/json-2.11.2/ext/json/ext/generator
~/.asdf/installs/ruby/3.3.4/bin/ruby extconf.rb
checking for whether -std=c99 is accepted as CFLAGS... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include=${opt-dir}/include
--without-opt-include
--with-opt-lib=${opt-dir}/lib
--without-opt-lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=~/.asdf/installs/ruby/3.3.4/bin/$(RUBY_BASE_NAME)
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:480:in `try_do': The compiler failed to generate an executable file.
(RuntimeError)
You have to install development tools first.
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:606:in `block in try_compile'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:553:in `with_werror'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:606:in `try_compile'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:670:in `try_cflags'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1019:in `block (2 levels) in append_cflags'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:983:in `block in checking_for'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:344:in `block (2 levels) in postpone'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:314:in `open'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:344:in `block in postpone'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:314:in `open'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:340:in `postpone'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:982:in `checking_for'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1018:in `block in append_cflags'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1017:in `each'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1017:in `append_cflags'
from extconf.rb:7:in `<main>'
To see why this extension failed to compile, please check the mkmf.log which can be found here:
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/extensions/arm64-darwin-24/3.3.0/json-2.11.2/mkmf.log
extconf failed, exit code 1
Gem files will remain installed in ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/json-2.11.2 for inspection.
Results logged to ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/extensions/arm64-darwin-24/3.3.0/json-2.11.2/gem_make.out
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/ext/builder.rb:125:in `run'
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/ext/ext_conf_builder.rb:28:in `build'
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/ext/builder.rb:193:in `build_extension'
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/ext/builder.rb:227:in `block in build_extensions'
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `each'
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `build_extensions'
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/rubygems/installer.rb:852:in `build_extensions'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/rubygems_gem_installer.rb:71:in
`build_extensions'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/rubygems_gem_installer.rb:28:in `install'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/source/rubygems.rb:204:in `install'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/installer/gem_installer.rb:54:in `install'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/installer/gem_installer.rb:16:in
`install_from_spec'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/installer/parallel_installer.rb:186:in
`do_install'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/installer/parallel_installer.rb:177:in `block
in worker_pool'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/worker.rb:62:in `apply_func'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/worker.rb:57:in `block in process_queue'
<internal:kernel>:187:in `loop'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/worker.rb:54:in `process_queue'
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/bundler-2.3.7/lib/bundler/worker.rb:91:in `block (2 levels) in
create_threads'
An error occurred while installing json (2.11.2), and Bundler cannot continue.
In Gemfile:
github-pages was resolved to 232, which depends on
github-pages-health-check was resolved to 1.18.2, which depends on
octokit was resolved to 4.25.1, which depends on
sawyer was resolved to 0.9.2, which depends on
faraday was resolved to 2.13.0, which depends on
json
The important part there seemed to be this line
You have to install development tools first.
And yet when I ran the command to ensure that xcode build tools was installed the system told me that the tools were already installed:
❯ sudo xcode-select --install
xcode-select: note: Command line tools are already installed. Use "Software Update" in System Settings or the softwareupdate command line interface to install updates
Strange.
I tried reshimming asdf
but that didn’t help
❯ asdf reshim
But the gem still failed to install
❯ gem install json -v 2.11.2
Building native extensions. This could take a while...
ERROR: Error installing json:
ERROR: Failed to build gem native extension.
current directory: ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/json-2.11.2/ext/json/ext/generator
~/.asdf/installs/ruby/3.3.4/bin/ruby extconf.rb
checking for whether -std=c99 is accepted as CFLAGS... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include=${opt-dir}/include
--without-opt-include
--with-opt-lib=${opt-dir}/lib
--without-opt-lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=~/.asdf/installs/ruby/3.3.4/bin/$(RUBY_BASE_NAME)
~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:480:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:606:in `block in try_compile'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:553:in `with_werror'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:606:in `try_compile'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:670:in `try_cflags'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1019:in `block (2 levels) in append_cflags'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:983:in `block in checking_for'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:344:in `block (2 levels) in postpone'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:314:in `open'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:344:in `block in postpone'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:314:in `open'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:340:in `postpone'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:982:in `checking_for'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1018:in `block in append_cflags'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1017:in `each'
from ~/.asdf/installs/ruby/3.3.4/lib/ruby/3.3.0/mkmf.rb:1017:in `append_cflags'
from extconf.rb:7:in `<main>'
To see why this extension failed to compile, please check the mkmf.log which can be found here:
~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/extensions/arm64-darwin-24/3.3.0/json-2.11.2/mkmf.log
extconf failed, exit code 1
Gem files will remain installed in ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/json-2.11.2 for inspection.
Results logged to ~/.asdf/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/extensions/arm64-darwin-24/3.3.0/json-2.11.2/gem_make.out
Again with the misleading error
You have to install development tools first.
The Solution
In the end, with help from a comment on a github issue in the asdf-ruby
repo (#323 asdf-ruby on macOS 12.6 Apple Silicon with rb 3.1.3 fails with install latest), I figured out that while xcode was installed I had not yet accepted the license:
❯ brew install openssl@3 readline libyaml gmp
Error: You have not agreed to the Xcode license. Please resolve this by running:
sudo xcodebuild -license accept
With hindsight I can see how a failure to accept the license might render the build tools unavailable or otherwise throw an error when invoked, and then be “read” as a signal that the tools were unavailable. From there, it’s a small leap to understand why the error might say “you have to install” things instead of the more helpful “you have installed Xcode but not yet agreed to the license.
In any case, after accepting the license
❯ sudo xcodebuild -license accept
Password:
❯
I was able to successfully build native extensions again:
❯ gem install json -v 2.11.2
Building native extensions. This could take a while...
Successfully installed json-2.11.2
Parsing documentation for json-2.11.2
Installing ri documentation for json-2.11.2
Done installing documentation for json after 1 seconds
1 gem installed
❯
❯ gem install eventmachine -v '1.2.7' -- --with-ldflags="-Wl,-undefined,dynamic_lookup0,--prefix=\"$(asdf which ruby)\",--with-gmp-dir=\"$(brew --prefix gmp)\",--with-libyaml-dir=\"$(brew --prefix libyaml)\",--with-openssl-dir=\"$(brew --prefix openssl)\",--with-readline-dir=\"$(brew --prefix readline)\",--with-zlib-dir=\"$(brew --prefix zlib)\",--with-opt-dir=\"$(brew --prefix jemalloc)\",--with-jemalloc"