Upgrading Ruby on a Mac can often be a tricky. I’ve experienced this firsthand. Over the years, I’ve upgraded Ruby numerous times, starting as far back as version 1.8.7. Some went just fine, some brought their own set of challenges, but with persistence and a bit of troubleshooting, I was usually able to make it work.
However, my recent attempt to install Ruby 3.2.2 on an M1 Mac was a different story. Despite my previous experiences, this attempt ended in failure. The problem seemed to stem from my use of RVM (Ruby Version Manager). It appeared that RVM and the MacOs were not playing well together, leading to unexpected complications.
So I tried to install new Ruby just like this, but it ended with error like this.
ak:~ > rvm install 3.2.2 ruby-3.2.2 - #downloading ruby-3.2.2, this may take a while depending on your connection... ruby-3.2.2 - #extracting ruby-3.2.2 to /Users/ak/.rvm/src/ruby-3.2.2 - please wait ruby-3.2.2 - #configuring - please wait ruby-3.2.2 - #post-configuration - please wait ruby-3.2.2 - #compiling - please wait Error running '__rvm_make -j10', please read /Users/ak/.rvm/log/1700152681_ruby-3.2.2/make.log
Determined to find the root cause, I dove into the make.log file. At first glance, the log file’s last few lines did not offer clear insight into the issue. However, upon closer inspection, I found lines indicating problems with OpenSSL:
ossl_ts.c:829:5: error: incomplete definition of type 'struct TS_verify_ctx' TS_VERIFY_CTX_set_certs(ctx, x509inter); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./openssl_missing.h:215:46: note: expanded from macro 'TS_VERIFY_CTX_set_certs' # define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./openssl_missing.h:195:52: note: expanded from macro 'TS_VERIFY_CTS_set_certs' # define TS_VERIFY_CTS_set_certs(ctx, crts) ((ctx)->certs=(crts)) ~~~~~^ /opt/homebrew/Cellar/openssl@3/3.1.2/include/openssl/ts.h:407:16: note: forward declaration of 'struct TS_verify_ctx' typedef struct TS_verify_ctx TS_VERIFY_CTX;
Who would have thought OpenSSL and Ruby. I challenge you to name more iconic duo.
Solutions that failed miserably
- Updating OpenSSL: Tried updating OpenSSL to fix the issue, but it didn’t work.
- Reinstalling and Linking OpenSSL: Reinstalled and linked OpenSSL, but the problem persisted.
- Updating Xcode Command Line Tools: Some GitHub issue suggest trying this and someone reported it worked. So I tried, but it had no effect on the Ruby installation issue.
- Tried setting environment variables to direct the installation process:
This step also failed to resolve the problem.
export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix firstname.lastname@example.org)"
- Attempted various RVM configuration options to change the compilation process, but none of these efforts were successful.
The Solution That Worked: Switching to rbenv
After several unsuccessful attempts with different methods, I tried one last solution:
Removing RVM: First, I completely removed RVM using the following command:
Installing rbenv and ruby-build:
Then, I installed
ruby-build using Homebrew:
brew install rbenv brew install ruby-build
Installing Ruby 3.2.2 with rbenv:
Finally, I used
rbenv to install Ruby 3.2.2:
rbenv install 3.2.2
The installation process worked flawlessly this time:
ak:~ > rbenv install 3.2.2 ruby-build: using openssl@3 from homebrew ... ==> Installed ruby-3.2.2 to /Users/ak/.rbenv/versions/3.2.2
Why It Worked
The key to success was how
rbenv configured the Ruby compilation. At first it identified the OpenSSL installed on my machine and the used this information in the
-> ./configure "--prefix=$HOME/.rbenv/versions/3.2.2" --with-openssl-dir=/opt/homebrew/opt/openssl@3 ...
Switching to rbenv
This experience led me to switch from RVM to rbenv, a change long recommended by my colleagues. The ability of rbenv to correctly configure Ruby compilation on an M1 Mac made it the right choice for me. Hopefuly this was the last time I had to google anything on configuring Ruby to use appropriate OpenSSL. So long RVM!