Fix: Failed to Build Gem Native Extension When Installing CocoaPods

Fix: Failed to Build Gem Native Extension When Installing CocoaPods

Written by

in

Quick answer: This error occurs when the Ruby gem installer cannot find a working C compiler or the proper macOS SDK headers to build gems like xcodeproj or ffi. Fix it by running xcode-select --install to install the Xcode Command Line Tools, or bypass Ruby compilation issues entirely by installing CocoaPods directly through Homebrew via brew install cocoapods.

Why this happens

When you run gem install cocoapods, Ruby compiles native C extensions for critical dependencies such as ffi and xcodeproj. To compile these extensions, the mkmf builder needs an active C compiler toolchain (clang), header files, and the macOS developer SDK.

If the Xcode Command Line Tools are missing, incomplete, or pointed to a broken path, the configuration step fails with:

ERROR: Failed to build gem native extension.
... The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.

This error also frequently occurs when using the system Ruby preinstalled with macOS (located in /usr/bin/ruby) or an unmanaged version manager environment. macOS restricts system directories via System Integrity Protection (SIP), and system Ruby often lacks the compiler configuration flags required to locate modern Apple SDK headers.


How to fix it

1. Install CocoaPods via Homebrew (Recommended)

The most reliable way to run CocoaPods on modern macOS installations is through Homebrew. Homebrew packages CocoaPods inside its own isolated Ruby runtime, avoiding system Ruby conflicts, permission errors, and manual extension compilation.

First, make sure Homebrew is up to date and clean up any broken references:

brew update
brew cleanup

Next, install CocoaPods:

brew install cocoapods

If the installation finishes but the pod command is not recognized, link the binary to your shell path:

brew link --overwrite cocoapods

Verify that CocoaPods works:

pod --version

2. Install or Reset Xcode Command Line Tools

If you prefer using gem install cocoapods or work within a project that requires a Gemfile, your environment must have an active, valid C compiler.

Open Terminal and trigger the developer tools installer:

xcode-select --install

A software update dialog will appear. Click Install and wait for the download to complete.

If the tools are already installed but you have full Xcode installed, ensure your active developer directory points to Xcode’s toolchain rather than an orphaned path:

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

Accept the Xcode license agreement, which can silently block command-line compilation:

sudo xcodebuild -license accept

After completing these steps, attempt to install the gem again:

sudo gem install cocoapods

3. Install an Independent Ruby Version with Homebrew

If you must use RubyGems directly, do not use the macOS system Ruby. Install a modern Ruby release via Homebrew so your gems install cleanly without sudo and with complete build headers.

  1. Install Ruby via Homebrew:
brew install ruby
  1. Add the Homebrew Ruby path to your shell profile. On modern macOS systems using Zsh, edit ~/.zshrc (or ~/.bash_profile if you use Bash):

On Apple Silicon Macs (M1/M2/M3/M4):

echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc
echo 'export LDFLAGS="-L/opt/homebrew/opt/ruby/lib"' >> ~/.zshrc
echo 'export CPPFLAGS="-I/opt/homebrew/opt/ruby/include"' >> ~/.zshrc

On Intel Macs:

echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc
echo 'export LDFLAGS="-L/usr/local/opt/ruby/lib"' >> ~/.zshrc
echo 'export CPPFLAGS="-I/usr/local/opt/ruby/include"' >> ~/.zshrc
  1. Reload your shell configuration:
source ~/.zshrc
  1. Confirm that which ruby points to Homebrew rather than /usr/bin/ruby:
which ruby
  1. Install CocoaPods into your user-managed Ruby environment:
gem install cocoapods

4. Manually Build Native Dependencies with Architecture Flags

On Apple Silicon machines running custom Ruby versions (such as via rbenv or rvm), gems like ffi sometimes fail to build if the compiler attempts to build for an unintended CPU slice.

You can pass architecture-specific flags directly to RubyGems to force a clean build against your current architecture:

arch -arm64 gem install ffi -- --enable-libffi-alloc
gem install cocoapods

If you are operating inside an Intel-translated terminal under Rosetta 2, match the target architecture explicitly:

arch -x86_64 sudo gem install cocoapods

How to prevent it

  • Migrate to Swift Package Manager (SPM): Where possible, adopt SPM instead of CocoaPods. SPM is built directly into Xcode and eliminates external Ruby runtime dependencies.
  • Do not modify system Ruby: Never run sudo gem update --system against /usr/bin/ruby. Apple updates or system security policies can break native extension compilation without warning.
  • Use Bundler for teams: If your project relies on CocoaPods, commit a Gemfile and use bundle install. Manage Ruby versions using .ruby-version through rbenv or asdf to ensure identical build flags across all developer machines.
  • Keep Command Line Tools synchronized: Re-run xcode-select --install whenever you upgrade to a major macOS release, as major OS updates often purge /Library/Developer/CommandLineTools.

FAQ

Why does gem install cocoapods require compiling C code?

CocoaPods relies on gems like ffi (Foreign Function Interface) and xcodeproj to interface with system libraries and parse Xcode project files. These gems include native C code that must be compiled specifically for your Mac’s CPU architecture during the installation process.

Should I use sudo when installing CocoaPods?

If you are using Homebrew (brew install cocoapods) or a user-managed Ruby (rbenv or Homebrew Ruby), you should never use sudo. sudo is only required when attempting to write directly to root-owned directories used by system Ruby, which is generally discouraged.

What if I get a permission denied error after fixing the compiler?

This occurs when trying to write gems to protected system paths like /Library/Ruby/Gems/. Avoid this by installing CocoaPods with Homebrew or by targeting your user directory using gem install --user-install cocoapods and adding $(ruby -e 'print Gem.user_dir')/bin to your PATH.

Sources & credits

Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.