E
Erik Veenstra
I did a test (on Linux) with the progressbar example. Yes,
RubyScript2Exe executes the application, in order to trace it,
with (simplified):
$ ruby -r require2lib app.rb
This require2lib sets an at_exit block. In this block, all
required and loaded files are copied to ./lib . This ./lib is
packed into the executable and recreated on the destination
machine just before doing something like:
$ ruby -I ./lib app.rb
That's part of the job RubyScript2Exe does to satisfy the
requirements (besides ruby.exe and ruby.dll and a bunch of
recursively determined dll's en so's).
This copying works for files required via require_gem as well,
because the old require is still done by require_gem, so they
show up in $". Checked that. It works. It's just that
rubygems.rb doesn't work properly on the targeted machine,
because it expects its own environment, which is not recreated.
My plan was to overwrite this rubygems.rb which a version of my
own, only implementing require_gem. I came up with the code
below.
Any RubyGems hackers willing to have a look at it? Just
shoot...
Thanks in advance.
gegroet,
Erik V.
----------------------------------------------------------------
at_exit do
# Copy the required files to ./lib .
$".each do |req|
...
end
# Overwrite rubygems.rb with my own version of require_gem.
autorequire = {}
Gem::Specification.list.each do |gem|
unless gem.autorequire.nil?
unless $".collect{|s| (s =~ /^#{gem.autorequire}\.\w+$/)}.compact.empty?
autorequire[gem.name] = gem.autorequire
end
end
end
File.open("./lib/rubygems.rb", "w") do |f|
f.puts "module Kernel"
f.puts " def require_gem(file, version=nil)"
f.puts " autorequire = %s" % autorequire.inspect
f.puts " file = autorequire[file]"
f.puts " require(file) unless file.nil?"
f.puts " end"
f.puts "end"
end
end
----------------------------------------------------------------
(I tried, no response...)
RubyScript2Exe detects progressbar.rb [1] and yes, it is
included in the executable [2]. But when the executable is
run, require_gem only searches for progressbar.rb in its
own dirs, not in the regular places. Resulting in an
Gem::LoadError.
There are a couple of ways of attacking this. You /could/
replicate the gem metadata (not really recommended). Perhaps
supplying a custom require_gem that works in your packaged
app. I think the only thing the custom require_gem would need
to do is do a require on that gems autorequire file (if any).
RubyScript2Exe executes the application, in order to trace it,
with (simplified):
$ ruby -r require2lib app.rb
This require2lib sets an at_exit block. In this block, all
required and loaded files are copied to ./lib . This ./lib is
packed into the executable and recreated on the destination
machine just before doing something like:
$ ruby -I ./lib app.rb
That's part of the job RubyScript2Exe does to satisfy the
requirements (besides ruby.exe and ruby.dll and a bunch of
recursively determined dll's en so's).
This copying works for files required via require_gem as well,
because the old require is still done by require_gem, so they
show up in $". Checked that. It works. It's just that
rubygems.rb doesn't work properly on the targeted machine,
because it expects its own environment, which is not recreated.
My plan was to overwrite this rubygems.rb which a version of my
own, only implementing require_gem. I came up with the code
below.
Any RubyGems hackers willing to have a look at it? Just
shoot...
Thanks in advance.
gegroet,
Erik V.
----------------------------------------------------------------
at_exit do
# Copy the required files to ./lib .
$".each do |req|
...
end
# Overwrite rubygems.rb with my own version of require_gem.
autorequire = {}
Gem::Specification.list.each do |gem|
unless gem.autorequire.nil?
unless $".collect{|s| (s =~ /^#{gem.autorequire}\.\w+$/)}.compact.empty?
autorequire[gem.name] = gem.autorequire
end
end
end
File.open("./lib/rubygems.rb", "w") do |f|
f.puts "module Kernel"
f.puts " def require_gem(file, version=nil)"
f.puts " autorequire = %s" % autorequire.inspect
f.puts " file = autorequire[file]"
f.puts " require(file) unless file.nil?"
f.puts " end"
f.puts "end"
end
end
----------------------------------------------------------------
Contact me (or another gem developer) if you need help
pursuing this. We would be glad to help.
(I tried, no response...)