6

I'm using the ruby gem charlock_holmes in a Rails 4 app to detect the character encodings of CSV's that I'm parsing so that CSV.foreach doesn't throw an error.

However, when I try to push to heroku (with gem 'charlock_holmes' in the Gemfile) I get the following error:

Installing charlock_holmes (0.6.9.4)
   Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

   /tmp/build_e741f6ed-a860-47bf-8c0d-1b678fa0ebeb/vendor/ruby-2.0.0/bin/ruby extconf.rb
   checking for main() in -licui18n... no
   checking for main() in -licui18n... no


   ***************************************************************************************
   *********** icu required (brew install icu4c or apt-get install libicu-dev) ***********
   ***************************************************************************************
   *** 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.

   Provided configuration options:
   --with-opt-dir
   --without-opt-dir
   --with-opt-include
   --without-opt-include=${opt-dir}/include
   --with-opt-lib
   --without-opt-lib=${opt-dir}/lib
   --with-make-prog
   --without-make-prog
   --srcdir=.
   --curdir
   --ruby=/tmp/build_e741f6ed-a860-47bf-8c0d-1b678fa0ebeb/vendor/ruby-2.0.0/bin/ruby
   --with-icu-dir
   --without-icu-dir
   --with-icu-include
   --without-icu-include=${icu-dir}/include
   --with-icu-lib
   --without-icu-lib=${icu-dir}/
   --with-icui18nlib
   --without-icui18nlib
   --with-icui18nlib
   --without-icui18nlib


   Gem files will remain installed in /tmp/build_e741f6ed-a860-47bf-8c0d-1b678fa0ebeb/vendor/bundle/ruby/2.0.0/gems/charlock_holmes-0.6.9.4 for inspection.
   Results logged to /tmp/build_e741f6ed-a860-47bf-8c0d-1b678fa0ebeb/vendor/bundle/ruby/2.0.0/gems/charlock_holmes-0.6.9.4/ext/charlock_holmes/gem_make.out
   An error occurred while installing charlock_holmes (0.6.9.4), and Bundler cannot
   continue.
   Make sure that `gem install charlock_holmes -v '0.6.9.4'` succeeds before
   bundling.

How do I get libicu-dev to install on Heroku?

silasjmatson
  • 1,814
  • 18
  • 37

4 Answers4

13

Try using gem "charlock_holmes_bundle_icu", "~> 0.6.9.2". More info.

Ryan Linton
  • 1,285
  • 1
  • 14
  • 20
11

EDIT June 2017: As custom one-off buildpacks for this singular issue seem to go out of date, I'd recommend trying the approach presented by Benjie in this answer. Use heroku-buildpack-multi and heroku-buildpack-apt with an Aptfile to specify dependencies.

Steve Tooke also has an excellent write-up on this very issue: http://tooky.co.uk/using-charklock_holmes-on-heroku/ -- note that things may have changed in the 3 years since this question was asked, but the thing to remember is that generic/supported, rather than specific/unsupported, is the best route to go with buildpacks.

Original Answer:

While Ryan's answer works, it also slows down deploy times to -in my tests- up to 15 minutes. I even ran into Heroku's deploy time limit a few times.

An easier solution (that doesn't affect deploy times), is to use a Heroku buildpack

Aaron Severs created a buildpack that includes icu4c (which charlock_holmes relies on) in the dyno build. [see here]

Steps to make it work (Copied from Aaron's comment for posterity):

  1. Install the buildpack CLI: heroku plugins:install https://github.com/heroku/heroku-buildpacks
  2. Set the buildpack to Aaron's fork heroku buildpacks:set frederick/heroku-buildpack-ruby -a myapp
  3. In your Gemfile, use: gem 'charlock_holmes'
silasjmatson
  • 1,814
  • 18
  • 37
  • This is still a valid answer, and while Benjie says the `frederick/heroku-buildpack-ruby` is not maintained, it was recently updated and seem to be continously updated - at least when I checked the README.md last. – Jeppe Liisberg Apr 08 '15 at 19:02
  • I get `remote: ! Push rejected, error fetching custom buildpack` when doing these steps. Am I missing something? – Stephane Maarek Sep 06 '15 at 19:54
2

Sadly the other two solutions don't work for me (see below), so I had to come up with my own solution. This solution works with Ruby 1.9.3 but hammady says it does not work with 2.0.0.

I used heroku-buildpack-multi:

heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

With the following .buildpacks:

https://github.com/benjie/heroku-buildpack-apt
https://github.com/heroku/heroku-buildpack-ruby

And this Aptfile:

libicu-dev

My fork of heroku-buildpack-apt is required to export the BUNDLE_BUILD__CHARLOCK_HOLMES variable via Heroku's ENV_DIRs. In the Gemfile you just reference gem 'charlock_holmes' as usual and all works smoothly now for me.

If anyone can think of a way that doesn't involve exporting BUNDLE_BUILD__CHARLOCK_HOLMES then please let me know!


Ryan's answer doesn't work for me - Heroku bails because the bundle install step doesn't offer any output for 3 minutes. Silasj's answer references the frederick/heroku-buildpack-ruby buildpack which is no longer maintained and lags behind the official heroku-buildpack-ruby by quite an amount, which is not acceptable to me.

Community
  • 1
  • 1
Benjie
  • 7,701
  • 5
  • 29
  • 44
  • I am very fortunate to have find your answer only after 18 hours after posting it! I am pushing now and will see if it works :) – hammady Mar 27 '14 at 07:53
  • It didn't work for me. Here is the output from git push: http://pastebin.com/W7izp3fD, I also tried heroku build as stated in https://github.com/ddollar/heroku-buildpack-apt but fails with readonly file system, output here: http://pastebin.com/TwFtwmvG. It is weird that I can see libicu installed but bundler still can't build native extension. – hammady Mar 27 '14 at 10:41
  • @hammady I'd be very interested to know if you figure out what went wrong; it's worked for me for a few pushes now but I spent over 4 hours yesterday iterating to get to that point. I think your `heroku build` command is failing because of the new [ENV_DIR](https://devcenter.heroku.com/articles/buildpack-api#bin-compile) stuff - the compile script doesn't seem to be sent a `$3` so it's trying to write to `/LIBRARY_PATH` instead of `/path/to/ENV_DIR/LIBRARY_PATH`. – Benjie Mar 27 '14 at 16:12
  • @hammady I've just pushed out a new version of heroku-buildpack-apt that exports a few more variables to the ENV_DIR and fixes an issue I didn't realise I had relating to running `rake` during the push. Other than that I'm at a loss; though you're using Ruby 2 whilst I'm on 1.9.3. – Benjie Mar 27 '14 at 17:26
  • yes the Ruby 2 was the culprit! Specifying ruby '1.9.3' in the Gemfile fixed it! I wonder why would ruby 2 fail to find the native libraries: /tmp/build_a46064ac-89bf-4503-9fe1-28bc880896dd/vendor/ruby-2.0.0/bin/ruby extconf.rb --with-icu-dir="/tmp/build_a46064ac-89bf-4503-9fe1-28bc880896dd/.apt/usr" checking for main() in -licui18n... no checking for main() in -licui18n... no – hammady Mar 30 '14 at 05:16
  • 1
    Thanks your solution gave me everything I needed to get this working - I've changed the process slightly to use a specific .bundle/config for heroku with a third build pack. Details here: http://tooky.co.uk/using-charklock_holmes-on-heroku/ – Tooky Jun 11 '14 at 12:57
-2

This works:

Execute the following commands and install this:

1. brew install erlang icu4c spidermonkey

2. brew ln icu4c

This will install the required dependencies and then try to install charlock_homes.

  • The OP is able to install locally but is having difficulty getting to install on heroku. This answer doesn't address OP's question (which is why it's been downvoted). – Stephen Mariano Cabrera Aug 09 '17 at 22:10