Question
When installing Compass version 1.0.0.alpha.17 on macOS with the system Ruby 2.0, installation fails while building the native extension for the ffi gem. The final build error is:
clang: error: unknown argument: '-multiply_definedsuppress'
make: *** [ffi_c.bundle] Error 1
What causes this native extension error, and how can Compass be installed successfully?
Short Answer
This error is not primarily a Compass error. Compass pulls in the ffi gem, which contains C code that must be compiled for your machine. The installed ffi version is using an old macOS compiler/linker option that a newer Clang toolchain rejects. You will learn how to read this kind of gem installation log, update or constrain dependencies safely, and avoid relying on macOS's system Ruby.
Concept
Ruby gems are often pure Ruby: RubyGems downloads their files and installation is complete. Other gems include a native extension, which is C, C++, Rust, or another compiled language integrated with Ruby.
ffi is one such gem. It lets Ruby code call native libraries. During installation, RubyGems performs roughly these steps:
- Runs
extconf.rbto inspect the computer and generate aMakefile. - Runs
maketo compile C source files. - Links the compiled files into a loadable Ruby extension, such as
ffi_c.bundleon macOS.
In the log, compilation mostly succeeds. The important failure is the final link command:
clang: error: unknown argument: '-multiply_definedsuppress'
That flag was accepted by older Apple build tools but is rejected by newer Clang versions. Therefore, the installed ffi 1.9.3 release is incompatible with that compiler configuration. The warnings earlier in the output are useful information, but the clang: error line and the following make failure identify the actual installation blocker.
This matters because a dependency can fail even when the gem you explicitly requested, such as Compass, contains no C code itself.
Mental Model
Think of a Ruby gem installation as assembling furniture.
- A pure Ruby gem is preassembled: you unpack it and use it.
- A native gem includes parts that must be assembled in your home.
Ruby,make,Clang, headers, and libraries are the tools and parts needed for assembly.- An old native extension may include instructions for an older tool. If your newer tool no longer recognizes one instruction, assembly stops.
Compass is the item you ordered, but ffi is one of the parts it depends on. The build fails while assembling that part.
Syntax and Examples
Native-extension failures are usually diagnosed from the last fatal error, not the first warning.
A typical installation command is:
gem install compass
If the dependency graph allows it, first install a compatible ffi release and then install Compass:
gem install ffi --version 1.9.5
gem install compass
For a project, prefer Bundler so all developers use the same dependency versions:
# Gemfile
source "https://rubygems.org"
gem "compass"
gem "ffi", "~> 1.9.5"
Then run:
bundle install
The ~> 1.9.5 constraint means “use version 1.9.5 or a later compatible 1.9.x version, but not 1.10.0.” Bundler records the exact resolved version in Gemfile.lock.
If you specifically need the historical Compass alpha, use its exact version in the Gemfile:
gem "compass", "1.0.0.alpha.17"
gem "ffi", "~> 1.9.5"
Whether this works depends on the alpha release's declared dependency constraints. If it requires an exact incompatible ffi version, use a newer Compass release or maintain a compatible older development environment instead.
Step by Step Execution
Consider this shortened build log:
checking for ffi.h... yes
creating Makefile
compiling Function.c
linking shared-object ffi_c.bundle
clang: error: unknown argument: '-multiply_definedsuppress'
make: *** [ffi_c.bundle] Error 1
Step by step:
checking for ffi.h... yesmeans the installer found the FFI header files it needs.creating Makefilemeansextconf.rbcompleted successfully and generated build instructions.compiling Function.cmeans Clang compiled at least some C source files into object files.linking shared-object ffi_c.bundlestarts the final stage: combining compiled objects into a file Ruby can load.- Clang rejects
-multiply_definedsuppressbecause the old extension passed a flag unsupported by the installed compiler. makereceives a nonzero exit status and stops.- RubyGems reports
Failed to build gem native extension, then Compass installation fails because its dependency was not installed.
The line Results logged to .../gem_make.out gives the full build log if terminal output has been truncated.
Real World Use Cases
Native Ruby dependencies appear in many practical situations:
- Database drivers: Gems may compile bindings for PostgreSQL, MySQL, or SQLite libraries.
- Image processing: Libraries such as ImageMagick integrations can require native headers and linker settings.
- Performance-sensitive code: Some gems use C extensions for speed.
- System integrations: FFI-based gems can communicate with operating-system libraries.
- Legacy application maintenance: A project lockfile may select an old native dependency that no longer builds with a current compiler.
In each case, identify the native gem named near the final error, then check compatibility among the gem version, Ruby version, OS, compiler, and required system libraries.
Real Codebase Usage
In real projects, developers avoid solving dependency problems by repeatedly installing global gems. They declare dependencies in a Gemfile and use Bundler:
source "https://rubygems.org"
gem "compass"
gem "ffi", "~> 1.9.5"
Useful workflow:
bundle install
bundle exec compass --version
bundle exec ensures the command uses the versions selected for the project rather than an unrelated globally installed gem.
Common maintenance patterns include:
- Pinning: Temporarily specify a known-working dependency version.
- Updating: Run
bundle update ffiwhen a newer compatible release fixes a build issue. - Lockfiles: Commit
Gemfile.lockfor applications so CI and teammates resolve the same versions. - Isolation: Use a Ruby version manager such as
rbenv,asdf, or RVM instead of changing the macOS-provided Ruby installation. - Reproducible environments: For old projects, use a container or an intentionally maintained older toolchain when modern tools cannot support the historical dependency set.
Common Mistakes
Treating every warning as the failure
The log contains C warnings, but the build actually stops at the fatal Clang error.
warning: implicit declaration ...
clang: error: unknown argument: '-multiply_definedsuppress'
Read from the bottom upward and find the first error: that causes make to fail.
Reinstalling the same incompatible version
This repeats the same build instructions and usually produces the same result:
gem install ffi --version 1.9.3
Use a compatible version instead, subject to the parent gem's dependency requirements.
Editing files inside the installed gem directory
It is possible to patch generated build files manually, but the patch disappears on reinstall and is hard to reproduce on another machine. Prefer an updated gem release, a Bundler constraint, or a maintained fork.
Using sudo gem install as the default fix
sudo changes permissions; it does not make an incompatible compiler flag valid. It can also mix project dependencies with macOS system files.
Assuming Compass itself is compiling
The log says the failing files are installed under an ffi-1.9.3 directory. Always locate the exact dependency that is being built.
Ignoring obsolete pre-release dependencies
A release named 1.0.0.alpha.17 is a pre-release. It may have old constraints or assumptions. Prefer a stable, supported release unless the project explicitly requires that pre-release.
Comparisons
| Situation | What it means | Typical response |
|---|---|---|
| Pure Ruby gem fails to install | Usually a RubyGems, dependency, or permission issue | Check Ruby and gem version constraints |
Native gem fails during extconf.rb | The configuration script cannot find headers, libraries, or tools | Install required development libraries and inspect mkmf.log |
| Native gem fails during compilation | C source is incompatible with the compiler or Ruby headers | Upgrade the gem or use a supported toolchain |
| Native gem fails during linking | A linker flag or native library is missing or incompatible | Update the native gem; verify library paths and build tools |
Global gem install | Installs into the active Ruby's gem set | Useful for tools, but can cause version drift |
bundle install | Resolves versions declared by a project | Preferred for application dependencies |
A compiler warning may indicate future maintenance work, while a compiler error prevents the extension from being built. In this log, the unsupported Clang argument is an error.
Cheat Sheet
# Install the normal stable Compass release
gem install compass
# Install a known newer compatible FFI release, if allowed by dependencies
gem install ffi --version 1.9.5
# Install project dependencies from a Gemfile
bundle install
# Run the project-selected executable
bundle exec compass --version
# See installed versions
gem list ffi
gem list compass
extconf.rbchecks the environment and writes aMakefile.makecompiles and links native code.ffi_c.bundleis the macOS native extension being built.- The final
clang: error:usually identifies the immediate cause. - A newer dependency can fix an old compiler flag.
- A Gemfile plus
Gemfile.lockis safer than relying on system-wide gem versions. - Do not use
sudoto solve compiler compatibility problems. - Pre-release gems can depend on outdated libraries; use stable versions when possible.
FAQ
Why does installing Compass install ffi?
RubyGems installs a gem's dependencies automatically. Compass or one of its dependencies requires ffi, so ffi must install successfully first.
What does “Failed to build gem native extension” mean?
It means RubyGems tried to compile non-Ruby code included with a gem, and the compiler or linker returned an error.
Is -multiply_definedsuppress a Ruby error?
No. It is an old compiler/linker option passed while building the native ffi extension. Clang rejects it in this environment.
Which line in the log is the important one?
The key line is:
clang: error: unknown argument: '-multiply_definedsuppress'
The subsequent make error is the result of that failure.
Should I install Xcode command-line tools?
Native gems need a working compiler toolchain, so installing current command-line tools can be necessary. However, this particular error shows that a compiler is already running; the immediate issue is the old ffi build flag.
Should I use the macOS system Ruby for development?
It is better to use an application-managed Ruby installed through a version manager. This isolates gems from system files and makes project Ruby versions reproducible.
What if Compass requires exactly ffi 1.9.3?
If the dependency constraint prevents a compatible ffi upgrade, choose a newer compatible Compass release, use a maintained fork, or run the legacy project in an environment with tools it supports.
Is installing an alpha version recommended?
Only when a project specifically requires it. Alpha releases are pre-release software and may not support modern Ruby or compiler toolchains.
Mini Project
Description
Create a small Ruby project that uses Bundler to install and run Compass with explicitly managed dependencies. This demonstrates how a Gemfile prevents your project from silently using whichever global gem versions happen to be installed.
Goal
Install and run Compass through Bundler, with the ffi dependency version recorded for repeatable installs.
Requirements
Create a new directory containing a Gemfile.
Declare Compass as a project dependency.
Declare a compatible ffi 1.9.x version constraint.
Run Bundler to generate a lockfile.
Verify the Compass executable using bundle exec.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.