Red Green Repeat Adventures of a Spec Driven Junkie

Techniques to Fixing Failing Gem Installs

Why ruby 2.1.5 instead of 2.2.3+?

One reason why I usually recommend using an older ruby version (2.1.5) over the latest was I had some bad gem install experiences with ruby 2.2.3, most notably: nokogiri.

Getting a new project ready for development on a new system was not a simple as: bundle, because of these dreaded lines:

Fetching: nokogiri-1.7.0.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
        ERROR: Failed to build gem native extension.

I thought I was the only one with this issue, but I wasn’t. It turned out to be a combo of things (one of them was because of ruby 2.2.3!)

I solved the issue somehow, but never remembered the steps, so every new system I wanted to do any work always had issues around getting gems installed. Hence, my reluctance on recommending a newer version of ruby, especially 2.2.3. I wanted to focus on programming, not solving weird setup problems, so ruby 2.1.5 was my recommended default.

Fixing Gem Installs

Instead of just letting this knowledge be rediscovered each time, I am writing them here so it’s easier for me and others to find. I have techniques to fix issues with header files, missing tools, and library linking.

Missing Header Files

Missing header file issues are easy to fix because the error message will usually tell what is missing or needed. For example, this is the message when installing the Postgresql or pg gem:

Building native extensions.  This could take a while...
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /home/user/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20161228-24260-rx9bta.rb extconf.rb
    checking for pg_config... no
    No pg_config... trying anyway. If building fails, please try again with
     --with-pg-config=/path/to/pg_config
     checking for libpq-fe.h... no
     Can't find the 'libpq-fe.h header
     *** extconf.rb failed ***
     Could not create Makefile due to some reason, probably lack of necessary
     libraries and/or headers.  Check the mkmf.log file for more details.  You may
     need configuration options.

The key piece of information is: Can't find the 'libpq-fe.h header.

A quick search for that file with the operating system usually recommends a solution to install the libpg-dev package, and the solution for Ubuntu would be as simple as: sudo apt-get install libpq-dev.

Missing Tools on System

Another problem could be around missing tooling, such as a special version of cmake for the rugged gem. This is an error encountered when trying to install a gem without the right build tool on the system.

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /home/user/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20161228-31966-1asakes.rb extconf.rb
    checking for gmake... no
    checking for make... yes
    checking for cmake... no
    ERROR: CMake is required to build Rugged.
    *** extconf.rb failed ***
    Could not create Makefile due to some reason, probably lack of necessary
    libraries and/or headers.  Check the mkmf.log file for more details.  You may
    need configuration options.

The key piece of information is: ERROR: CMake is required to build Rugged.

This one is a bit harder to solve. I have solved it by using a different repository for cmake using this answer.

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:george-edison55/cmake-3.x
sudo apt-get update
sudo apt-get install cmake

Missing or Unlinkable Libraries

The hardest problem I had when installing gems are ones involving missing libraries, where the error are in the form of:

/home/user/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20150905-15835-17vnavf.rb extconf.rb
checking if the C compiler accepts ...
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

As there is no specific detail other than something failing, there needs to be some digging, so let’s look at the mkmf.log file.

note: the mkmf.log can be found using: locate mkmf.log or in the gem’s build folder, for this example nokogiri: /home/user/.rvm/gems/ruby-2.3.0/extensions/x86_64-linux/2.3.0/nokogiri-1.7.0/mkmf.log

In the mkmf.log file, the last paragraph is:

"gcc -o conftest -I/home/user/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/x86_64-linux -I/home/user/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0/ruby/backward -I/home/user/.rvm/rubies/ruby-2.2.3/include/ruby-2.2.0 -I.     -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat  -fPIC  conftest.c  -L. -L/home/user/.rvm/rubies/ruby-2.2.3/lib -Wl,-R/home/user/.rvm/rubies/ruby-2.2.3/lib -L. -fstack-protector -rdynamic -Wl,-export-dynamic     -Wl,-rpath,'/../lib' -Wl,-R'/../lib' -lruby  -lpthread -lgmp -ldl -lcrypt -lm   -lc "
/usr/bin/ld: cannot find -lgmp
collect2: error: ld returned 1 exit status
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: int main(int argc, char **argv)
4: {
5:   return 0;
6: }
/* end */

note: Original error message here, I could not reproduce it again on my system

The key piece of information is: /usr/bin/ld: cannot find -lgmp

Solving this might require one or two additional steps: installing the missing library and/or making the library linkable.

Missing Library

Fixing missing library is as easy as looking up how to install the library package and following those steps. In this case, searching for how to install libgmp on the system will probably fix this problem.

note: on library naming convention and the linker: even though the line only has gmp, the library name is: libgmp. The linker, ld, has the argument -lgmp, and -l is shorthand for lib. If the argument was ld -llibgmp, then the expected library name would: liblibgmp.)

Unlinkable Library

If after installing the library, and the same error persists, I have found the problem is because the library has been installed but the linker cannot find the library in its path (aka LD_LIBRARY_PATH)

The easiest way I have found to fix this problem is to look at what the linker is missing by directly executing the ld command for the library. This is a fantastic piece of advice I found here

ld -l<missing library name> --verbose

So, if libgmp is installed, but the gem still won’t install, checkout what the linker is doing, but executing:

user@system:~$ ld -lgmp --verbose

It’s output:

attempt to open /usr/x86_64-linux-gnu/lib64/libgmp.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libgmp.a failed
attempt to open //usr/local/lib/x86_64-linux-gnu/libgmp.so failed
attempt to open //usr/local/lib/x86_64-linux-gnu/libgmp.a failed
attempt to open //usr/local/lib64/libgmp.so failed
attempt to open //usr/local/lib64/libgmp.a failed
attempt to open //lib/x86_64-linux-gnu/libgmp.so failed
attempt to open //lib/x86_64-linux-gnu/libgmp.a failed
attempt to open //lib64/libgmp.so failed
attempt to open //lib64/libgmp.a failed
attempt to open //usr/lib/x86_64-linux-gnu/libgmp.so failed
attempt to open //usr/lib/x86_64-linux-gnu/libgmp.a failed
attempt to open //usr/lib64/libgmp.so failed
attempt to open //usr/lib64/libgmp.a failed
attempt to open //usr/local/lib/libgmp.so failed
attempt to open //usr/local/lib/libgmp.a failed
attempt to open //lib/libgmp.so failed
attempt to open //lib/libgmp.a failed
attempt to open //usr/lib/libgmp.so failed
attempt to open //usr/lib/libgmp.a failed
ld: cannot find -lgmp

Here, the locate or find is your friend here: use locate to find the actual installed library on your system with a similar name:

user@system:~$ locate libgmp

and the output maybe:

/home/user/.rvm/log/1477953355_ruby-2.1.15/package_install_g++_gcc_make_libc6-dev_libreadline6-dev_zlib1g-dev_libssl-dev_libyaml-dev_libsqlite3-dev_sqlite3_autoconf_libgmp-dev_libgdbm-dev_libncurses5-dev_automake_libtool_bison_pkg-config_libffi-dev.log
/usr/lib/x86_64-linux-gnu/libgmp.so.10
/usr/lib/x86_64-linux-gnu/libgmp.so.10.1.3
/usr/lib/x86_64-linux-gnu/libgmpxx.a
/usr/lib/x86_64-linux-gnu/libgmpxx.so
/usr/lib/x86_64-linux-gnu/libgmpxx.so.4
/usr/lib/x86_64-linux-gnu/libgmpxx.so.4.3.3
/usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/libgmp.so
/usr/share/doc/libgmp-dev
/usr/share/doc/libgmp10
/usr/share/doc/libgmpxx4ldbl
/usr/share/doc/libgmp-dev/AUTHORS
/usr/share/doc/libgmp-dev/NEWS.gz
/usr/share/doc/libgmp-dev/README
/usr/share/doc/libgmp-dev/changelog.Debian.gz
/usr/share/doc/libgmp-dev/copyright
/usr/share/doc/libgmp10/README.Debian
/usr/share/doc/libgmp10/changelog.Debian.gz
/usr/share/doc/libgmp10/copyright
/usr/share/doc/libgmpxx4ldbl/changelog.Debian.gz
/usr/share/doc/libgmpxx4ldbl/copyright
/usr/share/lintian/overrides/libgmpxx4ldbl
/var/lib/dpkg/info/libgmp-dev:amd64.list
/var/lib/dpkg/info/libgmp-dev:amd64.md5sums
/var/lib/dpkg/info/libgmp10:amd64.list
/var/lib/dpkg/info/libgmp10:amd64.md5sums
/var/lib/dpkg/info/libgmp10:amd64.postinst
/var/lib/dpkg/info/libgmp10:amd64.postrm
/var/lib/dpkg/info/libgmp10:amd64.shlibs
/var/lib/dpkg/info/libgmpxx4ldbl:amd64.list
/var/lib/dpkg/info/libgmpxx4ldbl:amd64.md5sums
/var/lib/dpkg/info/libgmpxx4ldbl:amd64.postinst
/var/lib/dpkg/info/libgmpxx4ldbl:amd64.postrm
/var/lib/dpkg/info/libgmpxx4ldbl:amd64.shlibs

In this case, the missing library looks to be:

/usr/lib/x86_64-linux-gnu/libgmp.so.10

and it is in one of the LD_LIBRARY_PATH the linker is using, but the linker specifically wants a different name, because of this linker message:

attempt to open /usr/x86_64-linux-gnu/lib64/libgmp.so failed

To fix: create a symbolic link so ld can find it. In this case:

user@system:~$ sudo ln -s /usr/lib/x86_64-linux-gnu/libgmp.so.10 /usr/lib/x86_64-linux-gnu/libgmp.so

Summary

Three common errors where gem installation can go bad are presented: missing and/or unlinkable libraries, compilation tools are missing, or missing header files. Their solutions involve looking for key pieces of information, some searching, and installation and/or setup.

I kept my development environment in a single place since I was scared of debugging failing gem installs on different environments. Now with these tools, I will be taking my development environments to more places!

Go Forth & bundle everywhere!