Installing ruby with ruby-install causes error out on Mac M1

Viewed 5648

When installing ruby 2.6.6 or 2.7.2 using ruby-install on mac M1, the following error occurs. Ruby 3.0.0 works fine however anything older will error out with readline and not allow ruby to install.

readline.c:1905:37: error: use of undeclared identifier 'username_completion_function'; did you mean 'rl_username_completion_function'?
                                    rl_username_completion_function);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    rl_username_completion_function
readline.c:79:42: note: expanded from macro 'rl_username_completion_function'
# define rl_username_completion_function username_completion_function
                                         ^
/opt/homebrew/opt/readline/include/readline/readline.h:485:14: note: 'rl_username_completion_function' declared here
extern char *rl_username_completion_function PARAMS((const char *, int));
3 Answers

I finally got the older versions of ruby installed, including 2.6.6, on the m1 chip macbook pro with the following steps:

First, I had to reinstall rbenv, ruby-build and readline with:

brew reinstall rbenv ruby-build readline

Second, using CONFIGURE_OPTS was breaking my OpenSSL build. Use RUBY_CONFIGURE_OPTS instead. I was using hombrew and had to use the following flags:

RUBY_CONFIGURE_OPTS="--with-openssl-dir=`brew --prefix openssl` --with-readline-dir=`brew --prefix readline`"

Third, set the following to allow warnings in the make commands to not halt the build:

RUBY_CFLAGS="-Wno-error=implicit-function-declaration"

Fourth, ensure you set the arch flag when installing via rbenv:

arch -x86_84

Fifth, ensure your homebrew paths are correctly set:

export PATH="/opt/homebrew/bin:$PATH"
export PATH="/opt/homebrew/opt:$PATH"

The final command that successfully installed ruby 2.6.6 was:

export PATH="/opt/homebrew/bin:$PATH"
export PATH="/opt/homebrew/opt:$PATH"
RUBY_CFLAGS="-Wno-error=implicit-function-declaration" RUBY_CONFIGURE_OPTS="--with-openssl-dir=`brew --prefix openssl` --with-readline-dir=`brew --prefix readline`" sudo arch -x86_64 rbenv install --verbose 2.6.6

I used sudo to give mkdir permissions to the scripts.

I have been able to install both as x86_64 code and 3.0.1 as arm64 code. I use rvm but this should work with other things.

  1. I use iTerm2 and have made 2 copies. One I used Get Info to change one application to use Rosetta. Somewhere I even found a blue icon for the x86 app.

enter image description here

  1. I have 2 versions of Homebrew. One in /opt/homebrew/bin/brew and the other in /usr/local/bin/brew.

  2. I have 2 sets of exports in my .zshrc profile. I use the architecture to select the correct ones for the shell.

alias abrew="/opt/homebrew/bin/brew"

alias i="arch -x86_64"
alias ibrew="arch -x86_64  /usr/local/bin/brew"
alias irvm="arch -x86_64 rvm"

# Add RVM to PATH for scripting. Make sure this is the last PATH variable change.
export PATH="$PATH:$HOME/.rvm/bin"

_ARCH=$(arch)
PROMPT="$_ARCH $PROMPT"

# Requires iterm2
if [[ "$_ARCH" == "i386" ]]; then
  echo -ne "\033]1337;SetColors=bg=000FC5\007"
  #usr/local is X_86
  export PATH="/usr/local/bin:$PATH"
  export PATH="/usr/local/opt:$PATH"
fi

if [[ "$_ARCH" == "arm64" ]]; then
  #usr/local is X_86
  export PATH="/opt/homebrew/bin:$PATH"
  export PATH="/opt/homebrew/opt:$PATH"
fi

With this I can compile 2.6.6 (and I presume 2.7.2) in the x86 shell and separately 3.0.1 in the arm64 shell.

My rvm list looks like:

   ruby-2.4.6 [ x86_64 ]
   ruby-2.4.9 [ x86_64 ]
 * ruby-2.6.5 [ x86_64 ]
   ruby-2.6.6 [ x86_64 ]
   ruby-2.7.0 [ x86_64 ]
   ruby-2.7.2 [ x86_64 ]
=> ruby-3.0.1 [ arm64 ]

PS I still have trouble sometimes getting rails to link correctly to mysql. ruby / rails / mysql seem to all have to be the same architecture. Still chasing that one down.

This worked for me:

❯ arch -x86_64 rvm install 3.1.2 --with-openssl-dir=/usr/local/opt/openssl@3

So I had to specify the architecture (arch -x86_64) and a version of openssl under /usr/local/opt. In my case I already had a couple of versions of openssl installed there, I just picked the latest I had. In other cases you may have to download and compile it yourself

Related