在 macOS Ventura 13.6 上更新 Cocoapods

问题产生

最近在更新 cocoapods 更新项目的时候,遇到错误:

/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/rbconfig.rb:21: warning: Insecure world writable dir /opt/homebrew in PATH, mode 040777
Ignoring ffi-1.15.5 because its extensions are not built. Try: gem pristine ffi –version 1.15.5

一开始以为是没有写的权限,于是:

sudo chmod go-w /opt/homebrew

再次 pod update 后还是类似的错误,只不过此时:

/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/rbconfig.rb:21: warning: Insecure world writable dir /opt/homebrew/sbin in PATH, mode 040777

再次修改 /opt/homebrew/sbin 的权限后,也还是发生类似的错误。

/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'ffi' (>= 1.15.0) among 85 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/Users/scorpiozj/.gem/ruby/2.6.0:/Library/Ruby/Gems/2.6.0:/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0', execute `gem env` for more information from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/specification.rb:1449:in `block in activate_dependencies'

使用 macOS 自带ruby 重装 cocoapods

面对这种情况,我浅薄的开发经验告诉需要重新安装 cocoapods。于是将源修改为 https://gems.ruby-china.com 进行安装:

sudo gem install cocoapods

经过一段时间的等待后,还是出现了错误:

% pod update
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'ffi' (>= 1.15.0) among 85 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/Users/scorpiozj/.gem/ruby/2.6.0:/Library/Ruby/Gems/2.6.0:/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0', execute `gem env` for more information
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/specification.rb:1449:in `block in activate_dependencies'


Building native extensions. This could take a while...
current directory: /Library/Ruby/Gems/2.6.0/gems/ffi-1.16.3/ext/ffi_c
["/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby", "-I", "/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0", "-r", "./siteconf20240120-5244-79rvz2.rb", "extconf.rb"]
checking for ffi.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
    --with-ffi_c-dir
    --without-ffi_c-dir
    --with-ffi_c-include
    --without-ffi_c-include=${ffi_c-dir}/include
    --with-ffi_c-lib
    --without-ffi_c-lib=${ffi_c-dir}/lib
    --enable-debug
    --disable-debug
    --enable-system-libffi
    --disable-system-libffi
    --with-libffi-config
    --without-libffi-config
    --with-pkg-config
    --without-pkg-config
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1109:in `block in have_header'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1108:in `have_header'
    from extconf.rb:10:in `system_libffi_usable?'
    from extconf.rb:46:in `<main>'
ERROR:  Error installing cocoapods:
    ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/ffi-1.16.3/ext/ffi_c
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20240120-5244-79rvz2.rb extconf.rb
Building has failed. See above output for more information on the failure.
To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-22/2.6.0/ffi-1.16.3/mkmf.log

extconf failed, exit code 1

经过一番搜索,发现是因为 macOS 的安全策略不允许修改系统级的命令。因此,使用系统自带的 ruby 安装 gem 时会失败。
因此,接下来考虑使用 RVM 安装一个新版本的 Ruby。

使用 RVM 安装 Ruby

首先,安装 RVM。 如果网络“正常”的话,可以直接执行:

\curl -sSL https://get.rvm.io | bash -s stable

如果网络不那么“正常”的话,可以使用:

curl -L https://gitee.com/anviod/rvm/blob/master/binscripts/rvm-installer | bash -s stable 

接下来修改源: echo "ruby_url=https://cache.ruby-china.com/pub/ruby" > ~/.rvm/user/db, 然后再安装 Ruby 2.7.0,谁知:

$ rvm install 2.7.8

Searching for binary rubies, this might take some time.
No binary rubies available for: osx/13.6/arm64/ruby-2.7.8.
Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies.
Checking requirements for osx.
Installing requirements for osx.
Updating system - please wait

搜了几个最新的版本,如3.0等,发现都没有适合 OS X 13.6 的版本。想着只是需要用 ruby 安装 cocoapods 而已,安装老版本 Ruby 也未尝不可。于是选择安装 ruby-china 上显示最多人使用的 2.7.0,这个版本倒是可以安装,可还是出错:

% rvm install 2.7.0 --disable-binary                                    
Checking requirements for osx.
Installing requirements for osx.
Updating system - please wait

Failed to update Homebrew, follow instructions at

    https://docs.brew.sh/Common-Issues

and make sure `brew update` works before continuing.
Error running 'requirements_osx_brew_update_system ruby-2.7.0',
please read /Users/xxxxx/.rvm/log/1705754846_ruby-2.7.0/update_system.log
Requirements installation failed with status: 1.

查看日志文件,发现安装过程中会去尝试连接 github.com。而鉴于我的“非正常”网络(虽然已改过host文件),因此安装过程失败。

使用 RBENV 安装 Ruby

这时我发现了还有一个工具,可以安装和管理多个 Ruby,这就是 rbenv。 话不多说,开干:

brew install rbenv

成功安装 rbenv 后,安装ruby:

WARNING: ruby-2.7.0 is past its end of life and is now unsupported.
It no longer receives bug fixes or critical security updates.

ruby-build: using readline from homebrew
ruby-build: using libyaml from homebrew
ruby-build: using gmp from homebrew
-> ./configure "--prefix=$HOME/.rbenv/versions/2.7.0" --with-openssl-dir=/opt/homebrew/opt/openssl@1.1 --enable-shared --with-readline-dir=/opt/homebrew/opt/readline --with-libyaml-dir=/opt/homebrew/opt/libyaml --with-gmp-dir=/opt/homebrew/opt/gmp --with-ext=openssl,psych,+
-> make -j 8

BUILD FAILED (macOS 13.6.1 on arm64 using ruby-build 20240119)

瞬间 emo 了。。。。 鼓起勇气搜索了可用版本:

% rbenv install -l
3.0.6
3.1.4
3.2.3
3.3.0
jruby-9.4.5.0
mruby-3.2.0
picoruby-3.0.0
truffleruby-23.1.2
truffleruby+graalvm-23.1.2

Only latest stable releases for each Ruby implementation are shown.

死马当活马医,试了安装 3.0.6 版, bingo!

==> Installed ruby-3.0.6 to /Users/scorpiozj/.rbenv/versions/3.0.6

NOTE: to activate this Ruby version as the new default, run: rbenv global 3.0.6

这下如释重负,感觉切换到 3.0.6: rbenv global 3.0.6。可是此时系统的 ruby 版本还是 macOS自带的版本:

% ruby --version    
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin22]

这估计是 PATH 有问题,于是在 bashrc 文件下追加内容:

export PATH="$PATH:$HOME/.rbenv/shims"

并执行:

eval "$(rbenv init -)"

接下来选择 3.0.6 版本并检查:

ruby -v
ruby 3.0.6p216 (2023-03-30 revision 23a532679b) [arm64-darwin22]

顺利安装完毕。
接着再安装 cocoapods,并更新过程,完美搞定!!

修改源

过程中还修改了若干源,以解决一些常见的问题,一并记录之。

git -C "$(brew --repo)" remote set-url origin https://mirrors.ustc.edu.cn/brew.git 
git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
git -C "$(brew --repo homebrew/cask)" remote set-url origin https://mirrors.ustc.edu.cn/homebrew-cask.git

echo "ruby_url=https://cache.ruby-china.com/pub/ruby" > ~/.rvm/user/db

Comments