Hi everyone! My name is Thanh, I’m working in the Area-Marketing team at RAKSUL.
Raksul’s services are built on several technologies, including Ruby on Rails. Setting up Ruby and Gems is the first step to working with the Rails environment, but it’s not a frequent task. So I have lost so many hours fighting compilers to install Ruby and related gems on macOS Monterey M1. In this post, I will share my experience to help you avoid and fix the issues.
Contents
Detecting macOS CPU architecture
On macOS, two architectures are supported
x86_64
is the architecture of Intel's 64-bit CPUs, aka x64. It was shipped between 2005 and 2021.arm64
is the architecture used by newer Macs built on Apple Silicon, shipped in late 2020.
To know current architecture is the first step before starting to install compatible libraries/tools.
<arm64> % uname -m arm64
<x86_64> % uname -m x86_64
Homebrew
Issue: The current project has an installation script to collect all required tools in one place. Meanwhile, setting up the development environment got an issue with both versions of homebrew installed (arm64 and x86).
How to solve it:
To reinstall Homebrew using the official
method, it will correct the referenced prefix. The below info help you confirm Homebrew on your PC.
Installation
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Homebrew location
<arm64> % which brew /opt/homebrew/bin/brew
<x86_64> % which brew /usr/local/bin/brew
What is the reason that Homebrew has changed the prefix instead of /usr/local
for Macs Apple Silicon?
- The path
/usr/local
is also used by other tools, not only Homebrew. This can make conflict - Homebrew tools might be used by default without configuration to avoid the above issues making an alternate prefix would be easier.
You can find the detail of the Homebrew discussion at here
Tips:
You will do bundle install
later on, knowing the Homebrew prefix and location of tools help you run the correct reference libraries.
Ex: brew info openssl@1.1
The command show detail of the installed library that helps to know the configuration of OpenSSL, such as LDFLAGS
, CPPFLAGS
, and PKG_CONFIG_PATH
etc.,
% brew info openssl@1.1 ==> openssl@1.1: stable 1.1.1q (bottled) [keg-only] Cryptography and SSL/TLS Toolkit https://openssl.org/ /opt/homebrew/Cellar/openssl@1.1/1.1.1q (8,097 files, 18MB) Poured from bottle on 2022-10-04 at 07:33:33 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openssl@1.1.rb License: OpenSSL ==> Dependencies Required: ca-certificates ✔ ==> Caveats A CA file has been bootstrapped using certificates from the system keychain. To add additional certificates, place .pem files in /opt/homebrew/etc/openssl@1.1/certs and run /opt/homebrew/opt/openssl@1.1/bin/c_rehash openssl@1.1 is keg-only, which means it was not symlinked into /opt/homebrew, because macOS provides LibreSSL. If you need to have openssl@1.1 first in your PATH, run: echo 'export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc For compilers to find openssl@1.1 you may need to set: export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib" export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include" For pkg-config to find openssl@1.1 you may need to set: export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@1.1/lib/pkgconfig" ==> Analytics install: 1,158,119 (30 days), 2,567,700 (90 days), 11,370,947 (365 days) install-on-request: 52,608 (30 days), 103,510 (90 days), 418,568 (365 days) build-error: 1,533 (30 days)
Ruby issue
I got the issue when installing ruby 2.6.6
Issue:
% rbenv install 2.6.6 To follow progress, use 'tail -f /var/folders/rd/r2g0jzln74s6t3636gb6m8dh0000gq/T/ruby-build.20221110172716.6727.log' or pass --verbose Downloading ruby-2.6.6.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.bz2 Installing ruby-2.6.6... ruby-build: using readline from homebrew BUILD FAILED (macOS 12.6.1 using ruby-build 20220930) Inspect or clean up the working tree at /var/folders/rd/r2g0jzln74s6t3636gb6m8dh0000gq/T/ruby-build.20221110172716.6727.iLaZEA Results logged to /var/folders/rd/r2g0jzln74s6t3636gb6m8dh0000gq/T/ruby-build.20221110172716.6727.log
How to solve it:
After confirming the logs, disable the warning by set RUBY_CFLAGS="-w" to fix the issue. Also, Github issue solved a similar error with set environment variables.
% RUBY_CFLAGS="-w" rbenv install 2.6.6 To follow progress, use 'tail -f /var/folders/rd/r2g0jzln74s6t3636gb6m8dh0000gq/T/ruby-build.20221110174033.21130.log' or pass --verbose Downloading ruby-2.6.6.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.bz2 Installing ruby-2.6.6... ruby-build: using readline from homebrew Installed ruby-2.6.6 to /Users/XYZ/.rbenv/versions/2.6.6
Tips:
Tip 1
: correct OpenSSL installation
When you install openssl
via brew, let set a specific version for it, otherwise openssl@3
will be installed on Monterey
https://formulae.brew.sh/formula/openssl@1.1
brew install openssl@1.1
https://formulae.brew.sh/formula/openssl@3
brew install openssl@3
Tip 2:
Ruby version required different OpenSSL version
For Ruby versions 2.x ~ 3.0
brew install openssl@1.1 readline libyaml gmp export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)"
For Ruby versions 3.1 ~ above
brew install openssl@3 readline libyaml gmp export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@3)"
Gem issues
Issue 1:
Using gem version still does not support arm64.
Currently, using twirp (1.7.2)
/Users/XYZ/R/github/r/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.5.4/lib/zeitwerk/kernel.rb:35:in `require': cannot load such file -- google/protobuf_c (LoadError)
How to solve it:
Check the gem-released version and upgrade it.
gem 'twirp', '~> 1.9.0'
Issue 2:
OpenSSL didn't match reference environment variables
ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [rubyeventmachine.bundle] Error 1 make failed, exit code 2 Gem files will remain installed in /Users/XYZ/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/eventmachine-1.2.7 for inspection. Results logged to /Users/XYZ/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/extensions/arm64-darwin-21/2.7.0/eventmachine-1.2.7/gem_make.out
How to solve it:
Follow steps to correct environment variables for OpenSSL
- Confirm the installation of openssl
brew info openssl@1.1
- Export environment variables
% export PATH="/opt/homebrew/opt/openssl@1.1/bin:$PATH" // For compilers to find openssl@1.1 % export LDFLAGS="-L/opt/homebrew/opt/openssl@1.1/lib" % export CPPFLAGS="-I/opt/homebrew/opt/openssl@1.1/include" % export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@1.1/lib/pkgconfig"
Or you can add it to the bundle local config
% bundle config --local build.eventmachine --with-openssl-dir=$(brew --prefix openssl@1.1)
3.Runbundle install
Reference
To learn more, refer to the following resources
- Some influential environment variables:
CC C compiler command CFLAGS C or C++ compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CXX C++ compiler command CXXFLAGS C++ compiler flags CPP C preprocessor
Recap
When you are facing installation issues check the environment health, by following the commands
uname -m
: to know your architecturebrew doctor
: confirm the output of brew config- check ruby installation
% ruby -e 'require "rbconfig"; pp RbConfig::CONFIG' | grep "host" "host_os"=>"darwin21", "host_vendor"=>"apple", "host_cpu"=>"arm64", "host"=>"arm64-apple-darwin21", "host_alias"=>"",
- check bundle platform
% bundle platform Your platform is: arm64-darwin21
Should collect the current environment first before executing the commands that you search from google or GitHub issues. Otherwise apply the wrong parameter or environment variables the error is always the same and it seems to have no effect.