[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