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!