Создание EXE файла из ruby скрипта при помощи ocra на примере утилиты командной строки, посылающей XMPP (Jabber) уведомления из песочницы

Ruby*
Понадобилось мне, чтобы торрент клиент оповещал меня в QIP о закачке очередной порции добра.

Ринулся я искать подходящую утилиту с интерфейсом командной строки для отправки XMPP сообщений… и ничего не нашел — кругом клиенты, не заточенные для нужд автоматизации. Отсутствие очевидных кандидатов подвигло меня к написанию собственной утилиты.

Для того, чтобы быстро сваять что-то для собственного потребления я использую ruby.

Весь код помещается в 12 строк, хотя конечно можно ужать и в одну.
require 'rubygems'
require 'xmpp4r/client'

include Jabber

server, login, password = "qip.ru", "my_login", "my_password"
to, subject, body       = "someone@qip.ru", "XMPP4R test", "Hi, this is my first try from XMPP4R!!!"

Jabber::debug = true
jid=JID::new "#{login}@#{server}" 
cl = Client::new(jid)
cl.connect
cl.auth password

m = Message::new(to, body).set_type(:normal).set_id('1').set_subject(subject)
cl.send m


После того, как я убедился что скрипт работает, решил реализовать разбор праметров командной строки и возможность передавать скрипту постоянные параметры ( такие как [сервер, логин, пароль] ) через конфигурационный файл, чтобы не перегружать командную строку. Что из этого получилось можно посмотреть тут. Или по прямым ссылкам: xmpp_sender.rb, xmpp_sender.yml, setup.exe

Запущенная без параметров эта утилита прочтет параметры из конфига и пошлет тестовое собщение на специальный тестовый qip-логин. Чтобы увидеть справку используйте параметр -h. Чтобы воспользоваться этой утилитой для отсылки уведомлений rtorrent-ом, читайте тут

После того как утилита была написана и протестирована, я задумался о том, что неплохо ее оформить в виде exe файла, который можно было бы просто поместить в папку на компьютере и настроить вызов этого exe из rtorrent. А то получается довольно неудобно — надо ставить ruby, указывать в rtorrent вызов ruby c путем к скрипту, с путем к конфигу… Да и просто стало интересно разобраться с темой упаковки ruby приложения в exe файл. Помню, еще пару лет назад пробовал rubyscript2exe и ocra, но почему-то тогда они меня не впечатлили — не помню уже подробностей, но что-то было кривовато. В этот раз решил попробовать снова.

Согласно ruby-toolbox Есть три пакета для упаковки ruby в исполняемый файл: rubyscript (уже не развивается), crate, ocra. Я сразу начал с ocra, как с самого популярного.

Ocra фактически создает самораспаковывающийся архив, в который упаковывает интерпретатор ruby, геммы и собственно ruby-скрипты приложения. При запуске exe архив распаковывается во временный каталог, запускает в нем ruby со скриптом и передает ему параметры своей командной строки.

Скомпилировался exe без сложностей: ocra xmpp_sender.rb
Я запустил его и получил на экран сообщение от встроенного файрвола Windows с запросом о том, заблокировать или разблокировать ruby — выбрал разблокировать. Тем не менее этот запрос появлялся каждый запуск моего exe.

Неудивительно, т.к. exe распаковывался всякий раз в разную папку во временном каталоге и поэтому файрвол считал его новой программой.

На форуме рубистов мне посоветовали воспользоваться Inno Setup — программой для создания инсталляторов Windows программ.

Признаться, я сразу подумал о том, что получившийся инсталлятор будет запускать инсталлятор руби, как это бывает, когда ставишь какую-нибудь игру — сначала запускается отдельный инсталлятор directx, потом origin, потом еще чего-нибудь и только потом игра, но я ошибся.

Ocra так удачно использует Inno Setup, что интерпретатор ruby устанавливается вместе с exe и rb-скриптами одновременно и незаметно для пользователя. Так, как интерпретатор устанавливается однократно и в определенный каталог, то и разблокировать его файрволу нужно будет всего лишь раз.

Перед запуском ocra нужно запустить Inno Setup и создать проект инсталлятора в папке с приложением ruby.

При запуске надо выбрать создание нового скрипта при помощи Мастера. Далее все тривиально. На стадии выбора файлов естественно нужно выбрать «The application doesn't have a main executable file», затем надо выбрать файлы, которые должен установить инсталлятор. Не нужно выбирать rb-файлы, т.к. они будут выбраны ocra автоматически. В моем проекте я выбрал файлы readme, license, yml-конфиг.

После того как создан скрипт файл инсталлатора, он будет показан с вопросом надо ли его компилировать. Следует кликнуть Нет.

Запускаю опять ocra:
ocra --chdir-first --no-lzma --innosetup xmpp_sender.iss --icon doc/images/logo_icon.ico xmpp_sender.rb

Ocra запустит скрипт и в процессе его работы будет наблюдать какие приложению требуются геммы и dll-и, и после завершения пропишет их все в проект инсталлятора и запустит Inno Setup, который и соберет setup.exe.

C:\InstantRails\ruby_apps\xmpp_sender>ocra --chdir-first --no-lzma --innosetup xmpp_sender.iss --icon doc/images/logo_icon.ico xmpp_sender.rb
=== Loading script to check dependencies
working directory: ./
@server: qip.ru
@login: xmmp-sender
@password: xmmp-rednes
@to: xmmp-sender-test
@subject: first run
@body: Hey Zloy, I tried xmpp sender too. Best wishes!
=== Detected gem xmpp4r-0.5 (loaded, files)
=== 10 files, 39247 bytes
=== Building xmpp_sender.exe
=== Adding user-supplied source files
=== Adding ruby executable ruby.exe
=== Adding detected DLL C:/InstantRails/ruby/bin/libeay32-0.9.8-msvcrt.dll
=== Adding detected DLL C:/InstantRails/ruby/bin/ssleay32-0.9.8-msvcrt.dll
=== Adding detected DLL C:/InstantRails/ruby/bin/ZLIB1.dll
=== Adding library files
=== Running InnoSetup compiler ISCC

C:\InstantRails\ruby_apps\xmpp_sender>


Inno Setup создаст подпапку Output куда и поместит готовый Setup.exe. Эту папку можно поменять в скрипте на OutputDir=. чтобы Setup.exe был в корне папки установки.

Размер инсталлятора оказался ~1,5 Мб, что по нынешним меркам совсем мало. Размер каталога, установленного инсталлятором приложения, составляет ~5 Мб, что конечно многовато для подобной утилиты, но меня устраивает.

В итоге:
  1. легко распространять — один файл setup.exe весом в 1.5 Мб
  2. просто устанавливать и сносить
  3. можно легко изменить для собственых нужд, т.к. исходники прилагаются


В общем, рекомендую ruby и ocra!
+22
3 февраля 2012, 08:57
74
Zloy1 24,0

комментарии (6)

+3
zodiac #
Шикарное название топика!
0
Zloy1 #
Спасибо!
+2
Latobco #
Название топика здесь — по сути почти половина полезного материала :)
Можно еще добавить все параметры для ocra і profit
0
Deffe #
Так это компиляция руби-скрипта? Я то уж было подумал, что тут код для генерации отдельного исполняемого файла.
0
Deffe #
Т.е. одна программа генерирует другую
0
Zloy1 #
Ээээ… хм, ошибся в названии торрент-клиента. Вместо rtorrent надо читать utorrenrt

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.