Distributing the RubyCocoa Framework
You might want to distribute RubyCocoa with your application to not force your users to systematically install RubyCocoa on their machine in order to use your application.
RubyCocoa by default builds as an embeddable framework. It means that you can simply copy it inside your application bundle. You can do this fairly easily:
- Add a new Copy Files Phase to the appropriate target.
- Set the destination to Frameworks.
- Drag RubyCocoa.framework into the new copy files group.
Distributing the Ruby Libraries and Gems
If your application uses RubyGems, you might also want to distribute it as well as the necessary gems. You application may also depend on a third-party Ruby library.
As you can imagine, in order to address this you will have to customize the build of your application target to explicitly copy the required Ruby files and libraries inside the Resources folder of your application. And you could also have to do more complicated stuff to handle the gems.
RubyCocoa ships with a tool called standaloneify.rb, in framework/tool, that will embed the Ruby libraries and gems your application depends on. Usage is simple:
$ ruby standalonify.rb -d MyStandaloneProg.app MyBuiltinProg.app
Distributing the Ruby Runtime Library
standalonify won't embed the Ruby runtime library, libruby.1.dylib, but it's possible to do it, by following for example the steps below:
- Explicitly link against your specific version of libruby.1.dylib, by drag-and-dropping it in your Xcode project. Making sure the library is also in the project directory may help.
- Modify your target build so that the library will be copied inside your application bundle. An easy way is to add it to the already-existing Copy Bundle Resources phase. The library will therefore be copied in the Resources directory of your application bundle.
- Add a new Run Script Build Phase that will call the install_name_tool program on your application binary, to force the link against your embedded version of libruby.1.dylib at runtime. Here is an example that uses /usr/bin/env ruby as its shell:
require 'pathname'
exec = File.join(ENV['TARGET_BUILD_DIR'], ENV['EXECUTABLE_PATH'])
old = Pathname.new('/usr/lib/libruby.1.dylib').realpath
new = '@executable_path/../Resources/libruby.1.dylib'
system("install_name_tool -change '#{old}' '#{new}' '#{exec}'") or exit 1
exec = File.join(ENV['TARGET_BUILD_DIR'], ENV['EXECUTABLE_PATH'])
old = Pathname.new('/usr/lib/libruby.1.dylib').realpath
new = '@executable_path/../Resources/libruby.1.dylib'
system("install_name_tool -change '#{old}' '#{new}' '#{exec}'") or exit 1