Question
I am using Fedora 14 with MySQL Server 5.1.42 installed and running.
When I try to install the Ruby MySQL gem as the root user:
gem install mysql
I get this error:
Building native extensions. This could take a while...
ERROR: Error installing mysql:
ERROR: Failed to build gem native extension.
/usr/bin/ruby extconf.rb
mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/mysql-2.8.1 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/mysql-2.8.1/ext/mysql_api/gem_make.out
What is causing this error? Ruby 1.8.7 and RubyGems 1.3.7 are already installed.
Short Answer
By the end of this page, you will understand why some Ruby gems need compilation, what Ruby header files are, why native extension builds fail, and how to fix the problem by installing the correct development packages on Linux.
Concept
Some Ruby gems are written entirely in Ruby, but others include native extensions written in C. These extensions must be compiled during installation.
The mysql gem is one of those gems. When you run:
gem install mysql
RubyGems tries to:
- run
extconf.rb - generate a
Makefile - compile C code
- link it against Ruby and sometimes external libraries such as MySQL
To compile a native extension, the system needs development files, not just the Ruby interpreter.
These development files usually include:
- Ruby header files such as
ruby.h - compiler tools such as
gccandmake - library development packages such as MySQL client headers
In this case, the key error is:
mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h
That means Ruby itself is installed, but the Ruby development headers are missing. On Linux distributions, runtime packages and development packages are often split apart.
So the issue is not that Ruby is absent. The issue is that the gem needs files used for compilation, and those files are not currently installed.
This matters in real programming because many gems depend on external libraries or native code for:
- database drivers
- image processing
- JSON performance
- cryptography
- networking
Whenever a gem has to compile code, you need the matching development environment.
Mental Model
Think of installing a native gem like assembling a machine from parts.
- The Ruby interpreter is the finished machine already running.
- The gem with native extensions is a custom attachment you want to add.
- The header files like
ruby.hare the blueprints and connector specifications.
If you only have the machine but not the blueprints, the builder cannot attach the new part correctly.
So the error is basically saying:
I can see Ruby is installed, but I do not have the files that describe how to build something that connects to Ruby.
On Linux, those blueprint files usually come from packages named like:
ruby-develmysql-develbuild-essentialor compiler tools
Syntax and Examples
A native gem installation usually looks simple:
gem install mysql
But behind the scenes, it may require development packages.
Typical fix on Fedora
For Fedora or similar RPM-based systems, you usually need:
sudo yum install ruby-devel gcc make mysql-devel
Then try the gem install again:
gem install mysql
Why this works
ruby-develprovidesruby.hand other Ruby headersgcccompiles C source filesmakeruns the build processmysql-develprovides MySQL client headers and libraries
Example of checking whether the header exists
ls /usr/include/ruby*
Or on some systems:
rpm -ql ruby-devel
This helps confirm whether the Ruby development package is installed.
Another example with a different gem
Many gems behave the same way:
gem install pg
If PostgreSQL development headers are missing, installation will fail in a similar way. The pattern is the same: install the development package, then retry.
Step by Step Execution
Consider this command:
gem install mysql
Here is what happens step by step:
- RubyGems downloads the
mysqlgem. - It detects that the gem contains native C extensions.
- It runs a setup script, often named
extconf.rb. extconf.rbuses Ruby'smkmflibrary to inspect your system.mkmflooks for required files such as:- Ruby headers like
ruby.h - MySQL headers
- compiler tools
- Ruby headers like
- In your case, it fails immediately because it cannot find
ruby.h. - Since it cannot generate a valid build configuration, compilation stops.
- RubyGems reports
Failed to build gem native extension.
Small trace example
Suppose the installer needs this file:
/usr/include/ruby-1.8/ruby.h
If the file is missing:
extconf.rbcannot continue- no valid
Makefileis produced - the C extension is never compiled
- the gem install fails
Important detail
The first useful error is often not the final Failed to build gem native extension line. The real clue is usually a line above it, such as:
mkmf.rb can't find header files for ruby
When debugging gem installs, always read the first specific missing dependency message.
Real World Use Cases
Native extensions appear often in real Ruby projects.
Database adapters
Gems such as MySQL, PostgreSQL, and SQLite adapters often compile native code to communicate efficiently with database libraries.
Performance-sensitive libraries
Some gems use C code for speed, especially when pure Ruby would be too slow.
System integration
Libraries that interact with operating system features, networking, image libraries, or encryption tools often require native compilation.
Legacy projects
Older Ruby applications, especially on older Linux systems, often depend on gems like mysql, which need system packages and headers to build.
CI and deployment
In CI pipelines or production servers, native gems may fail if the machine has runtime packages installed but not development packages. This is a common setup issue.
Real Codebase Usage
In real projects, developers usually handle native gem dependencies in a few common ways.
Document system dependencies
Projects often include setup steps such as:
yum install ruby-devel mysql-devel gcc make
This is usually written in:
- a README
- a Dockerfile
- provisioning scripts
- CI configuration
Use dependency installation scripts
Teams often automate setup so new developers do not have to guess which packages are required.
Example:
sudo yum install -y ruby-devel mysql-devel gcc make
bundle install
Read build logs
When installation fails, developers check files like:
gem_make.out
mkmf.log
These logs often show the real missing dependency.
Prefer maintained gems
In modern Ruby projects, developers often use newer, maintained adapters instead of older gems when possible. But the same native-extension principle still applies.
Match runtime and development packages
A common pattern is making sure the interpreter version matches the development package version. For example, Ruby 1.8 runtime should have the matching ruby-devel package, not a different Ruby version.
Common Mistakes
1. Thinking Ruby itself is enough
Beginners often assume that if ruby -v works, gem compilation should also work.
That is not always true.
rubygives you the interpreterruby-develgives you header files for compiling extensions
2. Ignoring the specific missing file
This error:
Failed to build gem native extension
is generic.
The useful part is:
can't find header files for ruby
Always look for the first detailed error.
3. Installing only the database server
Having MySQL Server installed does not always mean you have the client development files.
You may still need:
sudo yum install mysql-devel
4. Missing compiler tools
Even with the correct headers, the build can fail if tools are missing.
You may need:
sudo yum install gcc make
5. Confusing runtime packages with development packages
Broken assumption:
# Ruby exists, so compilation should work
ruby -v
Correct approach:
sudo yum install ruby-devel
6. Using old gems without checking compatibility
Some older gems work differently across Ruby versions and OS versions. If a gem is old, check whether:
- it is still maintained
- there is a newer replacement
- your Ruby version is compatible
Comparisons
| Concept | What it provides | Needed to run Ruby code? | Needed to build native gems? |
|---|---|---|---|
ruby | Ruby interpreter | Yes | Yes |
ruby-devel | Ruby headers like ruby.h | No | Yes |
mysql-server | Database server process | No | No |
mysql client libraries | Database client support | Sometimes | Often |
mysql-devel | MySQL headers and linkable libs | No | Yes |
gcc / make | Build tools | No | Yes |
Pure Ruby gem vs native gem
| Type | Needs compilation? | Needs headers/tools? | Example |
|---|---|---|---|
| Pure Ruby gem | No | No | many utility gems |
| Native extension gem | Yes | Yes | mysql, pg, some image gems |
Generic error vs useful error
| Message | Meaning |
|---|---|
Failed to build gem native extension | Something in compilation failed |
can't find header files for ruby | Ruby development package is missing |
checking for mysql_query()... no | MySQL development files may be missing |
Cheat Sheet
# Install Ruby development headers on Fedora
sudo yum install ruby-devel
# Install common build tools
sudo yum install gcc make
# Install MySQL development files
sudo yum install mysql-devel
# Retry gem installation
gem install mysql
Key idea
If a gem builds native extensions, you often need:
- language development headers
- compiler tools
- library development packages
Error clues
ruby.hmissing -> installruby-devel- MySQL headers missing -> install
mysql-devel - compiler not found -> install
gccandmake
Debugging files
Look at:
gem_make.outmkmf.log
Rule of thumb
If a gem compiles C code, runtime packages alone are usually not enough.
FAQ
Why does gem install mysql try to compile code?
Because the mysql gem includes a native extension written in C, which must be built on your machine.
What is ruby.h?
ruby.h is a Ruby header file used when compiling native extensions that connect C code to Ruby.
Why is Ruby installed but ruby.h missing?
On Linux, runtime and development files are often packaged separately. You may have ruby installed but not ruby-devel.
Is installing MySQL Server enough for the mysql gem?
No. You may also need MySQL development files such as mysql-devel so the gem can compile and link correctly.
What package should I install on Fedora for this specific error?
Usually ruby-devel is the direct fix for the missing ruby.h error. You may also need gcc, make, and mysql-devel.
Where can I find more details about the build failure?
Check the generated log files, especially gem_make.out and often mkmf.log inside the gem extension directory.
Does running the command as root fix missing headers?
No. Permissions and missing development files are different problems. Root access does not provide header files.
Are native extension errors common with Ruby gems?
Yes. They are common when working with database adapters, image libraries, cryptography gems, and system-level integrations.
Mini Project
Description
Create a small setup checklist for installing a Ruby project that depends on a native MySQL gem. This project helps you practice identifying runtime dependencies versus development dependencies and writing repeatable setup steps for Linux environments.
Goal
Write and test a simple installation script or checklist that prepares a Fedora machine to compile and install a native Ruby MySQL gem successfully.
Requirements
[
"Install the Ruby development package required for ruby.h.",
"Install the compiler tools needed to build native extensions.",
"Install the MySQL development package required by the gem.",
"Run the gem installation command after dependencies are installed.",
"Verify that the gem installation completes without the missing-header error."
]
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.