How to running CocoaPods on Apple Silicon (M1)
I have a Flutter project that I'm trying to run on iOS. It runs normally on my Intel-based Mac, but on my new Apple Silicon-based M1 Mac it fails to install pods.
LoadError - dlsym(0x7f8926035eb0, Init_ffi_c): symbol not found - /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi.rb:6:in `rescue in <top (required)>'
/Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/lib/ffi.rb:3:in `<top (required)>'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/Library/Ruby/Gems/2.6.0/gems/ethon-0.12.0/lib/ethon.rb:2:in `<top (required)>'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/Library/Ruby/Gems/2.6.0/gems/typhoeus-1.4.0/lib/typhoeus.rb:2:in `<top (required)>'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/sources_manager.rb:74:in `cdn_url?'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/sources_manager.rb:36:in `create_source_with_url'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/sources_manager.rb:21:in `find_or_create_source_with_url'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer/analyzer.rb:178:in `block in sources'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer/analyzer.rb:177:in `map'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer/analyzer.rb:177:in `sources'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer/analyzer.rb:1073:in `block in resolve_dependencies'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/user_interface.rb:64:in `section'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer/analyzer.rb:1072:in `resolve_dependencies'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer/analyzer.rb:124:in `analyze'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer.rb:414:in `analyze'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer.rb:239:in `block in resolve_dependencies'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/user_interface.rb:64:in `section'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer.rb:238:in `resolve_dependencies'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/installer.rb:160:in `install!'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/command/install.rb:52:in `run'
/Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:334:in `run'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/command.rb:52:in `run'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/bin/pod:55:in `<top (required)>'
/usr/local/bin/pod:23:in `load'
/usr/local/bin/pod:23:in `<main>'
Based on a Github workaround, I tried to run Terminal using rosetta, but the issue remains the same: https://github.com/CocoaPods/CocoaPods/issues/9907#issuecomment-655870749
Realising it's still early for Macs with Apple Silicon. Is there a way to make this work for the time being?
Still working in January 2022
#1 Install ffi
sudo arch -x86_64 gem install ffi
#2 Re-install dependencies
arch -x86_64 pod install
Additional Information
#1 For anyone seeing the arch: posix_spawnp: gem: Bad CPU type in executable
error, you must first install Rosetta. Thanks, @Jack Dewhurst
#2 If you run pod
commands pretty often, setting up an alias in .zshrc
or .bash_profile
might be handy. Thanks, @theMoonlitKnight for the suggestion.
alias pod='arch -x86_64 pod'
EDIT: I recently disabled Rosetta, and Cocoapods runs just fine with the addition of the ffi gem.
For anyone else struggling with this issue, I just found a way to solve it. In addition to running terminal in Rosetta:
- Right-click on Terminal in Finder
- Get Info
- Open with Rosetta
I installed a gem that seems to be related to the symbol not found in the error:
sudo gem install ffi
After doing this, cocoapods runs as expected.
TL;DR:
- Install your own version of Ruby with Homebrew / rbenv / RVM (e.g.
brew install ruby
) - Add it and the gems binaries to your
PATH
and make sure the new version is used withwhich ruby
(should be/opt/homebrew/opt/ruby/bin/ruby
instead of/usr/bin/ruby
if installed with Homebrew) - Install CocoaPods with
sudo gem install cocoapods
(make sureethon
is at least version 0.13.0) - Run
pod install
Detailed answer:
All answers suggesting using Rosetta / arch -x86_64
are workarounds and not quite solving the real issue that comes from the way RbConfig and the universal binaries work.
require 'rbconfig'
OSVERSION = RbConfig::CONFIG['host_os']
ARCH = RbConfig::CONFIG['arch']
HOSTCPU = RbConfig::CONFIG['host_cpu']
BUILDCPU = RbConfig::CONFIG['build_cpu']
TARGETCPU = RbConfig::CONFIG['target_cpu']
puts "OS: #{OSVERSION}"
puts "Arch: #{ARCH}"
puts "Host CPU: #{HOSTCPU}"
puts "Build CPU: #{BUILDCPU}"
puts "Target CPU: #{TARGETCPU}"
If you call ruby
on a file containing this code with the universal binary shipped with macOS, you will get the following result on an M1 Mac:
OS: darwin20
Arch: universal-darwin20
Host CPU: x86_64
Build CPU: x86_64
Target CPU: universal
As you can see, RbConfig was compiled for a « universal » CPU but built with an x86 CPU, and the rbconfig.rb
file that was generated (see /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin20/rbconfig.rb
) consequently uses invalid information for the host CPU.
As ffi
uses information from RbConfig (see https://github.com/ffi/ffi/blob/dfae59e293974efaa7b4d414e5116d7a2187a06e/lib/ffi/platform.rb#L61 and https://github.com/ffi/ffi/blob/e3f2cf9b82055709ddbeecbf77810f43438c4b64/spec/ffi/fixtures/compile.rb#L11), we end up with OP’s error message.
The solution is, therefore, to get a version of Ruby built specifically for arm64 by using either Homebrew, rbenv or RVM.
For Homebrew:
- Execute
brew install ruby
- Add
export PATH=/opt/homebrew/opt/ruby/bin:/opt/homebrew/lib/ruby/gems/3.0.0/bin:$PATH
to your.zshrc
(you can find your Homebrew installation directory with$(brew --prefix)
if needed) - Execute
source ~/.zshrc
or restart your shell - Make sure you are using the correct
ruby
binary by executingwhich ruby
(should be$(brew --prefix)/opt/ruby/bin/ruby
) - Install CocoaPods with
sudo gem install cocoapods
- Make sure you are using the correct
pod
binary by executingwhich pod
(should be$(brew --prefix)/lib/ruby/gems/3.0.0/bin/pod
) - Make sure
ethon
is version 0.13.0 or more withgem info ethon
, otherwise runsudo gem install ethon
- Run
pod install
Ruby won't come with future macOS versions by default
Moreover, it should be noted that ruby
is still included in macOS only « for compatibility with legacy software », as evidenced by running irb -v
, so this is probably a good opportunity to install your own version anyway:
WARNING: This version of ruby is included in macOS for compatibility with legacy software. In future versions of macOS the ruby runtime will not be available by default and may require you to install an additional package.
irb 1.0.0 (2018-12-18)
Sources:
- https://betterprogramming.pub/ruby-on-apple-silicon-m1-macs-fb159849b2f5
- https://github.com/ffi/ffi/issues/870
To install completely cocoapods on Mac with M1 chip (Apple Silicon), please follow these steps:
- Duplicate the Terminal application in the Utilities folder.
- Right-click on the app and choose to Get Info.
- Rename the other version of the app as you like.
- Check the option "open with Rosetta".
- Install Cocoapods with the command "sudo gem install cocoapods"
- Type the command line "gem install ffi" to fix the ffi bundle problem. Now you can do a "pod install" without a problem.
Source : iPhoneSoft
An alternative to running Terminal in Rosetta 2 is to set the architecture with arch -x86_64
, as in the following:
arch -x86_64 sudo gem install cocoapods -n /usr/local/bin
To give credit where it is due, I found this solution here
MacPorts bug tracker, issue #61545, comment 7