Loading .so files in Rails

software development

#1

I’m trying to get RMagick set up for my Rails application. I’ve currently gotten it so that RMagick works fine in the Rails console (script/console), but it fails when running under my web application. The failure appears to be related to the “require ‘RMagick.so’” inside RMagick.rb silently failing. I’ve checked all my permissions, and can’t find anything wrong there. I’m thinking it may have something to do with the way the server strips out LD_LIBRARY_PATH from the environment variables available to the Rails application, but all my attempts to work my way around that so far have failed. Adding a "SetEnv LD_LIBRARY_PATH ‘/home/scottd72…’ " to my .htaccess doesn’t seem to add the environment variable back to the set visible to dispatch.[f]cgi; meanwhile, attempting to set ENV[‘LD_LIBRARY_PATH’] in dispactch.[f]cgi, environment.rb, or anywhere else in my Ruby code still does not keep the “require ‘RMagick.so’” from silently failing.

Any ideas what might be going wrong and how to fix it?

Thanks,

– Scott


#2

Ah…I do get the same behavior if I unset LD_LIBRARY_PATH before starting up a stand-alone ruby process, even if I try setting ENV[‘LD_LIBRARY_PATH’] within the ruby process before the “require ‘RMagick’”. So my question now boils down to:

How do I make sure LD_LIBRARY_PATH is set correctly by the time control gets passed to dispatch.[f]cgi? Adding “SetEnv LD_LIBRARY_PATH [blahblah]” to .htaccess doesn’t seem to help, so I’m afraid that the enviornment variable is getting stripped out just before the call the dispatch. Alternatively, what’s an easy way to write a CGI script that just sets an environment variable and then forwards everything (including POSTs) to another CGI script?

Thanks,

– Scott


#3

For future reference, here’s how I worked around the issue:

  • Rename dispatch.cgi to, say, dispatch2.cgi
  • Create a new dispatch.cgi that looks something like this:

#!/bin/sh
LD_LIBRARY_PATH="/your/path/here:/another/path"
export LD_LIBRARY_PATH
exec dirname $0/dispatch2.cgi ${1+"$@"}

A similar solution appears to work with dispatch.fcgi.

One glitch that tripped me up before I arrived at the above: at first I called my wrapper script “dispatch_env.cgi”, had it exec my original “dispatch.cgi”, and modified .htaccess to call dispatch_env.cgi. DON’T do that: there seems to be some special-casing done by the web server to handle scripts with base names of “dispatch”, because having .htaccess call a script with a different name causes other environment variables to be set in slightly different ways that may mess up any URLs generated by your “real” script by making them relative to your wrapper script.


#4

Hello… can you please tell me how to do that on dispatch.fcgi ?
I´ve tried copying the example, but didn´t work.


#5

I’ve been struggling with this exact problem all day.

Is this really the best way to fix this? How come it isn’t mentioned anywhere on the RMagick wiki page? Has anyone else managed to install their own update to RMagick without having to do this workaround?


#6

Hi all, it looks like there’s a way to fix this that obviates this hackish (but effective) tip. LD_LIBRARY_PATH shouldn’t be needed at all if the binary is built with LD_RUN_PATH set at compile time.

export LD_RUN_PATH=/home/me/local/lib

Then, do your gem install or
./configure && make && make install

Then, you can leave dispatch.fcgi as the usual ruby file. You’ll still need to set your custom GEM_PATH and RAILS_ENV (if not “production”) somewhere, but you won’t need a bin/sh script wrapper to do that anymore.


#7

THANK YOU SO MUCH FOR THIS POST!

It’s now 2:50am and after hours and hours of struggling to get around the fact that a gem was throwing linking errors and couldn’t find the libcurl libraries it required (that I had to custom-build/install in my account on a shared host) this fixed it!

Very weird. I wouldn’t have expected an environment variable present at compile-time would affect it’s operation after it was built. Dark magic.