ld: symbol(s) not found for architecture x86_64
“ld: symbol(s) not found for architecture x86_64” or “ld: symbol(s) not found for architecture arm64” are common errors people get on Apple Silicon Macs when installing Ruby itself, or when installing Ruby gems with
bundle install or
The three main reasons for these errors are:
- Installing things with and without Rosetta (mixing and matching the arm64 and x86_64 architectures)
- Installing outdated gems that don’t work on Apple Silicon
- Using installation options like
cppflagswithout understanding their effect
x86_64 vs arm64 (with and without Rosetta)
Apple Silicon Macs use the
arm64 architecture, which is not compatible with the
x86_64 architecture that would be used if you enable Rosetta, or run commands with
arch -x86_64, or if you try to install gems or other tools that were built for the
You can’t mix and match architectures. For example, if you install Homebrew while using Rosetta or with
arch -x86_64, it will install things under
/usr/local. However, when installing Homebrew in native mode, it will be installed under
If you install a Ruby version manager (such as asdf, chruby, frum, rbenv, rvm) and Ruby in native mode (arm64), you can’t install a gem with
arch -x86_64 or pass in installation options that point to
/usr/local (x86_64). You either have to do everything in native mode with the
arm64 architecture (highly recommended), or do everything with the
x86_64 architecture (not recommended).
If you don’t know what you’re doing, installing development tools with and without Rosetta (or with and without
arch -x86_64) can lead to lots of issues, such as “ld: symbol(s) not found for architecture x86_64”. To be sure you have a clean dev environment, I recommend completely removing all dev tools and starting over with a clean slate. At a minimum, remove everything that was installed with Rosetta and in
Completely cleaning up your dev setup can take up to 60 steps that take 60 minutes to run manually. If you don’t feel like spending an hour or more cleaning things up, or if you’re not sure what all the steps are, you can buy Ruby on Mac, which comes with a “reset” mode that will safely back up your dev setup, then clean everything up in 1 minute. And then you can run it in “normal” mode to reinstall everything from scratch in native mode (arm64).
Using outdated gems that are not compatible with Apple Silicon
Another very common issue people run into on Apple Silicon Macs is not being able to install gems in existing projects that have old versions of gems. For example, if you try to run
bundle install in a Ruby project that has version 0.5.3 of
mysql2 listed in the
Gemfile.lock, then it will fail because that version was released before the M1 Macs came out.
Most gems, tools, Mac apps, and other things you can install on a Mac had to be updated to work natively on Apple Silicon Macs. So, if a gem fails to install, the most common reason is because it’s an older version that doesn’t work on Apple Silicon. In most cases, there’s a newer version that does work on Apple Silicon, so the solution is simple: update the gem! For example:
bundle update mysql2
bundle install again, and if you get other installation failures, keep updating the gems that are failing to install.
Using Ruby installation flags like ldflags and cppflags
Over the past 11 years, I’ve helped hundreds of thousands of people set up a proper Ruby environment on their Mac. One thing I see often is people adding environment variables to their shell startup file, like
CPPFLAGS, or installing gems with
--with-cppflags. They do this blindly without understanding what these options do, and then are surprised when things go wrong.
I can assure you that when you have a proper Ruby dev setup, like the one Ruby on Mac sets up for you, none of these options are necessary in 2023 on any Mac, whether Intel or Apple Silicon.
Setting environment variables like
CPPFLAGS in your shell startup file is especially problematic because it will affect any tool that uses those variables, not just Ruby-related tools. If you know what you’re doing and you know you need to set those flags to a particular value, it should only be done on the command line at the same time as installing a particular tool. They should never be set globally in your shell startup file.