← Blog

OCRAN:RubyスクリプトをWindows・Linux・macOS向けの実行ファイルにする

私は OCRAN というRubyのgemをメンテナンスしています。OCRANはRubyアプリケーションを配布用にパッケージするツールで、スクリプト、Rubyインタプリタ、gem、必要なネイティブライブラリを1つにまとめます。そのため、受け取った人はRubyをインストールしなくてもプログラムを実行できます。バージョン1.4からは、Windowsに加えてLinuxとmacOSにも対応しました。

OCRANは「One-Click Ruby Application Next」の略です。この記事では、OCRANの成り立ち、使い方、最近の変更点を紹介します。

OCRAからOCRANへ

OCRANは、Lars Christensenさんが2009年に始めた OCRA(One-Click Ruby Application Builder)のフォークです。OCRAは長い間、RubyスクリプトからWindowsの .exe を作る定番の方法でした。ただ、最後のリリースは2020年3月の1.3.11で、変更履歴に記載されている対応バージョンはRuby 2.2〜2.7です。

私は2023年に、新しいRubyでも使い続けられるようにOCRAをフォークしました。最初のOCRANリリースである1.3.12は、Ruby 3.2まで対応していました。開発は私ひとりで進めているわけではありません。gemspecには共著者としてshinokaroさんが載っており、フォーク以降のコミットの多くはshinokaroさんによるものです。土台を作ったLars Christensenさんも、引き続き作者として記載されています。

まだOCRAを使っている方向けに、OCRAからOCRANへの移行ガイドを用意しました。コマンドラインオプションは同じです。

OCRANが出力するもの

出力形式は4種類あります。

Windowsでは、Inno Setup(--innosetup)を使って本格的なインストーラーを作ることもできます。

使ってみる

OCRANにはRuby 3.2以降が必要です。

gem install ocran
ocran script.rb

これで script.rb が実行され、読み込まれたファイルやライブラリが記録されます。そのうえで、Windowsでは script.exe、LinuxとmacOSでは script が作られます。

ほかの出力形式は次のとおりです。

ocran --output-dir myapp/ script.rb
ocran --output-zip myapp.zip script.rb
ocran --macosx-bundle --output MyApp --bundle-id com.example.myapp --icon icon.icns script.rb

追加のファイルやディレクトリ、globパターンはそのまま後ろに並べます。スクリプトに渡す引数は -- の後に書きます。

ocran script.rb assets/**/*.png
ocran script.rb -- --some-option=value

すべてのオプションは ocran --help で確認できます。

依存関係の検出のしくみ

OCRANはコードを静的に解析するのではなく、ビルド中に実際にスクリプトを実行し、require や load で読み込まれたものをすべて取り込みます。条件によってだけ読み込まれるコードは、ビルド時の実行でその条件を通った場合にしか含まれません。

ウィンドウを開いたり入力を待ったりするプログラムでは、Ocran 定数を確認すると便利です。この定数はOCRANがビルドしている間だけ定義されます。

app = MyApp.new
app.main_loop unless defined?(Ocran)

実行時にgemのファイルが足りない場合は、まず --gem-all=gemname、次に --gem-full=gemname を試してください。Bundlerを使っているプロジェクトでは、--gemfile Gemfile でGemfileに書かれたgemをすべて含められます。

自己展開型の実行ファイルが動いているとき、$0 は一時ディレクトリの中を指します。一方、環境変数 OCRAN_EXECUTABLE には実行ファイル自体のフルパスが入っているので、実行ファイルと同じ場所に置いたファイルを探すときに使えます。

base_dir = File.dirname(ENV["OCRAN_EXECUTABLE"].to_s)

注意点

最近の変更点

すべての変更は CHANGELOG にあります。

フィードバック

うまく動かないときは、まず GitHubのIssue を確認し、同じ問題がなければ新しく登録してください。Rubyのバージョン、OS、実行した ocran コマンドを書いていただけると、とても助かります。