DEV Community

Cover image for Nokogiri installation errors on macos
Christoph Grabo
Christoph Grabo

Posted on • Originally published at markentier.tech on

Nokogiri installation errors on macos

Quick answer:

bundle config build.nokogiri --use-system-libraries && bundle install

This was originally posted on my blog here.

Every other year or so I want (or need) to install dependencies for a Ruby application on my Macbook, directly on the host instead of a VM or container. Mostly it's a Rails app.

And every time our most "loved" dependency bails on me: nokogiri. I think it always fails on a Mac. (At least once.)

Because I never go directly to the documentation of whatever refuses to work, I usually google my way to a solution.
In my case this was then harder than it should have been, so I write this down here for me as a reminder.

The next time I google it, I hope to find my own blog post and will make the same expression at the end. Again.

How does it fail

Try to get and build the dependencies:

# maybe a fancy Rails application
bundle install

And after a while …

# snippet
An error occurred while installing nokogiri (1.8.5), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.8.5' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  rails was resolved to 5.2.1.1, which depends on
    actioncable was resolved to 5.2.1.1, which depends on
      actionpack was resolved to 5.2.1.1, which depends on
        actionview was resolved to 5.2.1.1, which depends on
          rails-dom-testing was resolved to 2.0.3, which depends on
            nokogiri
# /snippet

Now if you run what is suggested …

gem install nokogiri -v '1.8.5'
Building native extensions. This could take a while...
ERROR:  Error installing nokogiri:
  ERROR: Failed to build gem native extension.

# ... snip ...

Undefined symbols for architecture x86_64:
  "_iconv", referenced from:
      _main in conftest-451598.o
  "_iconv_open", referenced from:
      _main in conftest-451598.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
checked program was:
/* begin */
 1: #include "ruby.h"
 2:
 3: #include <stdlib.h>
 4: #include <iconv.h>
 5:
 6: int main(void)
 7: {
 8:     iconv_t cd = iconv_open("", "");
 9:     iconv(cd, NULL, NULL, NULL, NULL);
10:     return EXIT_SUCCESS;
11: }
/* end */

You can also check the logs for later reference, too.

/Users/chris/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-17/2.5.0-static/nokogiri-1.8.5/gem_make.out
/Users/chris/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-17/2.5.0-static/nokogiri-1.8.5/mkmf.log

This is a problem that it cannot work with the iconv library currently present for linking.

Alternatively also another library can cause some troubles: libxml2

Then the output might look like …

Running 'compile' for libxml2 2.9.8... ERROR, review '/Users/chris/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/nokogiri-1.8.5/ext/nokogiri/tmp/x86_64-apple-darwin17.7.0/ports/libxml2/2.9.8/compile.log' to see what happened. Last lines are:
========================================================================
      _parseAndPrintFile in xmllint.o
  "_xmlXPathEval", referenced from:
      _doXPathQuery in xmllint.o
  "_xmlXPathFreeContext", referenced from:
      _doXPathQuery in xmllint.o
  "_xmlXPathFreeObject", referenced from:
      _doXPathQuery in xmllint.o
  "_xmlXPathIsInf", referenced from:
      _doXPathDump in xmllint.o
  "_xmlXPathIsNaN", referenced from:
      _doXPathDump in xmllint.o
  "_xmlXPathNewContext", referenced from:
      _doXPathQuery in xmllint.o
  "_xmlXPathOrderDocElems", referenced from:
      _parseAndPrintFile in xmllint.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

How to fix it

Well, if one would pay attention to the output, sometimes the output already tells you what could be done.

For the libxml case:

IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxml2-2.9.8
with the following patches applied:
    - 0001-Revert-Do-not-URI-escape-in-server-side-includes.patch
    - 0002-Fix-nullptr-deref-with-XPath-logic-ops.patch
    - 0003-Fix-infinite-loop-in-LZMA-decompression.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install

Note, however, that nokogiri is not fully compatible with arbitrary
versions of libxml2 provided by OS/package vendors.

So, the last commands are the things you should consider for a bundler based project.

bundle config build.nokogiri --use-system-libraries
bundle install

You can check the config:

bundle config
Settings are listed in order of priority. The top value will be used.
gem.test
Set for the current user (/Users/chris/.bundle/config): "rspec"

gem.mit
Set for the current user (/Users/chris/.bundle/config): true

gem.coc
Set for the current user (/Users/chris/.bundle/config): true

build.nokogiri
Set for the current user (/Users/chris/.bundle/config): "--use-system-libraries"

The file ~/.bundle/config for completion (shown as diff):

  ---
  BUNDLE_GEM__TEST: "rspec"
  BUNDLE_GEM__MIT: "true"
  BUNDLE_GEM__COC: "true"
+ BUNDLE_BUILD__NOKOGIRI: "--use-system-libraries"

And that's it. Fixed!

Nokogiri documentation

If I had consulted the nokogiri documentation at all, I also would have got the hint earlier:

Nokogiri will refuse to build against certain versions of libxml2, libxslt supplied with your operating system, and certain versions will cause mysterious problems. The compile scripts will warn you if you try to do this.

It focuses on libxml2, but the steps also help with the libiconv issue, too.

🤦

Top comments (1)

Collapse
 
philnash profile image
Phil Nash

Nokogiri is permanently an issue with this sort of thing. Thanks for this guide to solving the issue, my bet is you will help many people!