hi, what is the best way to distribute ruby apps without having the end
user need to download ruby?
i have looked into:
tar2ruby
exerb
and Xruby
however they seem difficult to use, after trying and failing. are there
other solutions? or any guides? for such an amazing language, ruby is
very difficult to compile to a standalone.
I asked almost the same question not too long ago. I think the
consensus was that JRuby was the best way to go. I don’t really like
this solution, but seems like the only way to go at the moment.
well it seems as tho i can;t really figure out how to use
rubyscript2exe, but i emailed the creator. im still trying to get jruby
to work. But seriously for such a language, it’s hard to believe that
there isn’t any ‘standard’ compiler.
Ruby is an interpreted language at this point, so you have no choice
but to pair it with an interpreter of some kind, whether it be MRI
Ruby, Rubinius, JRuby, or whatever.
Ruby 1.9, XRuby, IronRuby, Ruby.NET, and Rubinius run Ruby as compiled
bytecodes all the time (ok, you could say a bytecode interpreter, but
it’s still a big step beyond walking an AST). JRuby includes a mixed
interpred/compiled mode for execution by default along with “all
interpreted” and “all compiled” modes. In fact, as far as I know, Ruby
1.8 is the only version that’s “only” interpreted at this point…all
other versions have compiled execution.
Actually, we’ve recently enabled an interpreted mode in IronRuby / DLR.
We run interpreted by default until a method gets called multiple times,
and then we compile. The exact heuristic hasn’t been finalized yet, but
we’re forced to do this to do better on startup perf. The cost of JIT is
rather expensive …
This is more to the ‘gods of ruby’ than a reply. Tcl/Tk has a nice
way to do stuff like this called Starpacks. This is possible using
the Tcl/Tk virtual file system hooks. Starpacks are executables that
consist of the intepreter, necessary compiled packages, and a virtual
file system appended to the back end of the executable that contains the
script, scripted packages and loadable binaries.
A similar sort of thing for Ruby might be a good thing. The
seminal paper on starpacks and the related starkit (the virtual
filesystem unbundled from the run-time) is at:
Please don’t read this as a Tcl/Tk plug… just a comment that other
scripted languages had to face this and here’s one solution that another
scripting language came up with that may apply here.
Ruby is an interpreted language at this point, so you have no choice
but to pair it with an interpreter of some kind, whether it be MRI
Ruby, Rubinius, JRuby, or whatever.
Ruby 1.9, XRuby, IronRuby, Ruby.NET, and Rubinius run Ruby as compiled
bytecodes all the time (ok, you could say a bytecode interpreter, but
it’s still a big step beyond walking an AST). JRuby includes a mixed
interpred/compiled mode for execution by default along with “all
interpreted” and “all compiled” modes. In fact, as far as I know, Ruby
1.8 is the only version that’s “only” interpreted at this point…all
other versions have compiled execution.
Starpacks are executables that
consist of the intepreter, necessary compiled packages, and a virtual
file system appended to the back end of the executable that contains the
script, scripted packages and loadable binaries.
A similar sort of thing for Ruby might be a good thing. The
seminal paper on starpacks and the related starkit (the virtual
filesystem unbundled from the run-time) is at:
Sounds like it to me, although I don’t know starpacks at all.
I’ve had very good luck with rubyscript2exe. Even used it with C
extensions (like rb-gsl) and it worked on different distributions than
what I “compiled” it on.
Pavel, it’s really straight-forward to use. What are you having
problems with?
Sounds like it to me, although I don’t know starpacks at all.
Hi Cameron,
No, starkits and starpacks are actually much more powerful and
versatile. The Tcl world had the equivalent of rubyscript2exe for years
and years, but when starkits and starpacks came out it everyone found it
a huge step forward when it came to deployment.
Among the advantages:
ship a single file platform-specific executable (as per *2exe)
ship a single file platform-neutral application, which can then be
run with a (single file) platform-specific but application-neutral
binary; in other words, your entire language runtime can be in a single
file you can just download, and use for many applications
no changing your code… because starkits are based on a virtual
file system, you refer to files “in” the starkit exactly the same as you
would normal files on disk, using standard I/O commands. so that is
both scripts, data files, etc.
starkits can be used as a way to distribute source, again all in
one file; people can grab the starkit, unpack it, make some changes,
pack it up again
source can be optionally protected (i.e. you can’t get the original
scripts back) using a compiler, which is actually a separate and
complementary tool
starpack/starkit technology also supports a separation of the
run-time (tclkit in Tcl/Tk land), and the application stuff (the stuff
in the VFS). This allows you to split the installer into a system
dependent piece (the tclkit) and the application (starkit). These can
be combined to a starpack which is system dependent.
Because the starkit part of the system is a full featured filesystem
from the Tcl/Tk point of view it’s possible to do a few neat things
including automatic updating of the contents of the starkit. The
application, as it starts up can ask the world if there are newer
versions and, if desired, confirmed by the user…all the application
specific caveats you care to apply, can update itself in place.
Because the VFS that constitutes starkits is actually a metakit
database, updates described above can be done as a transaction which
either entirely succeed or entirely fail, but not leave the application
in some funky state.
Again, because the VFS is a file system, the application can:
store data (e.g. ordinary help files) and access them as files.
keep e.g. configuration data allowing for a portable computing env.
(e.g. a web-browser starpack could keep your book marks in its
VFS so you could run around with your browser on a memory stick).
Because the starkit is a virtual file system to Tcl/Tk, there’s no
need to unpack the application into a temp directory for purely scripted
apps… or for apps whose extensions are built into the tclkit. Only
compiled loadable extensions need to be copied out into the host’s
filesystem so that they host system’s dynamic loader can find them. For
large apps this can improve the startup time significantly.
How does this handle interacting with the filesystem outside the VFS?
So let’s say you have files in the same directory as the starkit How
would you access them? Does it automatically assume you’re accessing
something outside of the starkit unless you specifically say you want
something in the starkit? (IIRC that’s how jars work in Java)
Ruby 1.9, XRuby, IronRuby, Ruby.NET, and Rubinius run Ruby as compiled
bytecodes all the time (ok, you could say a bytecode interpreter, but
it’s still a big step beyond walking an AST). JRuby includes a mixed
interpred/compiled mode for execution by default along with “all
interpreted” and “all compiled” modes. In fact, as far as I know, Ruby
1.8 is the only version that’s “only” interpreted at this point…all
other versions have compiled execution.
Actually, we’ve recently enabled an interpreted mode in IronRuby / DLR. We run interpreted by default until a method gets called multiple times, and then we compile. The exact heuristic hasn’t been finalized yet, but we’re forced to do this to do better on startup perf. The cost of JIT is rather expensive …
I’ll be interested to see what heuristic you come up with. Currently
JRuby just uses “20 invocations” as the deciding moment. This ends up
working great for small apps, where the code you want compiled gets
compiled quickly. But for large apps, it seems we may want an upper
limit on the number of JITed methods, since it can eventually swamp the
system with barely-used code.
Joe, the virtual file system hooks work comparably to ‘real’ file
systems in that you can ‘mount’ a new file system at a particular point
in the directory tree.
Let’s say you’ve downloaded your starkit to /home/foo/my.kit. When you
run the starkit, the file system inside it essentially gets mounted at
that location in the directory tree. So if you try to access
/home/foo/my.kit/bar/data.txt, that will look inside the starkit. If
you try to access /home/foo/other.dat, it will look in the regular file
system, because the starkit isn’t mounted there.
So the nice thing is that it’s all transparent. You just use the
regular commands you’d used to operate on any old file, and the internal
I/O system will figure out what ‘filesystem’ you’re working on based
upon the path names.
Like any virtual file system based thing, the same approach is used for
other filesystems… e.g. one that maps an http server to a file system.
The VFS appears mounted in a specific point on the actual filesystem.
There’s no problem accessing files outside or inside the VFS.
I have a starkit, for example that implements a launcher for X11 clients
to windows X11 servers. That starkit is able to, and perfectly well
does, store session configurations in a file in the ‘normal windows
locations $AppData\xlauncer’.
The application can find the top-level of the starkit vfs via the
variable starkit::topdir