Compiling a Ruby app

Hi
Does there exist a compiler for compiling Ruby apps?
I dont like the idea of being forced to distribute apps open source.
My first concern is that distribution, at least on the windows platform,
will differ a lot from what users are used to.
My second concern is protecting source code.
I realize that everything that can be compiled can also be decompiled,
but I would like it to take a little more effort for average Joe to
view/edit source code than to simply right-click on somefile.rb and
opening it in wordpad.

I know about “rubyscript2exe”, which solves the first part of the
problem, but not the second.

-S

Sharagoz – wrote:

Hi
Does there exist a compiler for compiling Ruby apps?
I believe there is a way to do this through using jruby, though I’ve
never done it.
Cheers!
-=r

Sharagoz – wrote:

My second concern is protecting source code.
I realize that everything that can be compiled can also be decompiled,

That is not entirely true. Or rather, it can be “decompiled”, all right,
but not into anything resembling the original source code.

but I would like it to take a little more effort for average Joe to
view/edit source code than to simply right-click on somefile.rb and
opening it in wordpad.

The main question you need to ask yourself is, why don’t you want Joe to
do that?

If your goal is to prevent others from taking your code, repackaging it,
and selling it as their own, that’s fine, although there are better ways
of doing it – like legal measures.

If your goal is to prevent users from doing something they want to do –
for example, if this is a form of copy protection – you should realize
two things:

  • Someone (not Average Joe) will reverse engineer it, and publish a
    crack.
  • Average Joe will be able to find that crack.

That is true with or without source code. It’s not a “might”, it’s a
“will”.

But yes, if it’s not possible now, I believe it will be possible to
compile JRuby.

But there is a reason the obvious solution is to never give your users a
program at all – instead, build it as a web app, and host it yourself.

Thanks for the input.

So there is no way to compile a “regular” ruby app, you’d have to go for
Jruby?
I’ve seen projects like “Brite”, “YARV” and “Rubinius” mentioned that
seems to be “compiler related” projects. (Excuse the poor terminology).
Will any of those do the job?

Im not concerned about reverse engineering or cracks being made for my
software. All I want is to be able to distribute it the traditional way
like most commercial software is (at least on the windows platform).
Open source makes code stealing too easy.

I find it strange that there isnt a compiler readily available for Ruby.
Is there a technical reason why there shouldnt be one?
Is it because Ruby is ment to be pure open source and never used in the
commercial sector?

I use Ruby on Rails for web apps, and its an excelent framework to work
in.
Sometimes though, client apps are a better solution and I was hoping I
could use Ruby for that purpose because I’ve grown fond of Ruby through
RoR.

On Tue, Mar 3, 2009 at 5:09 AM, David M. [email protected]
wrote:

Sharagoz – wrote:

My second concern is protecting source code.
I realize that everything that can be compiled can also be decompiled,

That is not entirely true. Or rather, it can be “decompiled”, all right,
but not into anything resembling the original source code.

Actually closer than you might think:

require ‘rubygems’
require ‘ruby2ruby’

class Foo
def bar
a = 1
b = 2
a + b
end
end

puts Ruby2Ruby.translate(Foo)

produces:

class Foo < Object
def bar
a = 1
b = 2
(a + b)
end
end


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

On Mar 3, 2009, at 11:09 AM, David M. wrote:

Sharagoz – wrote:

My second concern is protecting source code.
I realize that everything that can be compiled can also be
decompiled,

That is not entirely true. Or rather, it can be “decompiled”, all
right, but not into anything resembling the original source code.

Almost every kind of Bytecode is surprisingly well decompilable.

BTW: Open Source has nothing to do with the code being viewable.
Battlefield 2 and Eve Online for example contain large portions of
viewable code, but none of it is open source.

If Bytecode is enough for you: A patched Ruby 1.9-Interpreter is able
of loading Bytecode (it is off, due to likely changes in the Bytecode
format). Exporting is already available. I don’t think there are
readymade solutions available, but you could construct something out
of it.

Regards,
Florian


Florian G.

smtp: [email protected]
jabber: [email protected]
gpg: 533148E2

On Tue, Mar 3, 2009 at 5:09 AM, David M. [email protected]
wrote:

view/edit source code than to simply right-click on somefile.rb and
opening it in wordpad.

The main question you need to ask yourself is, why don’t you want Joe to do
that?

If your goal is to prevent others from taking your code, repackaging it, and
selling it as their own, that’s fine, although there are better ways of
doing it – like legal measures.

You know, I see this argument repeated from time to time on the ruby
mailing list and I have to disagree. Legal measures are a (expensive)
way of defending your intellectual property, but preventing access is
the easiest and by far the cheapest. Any time you have to do something
with the word “legal” in it, it’s costing you hourly money. For a
small shop, this can often be debilitating.

The only time legal measures would be pointed out as a better option
than prevention…is when the option for prevention doesn’t exist…

John

Err, not to attempt to de-rail a good open vs closed argument, but
lets look at what the guy said,

“Im not concerned about reverse engineering or cracks being made for my
software. All I want is to be able to distribute it the traditional way
like most commercial software is”

It sounds to me like the main thing he wants to make a self contained
installer that bundles up everything needed for the app to run, so
it’s transparent to the user whether it’s ruby, C#, python or Java.

That’s rather admirable, especially considering that even some
Microsoft downloads have dependencies that aren’t auto-installed.

What are the ways do do that? From hardest to easiest:
A) Have the installer check for a compatible ruby then install if
necessary (I used to make installers for work, this method may really
suck unless someone has already made a template, or the installer
software already supports it)
B) Install just enough of a ruby distro local to the applications
directory (lots of legwork for you, but maybe worth it)
C) Compile the application with JRuby, install the requisite JRuby
jars (there’s only one or two, right?), and have the installer install
Java if necessary (relatively easy, since there are lots of templates
and installers that already support installing Java, if necessary)
D) Compile the application using ruby2c or ruby2cext or something
similar, and distribute the program with a static ruby.exe + one huge
honkin .so that it loads.
E) Magically compile the application to a native windows binary…

I’d say A is in many ways best, since the user then has a full ruby
stack ever-after, but C looks really really inviting too.

–Kyle

On Mar 3, 2009, at 2:51 PM, John W. wrote:

right, but
If your goal is to prevent others from taking your code,
small shop, this can often be debilitating.

The only time legal measures would be pointed out as a better option
than prevention…is when the option for prevention doesn’t exist…

John

My argument is usually a different one: is your code sufficiently
interesting and reusable enough to be stolen?

Usally, programs are stolen entirely, not in parts. No part of code
blurring can fix that.

There are solutions to this (code obfuscation, removing comments,
etc.) that make it harder for uninitated thieves, but a lot of people
just don’t see a need for them. So, no one implements them. If you see
the need: go ahead.

It is a problem of introspective languages since day 1: if the program
knows everything about itself, everyone can make the program speak
about itself.

Regards,
Florian


Florian G.

smtp: [email protected]
jabber: [email protected]
gpg: 533148E2

Note on option B, “Shoes” by why the lucky stiff works this way.
There may be notes on the shoes website about how the installer was
made. Or he may just share the files for making the installer if you
ask.

On Mar 3, 2009, at 5:02 PM, Kyle S. wrote:

“Im not concerned about reverse engineering or cracks being made for
my
software. All I want is to be able to distribute it the traditional
way
like most commercial software is”

In the first post, he also said that he wanted to protect his source
code.

But, i forgot:

http://rawr.rubyforge.org/

is a good option to do that.

Regards,
Florian


Florian G.

smtp: [email protected]
jabber: [email protected]
gpg: 533148E2

Thanks Kyle and Florian, very usefull information

There may be notes on the shoes website about how the installer was
made.

Here is a short description on how it works:
http://hackety.org/2008/06/19/stampingExesAndDmgs.html

Mailinglist:
http://news.gmane.org/gmane.comp.lib.shoes

  • Axel

Rick DeNatale wrote:

That is not entirely true. Or rather, it can be “decompiled”, all right,
but not into anything resembling the original source code.

Actually closer than you might think:

require ‘rubygems’
require ‘ruby2ruby’

I was speaking of compiled languages in general. As a trivial example, a
common C optimization is to inline functions which are below a certain
size. Now, when decompiling, how do I know what was inlined, and what
really should be duplicate code?

Oh, and not all compiled versions preserve debugging symbols, meaning
any code that isn’t actually part of an external API is likely
completely without comments, variable names, method names, etc…

Now, Ruby tends to be much more dynamic, meaning less of the code can be
discarded by the compiler. But that doesn’t mean it will look like you
expect. For example:

class Foo
%w(one two three four five).each_with_index do |name, index|
define_method(name) { index + 1 }
end
end

puts Ruby2Ruby.translate Foo

produces:

class Foo <
Object
def
five
(index +
1)

end

def four
(index + 1)
end

def one
(index + 1)
end

def three
(index + 1)
end

def two
(index + 1)
end
end

Completely out of order, I have no idea what “index” means in that
context, and it only bears a vague resemblance to the source code used.

On Wed, Mar 4, 2009 at 6:21 AM, David M. [email protected]
wrote:

No. But there are technical reasons it’s hard to create one.

The biggest one is reflection:

eval ‘class Fixnum; def +(other); 42; end; end’

Imagine the backflips a compiler would have to do in order to allow the
above to work. You’d have no choice but to include the entire compiler with
your program.

Heh. Just try and use software that relies heavily on reflection in a
compiled language. Supposedly .Net has reflection nativeley, but the
applications I’ve used that take advantage of it were horribly slow
and or unreliable. From what I’ve seen the compiled applications out
there that use reflection are either trivial, or slow.

–Kyle

On Mar 4, 2009, at 12:47 PM, David M. wrote:

decompiled,

require ‘rubygems’
require ‘ruby2ruby’

I was speaking of compiled languages in general. As a trivial
example, a common C optimization is to inline functions which are
below a certain size. Now, when decompiling, how do I know what was
inlined, and what really should be duplicate code?

Thats the problem of decompiling native code to a language. Usually,
Bytecodes like Java and .NET are very well decompilable, because they
retain a lot of the language instructions within the code. I suspect
the same to be true for YARV code. For example, inlined Code is
possible in Java, but there are still symbols for determining where it
originates from (for the sake of Backtraces for example).
In the case of Ruby, this also allows you to read stuff like your
dynamic method example.

Regards,
Florian


Florian G.

smtp: [email protected]
jabber: [email protected]
gpg: 533148E2

Sharagoz – wrote:

Im not concerned about reverse engineering or cracks being made for my
software. All I want is to be able to distribute it the traditional way
like most commercial software is (at least on the windows platform).

Great – glad to hear it. Until you derail the whole thing with:

Open source makes code stealing too easy.

So does distributing software. Again, this will fail. be prepared for
it.

That aside…

I find it strange that there isnt a compiler readily available for Ruby.
Is there a technical reason why there shouldnt be one?

No. But there are technical reasons it’s hard to create one.

The biggest one is reflection:

eval ‘class Fixnum; def +(other); 42; end; end’

Imagine the backflips a compiler would have to do in order to allow the
above to work. You’d have no choice but to include the entire compiler
with your program.

If you then start hacking off every piece of metaprogramming and wizardy
that makes Ruby hard to compile, you’re killing a lot of what makes Ruby
so great.

Is it because Ruby is ment to be pure open source and never used in the
commercial sector?

I think the Rails crowd might have something to say about that.

It’s not that anyone disapproves of you distributing a proprietary app.
It’s just a hard problem that open source people aren’t likely to want
to put much time into. After all, open source projects have no problem
distributing as source code.

That said, one of the side effects of JRuby and IronRuby is that you can
probably find a way to compile to Java or .NET bytecode, and I’m sure
there are reasonable ways to either compile these, or distribute them
with something that makes it easy to install the runtime.

On Wed, Mar 4, 2009 at 12:58 PM, Randall Alexander
[email protected] wrote:

The Spring Framework uses a lot of reflection yet many would not call it
trivial. Â We use reflection in our enterprise because it is the best way to
solve a problem.
Fair enough. I never argued that it wasn’t the best way to solve some
problems, just that the last time I used a heavily reflected compiled
app (2007?) it was a dog. I should have made it more clear that in my
experiences were with .Net applications.

If your runtime engine does look aheads (which many modern ones do) then the
interpreter can have the class evaluated and loaded before it is ever used.
One of the factors of that working is the size of the class and everything
the class needs. Â We ran a few tests for our enterprise and determined that
if the class was not a heavy weight class then there was no real performance
penalty (i.e. response time). Ironically it actually speed things up over
Ahh. The ones I was working in had some pretty heavy classes. Maybe
reflection wasn’t the best way then. I dunno. Would you say that a
caveat for efficient reflection is fairly light-weight classes?

–Kyle

On Wed, 04 Mar 2009 11:52:29 -0500, Florian G. wrote:

My second concern is protecting source code. I realize that
Actually closer than you might think:

Thats the problem of decompiling native code to a language. Usually,
Bytecodes like Java and .NET are very well decompilable, because they
retain a lot of the language instructions within the code. I suspect the
same to be true for YARV code. For example, inlined Code is possible in
Java, but there are still symbols for determining where it originates
from (for the sake of Backtraces for example). In the case of Ruby, this
also allows you to read stuff like your dynamic method example.

But decompiling the Java bytecode generated by JRuby would be pretty
much
impossible because it has crazy things in it like call-site caches. The
reason why the Java bytecode can be decompiled into the equivalent Java
source code is because (a) the Java bytecode keeps a lot more
information
around, (b) because Java is the C of the JVM, and © because in Java,
the JVM does the optimization, not the compiler.

–Ken

The Spring Framework uses a lot of reflection yet many would not call it
trivial. We use reflection in our enterprise because it is the best way
to
solve a problem.

As far as it being slow there are a lot of cavities to that. It being
slow
used to be the case but the blanket statement of all is not true. The
reason why it was always slow is because instead of the compiler do a
lot of
the work the interpreter has to do the compilers work now in addition to
what it already had to do with a precompiled class.

If your runtime engine does look aheads (which many modern ones do) then
the
interpreter can have the class evaluated and loaded before it is ever
used.
One of the factors of that working is the size of the class and
everything
the class needs. We ran a few tests for our enterprise and determined
that
if the class was not a heavy weight class then there was no real
performance
penalty (i.e. response time). Ironically it actually speed things up
over
the code that needed to do the same thing, in a non “reflection” based
algorithm.

There are a number of other reasons why an application can be trivial or
slow, but it does not necessarily mean it is because of reflection.