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





















Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
Rubygems-developers mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rubygems-developers

Reply via email to