[Rubygems-developers] How to deal with binary dependencies?

Charlie Savage cfis at savagexi.com
Sat Jul 19 16:18:29 EDT 2008


I'd like to revisit a thread from last year:

http://rubyforge.org/pipermail/rubygems-developers/2007-March/002646.html

The problem is how to deal with binary dependencies within a GEM file. 
I think I've come up with a solution, and just posting here for anyone i 
the future that runs into the same problem.

To understand the issue, let's look at libxml-ruby.  For Windows, we 
include a compiled extension (libxml_ruby.so) in the lib directory.

In addition, we include a compiled libxml2-2.dll in the mingw directory 
since its highly likely that windows users don't have it.  Thus:

libxml-ruby
    ext
       <all the c code>
    lib
       libxml.rb
       libxml_ruby.so
    mingw
        MingW rake files
        libxml2-2.dll


When a user does require 'libxml' what happens:

1.  libxml.rb is loaded
2.  libxml.rb loads libxml_ruby.so
3.  libxml_ruby.so loads libxml2-2.dll

Its this third step that causes the issue.  Windows must be able to find 
libxml2-2.dll.  This is explained here:

http://msdn.microsoft.com/en-us/library/7d83bc18.aspx

Which basically means:

* The current directory (where the Ruby program is)
* In the Windows system directory or PATH
* In the root directory of the executable.  Since that's ruby.exe, that 
would be ruby/bin

Choices that do NOT work:

* libxml-ruby/lib
* site_ruby/1.8/i386-msvcrt
* Using the "app paths" registry key - that only seems to work for 
programs invoked from Windows Explorer via Shell Execute 
(http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx)

The Ruby one-click installer goes with the third choice - its puts all 
its dlls in that directory (iconv.dll, libexpat.dll, readline.dll, 
gdbm.dll, etc.).

Phew, got all that?

So after playing around with this a  bit I see a few possible solutions:

*  Have GEMS support the need to move binary dependencies into the 
ruby/bin directory on Windows.  Same issue could happen on other OS's in 
theory, but you usually install libraries like libxml2 system wide. 
This is recommended practice by MSFT 
(http://msdn.microsoft.com/en-us/library/ms682600(VS.85).aspx - see last 
paragraph).

*  Have GEMS support the need to move binary dependencies into the 
site_ruby/1.8/i386-msvcrt directory and tell the user that they have to 
put that directory on the Windows path.  The problem with this of course 
is a) the extra user required step b) its opposite the precedent set by 
the one click install.

* Modify the PATH on the fly.  This can be done by setting ENV['path'] 
or SetDllDirectory 
(http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx).  From 
testing, this solution in fact does work (I wasn't sure if it would).

Thoughts?  And more questions.  Should this be standardized?  Should 
there be a libs directory for dlls in gems?  Or should we reuse lib? 
Should there be an option to set the path for Windows?  Should there be 
the ability to check if the dll is already present (sort of like 
setup.rb does, but not using the C compiler, using LoadLibrary instead)

Thanks,

Charlie





















-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3237 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://rubyforge.org/pipermail/rubygems-developers/attachments/20080719/eeeae935/attachment.bin>


More information about the Rubygems-developers mailing list