grpc: grpc_c.bundle fails to load on Apple M1 (wrong architecture)

What version of gRPC and what language are you using?

Don’t know.

What operating system (Linux, Windows,…) and version?

MacOS 11.0 on Apple Silicon (M1)

What runtime / compiler are you using (e.g. python version or version of gcc)

ruby 2.7.1

What did you do?

rails db:migrate

but also just

ruby -rgrpc -e"puts 'OK'"

What did you expect to see?

The migration complete successfully

What did you see instead?

LoadError: dlopen(/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/grpc-1.32.0-universal-darwin/src/ruby/lib/grpc/2.7/grpc_c.bundle, 9): no suitable image found.  Did find:
	/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/grpc-1.32.0-universal-darwin/src/ruby/lib/grpc/2.7/grpc_c.bundle: mach-o, but wrong architecture
	/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/grpc-1.32.0-universal-darwin/src/ruby/lib/grpc/2.7/grpc_c.bundle: mach-o, but wrong architecture - /Users/nilleb/.rvm/gems/ruby-2.7.1/gems/grpc-1.32.0-universal-darwin/src/ruby/lib/grpc/2.7/grpc_c.bundle
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4/lib/active_support/dependencies.rb:291:in `block in require'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4/lib/active_support/dependencies.rb:257:in `load_dependency'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4/lib/active_support/dependencies.rb:291:in `require'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/grpc-1.32.0-universal-darwin/src/ruby/lib/grpc/grpc.rb:20:in `<main>'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/Users/nilleb/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'

Anything else we should know about your project / environment?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 40
  • Comments: 46 (4 by maintainers)

Most upvoted comments

@skanev I had the same issue with 1.38.0 too. Here’s what worked for me.

For a Gemfile with:

gem 'google-protobuf', '~> 3.17.0'
gem 'grpc', '~> 1.38.0'

Remove the gems (all versions):

gem uninstall google-protobuf
gem uninstall grpc

Add the ruby platform to the Gemfile.lock and remove the arm64-darwin20 platform:

bundle lock --add-platform ruby
bundle lock --remove-platform arm64-darwin20

Force your platform to be ruby:

bundle config set force_ruby_platform true

Install the gems:

bundle install

If you see Installing grpc 1.38.0 with native extensions and Installing google-protobuf 3.17.0 with native extensions then it worked.

If you see Installing grpc 1.38.0 (universal-darwin) or Installing google-protobuf 3.17.0 (universal-darwin) then it did not work. (and good luck!)

Confirm working with:

bundle exec ruby -rgrpc -e"puts 'OK'"
OK

I’m getting the same issue with 1.38.0, though, sadly.

I got one step closer by following https://github.com/protocolbuffers/protobuf/issues/8199

A bundle pristine install just works, then when running rspec I get the following:

$ bundle exec rspec
dyld: lazy symbol binding failed: Symbol not found: _grpc_set_ssl_roots_override_callback                                     |  ETA: ??:??:??
  Referenced from: /Users/danilo/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/grpc-1.35.0/src/ruby/lib/grpc/grpc_c.bundle
  Expected in: flat namespace

dyld: Symbol not found: _grpc_set_ssl_roots_override_callback
  Referenced from: /Users/danilo/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/grpc-1.35.0/src/ruby/lib/grpc/grpc_c.bundle
  Expected in: flat namespace

zsh: abort      bundle exec rspec

Even though I am using the arm64 architecture now. 🤔

If bundler is still installing universal-darwin when doing as @anothermh has described then try directly using gem install:

gem install grpc --platform=ruby

Is there a way to get this working with Ruby 2.6.6? We’re… currently on this and, uh, it’s problematic to upgrade

This issue cannot be considered resolved by installing Ruby with arch -x86_64 - it is but merely sidestepped.

The current state of events is: as long as you need the grpc gem, you are stuck with x86 Ruby. Which doesn’t sound too bad, but for installing many native gems (like pg) you need to obtain x86 dependencies and configure build scripts to use them. And then help your teammates do the same on their M1 machines. It’s a huge amount of friction for any updates.

I’m seeing it compile with native extensions and still see the dyld errors… any other thoughts?

Installing google-protobuf 3.17.3 with native extensions
Using googleapis-common-protos-types 1.0.6
Fetching grpc 1.38.0
Installing grpc 1.38.0 with native extensions
Using anycable 1.0.3
Using anycable-rails 1.0.7
Bundle complete! 120 Gemfile dependencies, 288 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.


ted>  bundle exec ruby -rgrpc -e"puts 'OK'"                                                               
dyld: lazy symbol binding failed: Symbol not found: _grpc_set_ssl_roots_override_callback
  Referenced from: /Users/ted/.rvm/gems/ruby-2.5.8/gems/grpc-1.38.0/src/ruby/lib/grpc/grpc_c.bundle
  Expected in: flat namespace

dyld: Symbol not found: _grpc_set_ssl_roots_override_callback
  Referenced from: /Users/ted/.rvm/gems/ruby-2.5.8/gems/grpc-1.38.0/src/ruby/lib/grpc/grpc_c.bundle
  Expected in: flat namespace

[1]    16553 abort      bundle exec ruby -rgrpc -e"puts 'OK'"

@ted-hanson I had the same errors and upgrading Ruby from 2.6.5 to 2.7.2 fixed these errors. I see that you are running Ruby 2.5.8 so you could try upgrading to 2.7.2.

I’m seeing it compile with native extensions and still see the dyld errors… any other thoughts?

Installing google-protobuf 3.17.3 with native extensions
Using googleapis-common-protos-types 1.0.6
Fetching grpc 1.38.0
Installing grpc 1.38.0 with native extensions
Using anycable 1.0.3
Using anycable-rails 1.0.7
Bundle complete! 120 Gemfile dependencies, 288 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.


ted>  bundle exec ruby -rgrpc -e"puts 'OK'"                                                               
dyld: lazy symbol binding failed: Symbol not found: _grpc_set_ssl_roots_override_callback
  Referenced from: /Users/ted/.rvm/gems/ruby-2.5.8/gems/grpc-1.38.0/src/ruby/lib/grpc/grpc_c.bundle
  Expected in: flat namespace

dyld: Symbol not found: _grpc_set_ssl_roots_override_callback
  Referenced from: /Users/ted/.rvm/gems/ruby-2.5.8/gems/grpc-1.38.0/src/ruby/lib/grpc/grpc_c.bundle
  Expected in: flat namespace

[1]    16553 abort      bundle exec ruby -rgrpc -e"puts 'OK'"

I compiled the grpc manually and replaced it inside gems, but still getting some strange error. My steps: in project

bundle config set force_ruby_platform true.
bundle

it completes fine and then compile manually grpc.

git clone git@github.com:grpc/grpc.git
git submodule update --init
bundle 
<updated extconf.rb with -arch arm64>
rake 
cp tmp/arm64-darwin20/stage/src/ruby/lib/grpc/grpc_c.bundle /Users/jkonalegi/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/grpc-1.35.0/src/ruby/lib/grpc/grpc_c.bundle

But still getting the following error.

$ bundle exec ruby -rgrpc -e"puts 'OK'"
[1]    15735 killed     bundle exec ruby -rgrpc -e"puts 'OK'"

The same error I get if I download from github actions. Do you have any ideas about what could be wrong?

I was able to follow @nilleb’s instruction with some tweaks. Notably:

  • Added -arch arm64 to ARCH_FLAGS on extconf.rb.
  • Forced native extension complication by setting bundle config set force_ruby_platform true.
  • Not sure if this is needed, but symlinked /opt/homebrew/lib to /opt/local/lib. This helped troubleshooting some other native gem issue on Apple Silicon.

I hooked everything up to self-hosted GitHub Actions runner I own, and was able to build gem and use it without _grpc_set_ssl_roots_override_callback issue reported above. (GitHub Actions workflow)

Or, you can download grpc_c.bundle file and just replace from the already installed gem path.

image

This seems to be broken again in 1.43 😢 . As long as I keep < 1.43, it finds the correct extensions for arm64-darwin-21 platform. Anything >= 1.43 pulls down universal (which will never work).

The easiest and most straightforward way to resolve issues with platforms is to tell bundler to use only ruby platform which will force gems with native extensions to be compiled from scratch:

bundle config set force_ruby_platform true

Your Gemfile.lock should have only one platform:

PLATFORMS
  ruby

You should then remove all installed gems with gem uninstall -aIx and reinstall your bundle with bundle install. Then your gems should compile from scratch and work fine.

@jaredallard have you found a solution? I’m stuck at the same point

This seems to be broken again in 1.43 😢 . As long as I keep < 1.43, it finds the correct extensions for arm64-darwin-21 platform. Anything >= 1.43 pulls down universal (which will never work).

Hi @premist , thank you for looking into that as well as suggesting the PR to maintainers.

I tried following your steps, it also required a xcode-select --install in order to run xcrun, my resulting file still crashed for some unknown reason: zsh: killed bundle exec rspec.

I downloaded the file from Github actions after checking your changes and Apple prevented me from running due to “malicious software”, I did the following to correct:

xattr -l grpc_c.bundle # to see the blocking issue
...
...
com.apple.quarantine: 0083;6027d9ba;Safari;1DC2XXXX-92E0-4235-A927-XXXXXA4207F
xattr -d com.apple.quarantine grpc_c.bundle # to remove the quarantine mark

After that my test suite run successfully for the first time, yay! 🎉

Thank you 🙇

@Vepk17 Take this abusive language somewhere else.

@lidizheng or @veblush could you please remove the above comment? And is it possible to cut a new release of the gem if #25419 addresses Apple Sillicon support adequately? Thank you.

@skanev I had the same issue with 1.38.0 too. Here’s what worked for me.

For a Gemfile with:

gem 'google-protobuf', '~> 3.17.0'
gem 'grpc', '~> 1.38.0'

Remove the gems (all versions):

gem uninstall google-protobuf
gem uninstall grpc

Add the ruby platform to the Gemfile.lock and remove the arm64-darwin20 platform:

bundle lock --add-platform ruby
bundle lock --remove-platform arm64-darwin20

Force your platform to be ruby:

bundle config set force_ruby_platform true

Install the gems:

bundle install

If you see Installing grpc 1.38.0 with native extensions and Installing google-protobuf 3.17.0 with native extensions then it worked.

If you see Installing grpc 1.38.0 (universal-darwin) or Installing google-protobuf 3.17.0 (universal-darwin) then it did not work. (and good luck!)

Confirm working with:

bundle exec ruby -rgrpc -e"puts 'OK'"
OK

Thanks it works for me.

Great news for Ruby 2.6* peeps! It appears that Ruby 2.6.9 works

bundle config set force_ruby_platform true
gem uninstall -aIx
bundle install
# install the missing bundle version they tell you to install
bundle install

(note: i did not need to remove other platforms from my gemfile (just the bundle config ... command above)) cc @pnaponoceno

(THANK YOU @jjworren for figuring this out)

incase anyone still having these issue, i was success runing grpc and google-protobuf in ruby 2.5.7 by installing all required lib such as rbenv, ruby-build by using prefix arch -x86_64 $(command) :

e.g. arch -x86_63 bundle install

notes : make sure u have 2 versions of homebrew installed, and use rbenv from -x86 directory instead.

and this is partial versions of my zshrc :

###### Multiple Homebrew
alias abrew="/opt/homebrew/bin/brew"
alias i="arch -x86_64"
alias ibrew="arch -x86_64 /usr/local/bin/brew"
_ARCH=$(arch)
PROMPT="$_ARCH $PROMPT"
# Requires iterm2
if [[ "$_ARCH" == "i386" ]]; then
 #usr/local is X_86
 alias bundle="arch -x86_64 bundle"
 export PATH="/usr/local/bin:$PATH"
 export PATH="/usr/local/opt:$PATH"
 export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"
fi
if [[ "$_ARCH" == "arm64" ]]; then
 #usr/local is X_86
 # export GEM_HOME=$HOME/.gems
 export PATH=$HOME/.gems/bin:$PATH
 export PATH="/opt/homebrew/bin:$PATH"
 export PATH="/opt/homebrew/opt:$PATH"
 export PATH="/opt/homebrew/opt/curl/bin:$PATH"
 export PATH="/opt/homebrew/opt/imagemagick@6/bin:$PATH"
 export PATH="/opt/homebrew/opt/mysql@5.7/bin:$PATH"
 export LDFLAGS="-L/opt/homebrew/opt/libffi/lib"
 export CPPFLAGS="-I/opt/homebrew/opt/libffi/include"
 export PATH="$(brew --prefix openssl@1.1)/bin:$PATH"
 export PATH="$(brew --prefix postgresql)/bin:$PATH"
 export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(abrew --prefix openssl@1.1)"
 export PKG_CONFIG_PATH="/opt/homebrew/opt/libffi/lib/pkgconfig"
fi


######

eval "$(rbenv init -)"

PS: i was following this tutorial, but instead using abrew, i’m using ibrew and all x86 command instead. https://udnpico.medium.com/install-ruby-di-macbook-pro-m1-a109be60b8aa (its indonesian, but the commands are pretty clear tho)

hope this helps.

@olivierlacan Thanks for reporting this. The new release is on the way, a release candidate will be tagged soon.

@anothermh Thanks for your detailed instructions.

For anyone else running into this problem: The instructions did not work for me with Ruby 3.0.0. It did however work with a clean installation of both Ruby 2.7.2 and 3.0.2.