
Installing EventMachine Gem from Source on Apple Silicon Macs
EventMachine is a popular Ruby gem that provides event-driven I/O using the Reactor pattern. While it’s typically installed via a simple gem install eventmachine
, Apple Silicon (M1/M2) Mac users often encounter compilation issues when installing from source. This guide walks through the common problems and provides a detailed solution.
Apple Silicon Macs use ARM64 architecture, which requires specific compiler configurations for native extensions. EventMachine’s native extensions were originally written with x86 architectures in mind, and its build system needs adjustments for proper ARM64 compilation.
Common Installation Failure
When attempting to install EventMachine from source on an M1/M2 Mac, you might encounter this error:
➜ git clone https://github.com/eventmachine/eventmachine.git
➜ cd eventmachine
➜ gem build eventmachine.gemspec && \
ARCHFLAGS="-arch arm64" \
gem install eventmachine-1.2.7.gem -- \
--with-openssl-dir=$(brew --prefix openssl@3)
This typically fails with:
ERROR: Failed to build gem native extension.
extconf.rb:3:in `require_relative': cannot load such file -- [...]/em_config (LoadError)
And even if you get past this error, you might hit another one in the fastfilereader extension:
compiling mapper.cpp
make: *** [mapper.o] Error 1
The issues stem from two main factors:
- The main EventMachine extension needs proper C++ compiler configuration for ARM64
- The FastFileReader sub-extension also requires similar ARM64-specific settings
- The default compiler flags aren’t compatible with Apple’s ARM64 architecture
The Solution
1. Modify the Main Extension Configuration
First, edit ext/extconf.rb
with these contents:
require 'fileutils'
require 'mkmf'
# Configure compiler for ARM64 Mac directly in extconf.rb
if RUBY_PLATFORM =~ /darwin/
CONFIG['CXX'] = 'clang++'
CONFIG['CC'] = 'clang'
# Set proper include paths for C++
sdk_path = `xcrun --show-sdk-path`.chomp
cxx_include = "#{sdk_path}/usr/include/c++/v1"
$CXXFLAGS = " -std=c++11 -stdlib=libc++ -I#{cxx_include}"
$LDFLAGS << " -stdlib=libc++"
# Reset any problematic flags
RbConfig::CONFIG['CXXFLAGS'] = RbConfig::CONFIG['CXXFLAGS'].to_s.gsub(/-fdeclspec/, '')
CONFIG['CXXFLAGS'] = CONFIG['CXXFLAGS'].to_s.gsub(/-fdeclspec/, '')
end
2. Modify the FastFileReader Extension
Then, edit ext/fastfilereader/extconf.rb
:
require 'mkmf'
# Configure compiler for ARM64 Mac
if RUBY_PLATFORM =~ /darwin/
CONFIG['CXX'] = 'clang++'
CONFIG['CC'] = 'clang'
# Set proper include paths for C++
sdk_path = `xcrun --show-sdk-path`.chomp
cxx_include = "#{sdk_path}/usr/include/c++/v1"
$CXXFLAGS = " -std=c++11 -stdlib=libc++ -I#{cxx_include}"
$LDFLAGS << " -stdlib=libc++"
# Reset any problematic flags
RbConfig::CONFIG['CXXFLAGS'] = RbConfig::CONFIG['CXXFLAGS'].to_s.gsub(/-fdeclspec/, '')
CONFIG['CXXFLAGS'] = CONFIG['CXXFLAGS'].to_s.gsub(/-fdeclspec/, '')
end
dir_config("fastfilereader")
# Force g++ instead of gcc for linking
if CONFIG['CXX'] == 'g++'
CONFIG['LDSHARED'] = "$(CXX) -shared"
CONFIG['LDSHAREDXX'] = "$(CXX) -shared"
end
have_func('rb_thread_blocking_region')
have_func('rb_thread_call_without_gvl')
create_makefile("fastfilereader")
3. Install the Modified Gem
Now you can install the gem with:
gem build eventmachine.gemspec && \
ARCHFLAGS="-arch arm64" \
gem install eventmachine-1.2.7.gem -- \
--with-openssl-dir=$(brew --prefix openssl@3)
What Changed and Why It Works
The key modifications we made:
- Compiler Selection: We explicitly set
clang++
as the C++ compiler, which is optimized for Apple Silicon. - C++ Standard: We specify C++11 standard with
-std=c++11
. - Standard Library: We use
libc++
instead oflibstdc++
with-stdlib=libc++
. - Include Paths: We properly set up C++ include paths using the Mac SDK.
- Flag Cleanup: We remove problematic flags that could interfere with compilation.
These changes ensure that:
- The code compiles with the correct ARM64 architecture settings
- The proper C++ standard library is used
- All necessary headers are found
- The linking process uses the correct flags
Requirements
- macOS on Apple Silicon (M1/M2)
- Homebrew installed
- OpenSSL installed via Homebrew (
brew install openssl@3
) - Ruby installed (preferably via rbenv or RVM)
- Xcode Command Line Tools installed
Troubleshooting Tips
If you still encounter issues:
- Ensure Xcode Command Line Tools are installed:
xcode-select --install
- Verify OpenSSL installation:
brew info openssl@3
- Check your Ruby installation:
ruby -v
- Make sure all changes to extconf.rb files are saved properly
While installing EventMachine from source on Apple Silicon Macs requires some additional configuration, the process becomes straightforward once you understand the necessary compiler settings. The modifications we’ve made ensure proper compilation of both native extensions while maintaining compatibility with the ARM64 architecture.
This solution should work for EventMachine version 1.2.7 and similar versions, though future versions might require adjustments as the codebase evolves.
Francium Tech is a technology company laser-focused on delivering top quality software at scale and at extreme speeds. The numbers and size of the data don’t scare us. If you have any requirements or want a free health check of your systems or architecture, feel free to shoot an email to contact@francium.tech, we will get in touch with you!