naoki86star

インターネットの片隅でなにかしら書いてみる

launch4jの覚書

 launch4jという、javaの実行可能なjar形式を実行可能Windows exe形式にラップしてくれるソフトウェアがある。まず基本的な使い方は、UIを起動して、javaの実行環境としてのjarファイル、実行可能Windows exeの出力ファイル名を指定し、出力実行すると、設定をxmlに保存すると同時にexe形式ファイルを出力する。設定の際にjvmのバージョン等いくらかのパラメータも指定できる。

 HPの冒頭にCross-platform Java executable wrapperとあるが、Windows, macOS, Linuxのいずれからでも、jarをwrapしたwindows形式を出力するのをcrossと呼んでて、各OSの実行形式に(例えばLinuxに)出力してくれるわけではない。また、exeはあくまでjarを起動する手順を提供し、jar自体を内包するわけではない*1

 使い方のひとつとして、UIで出力した設定ファイルを引数として指定すると、UIを開くことなくラッパーexeを出力してくれる。設定xmlを用意しておけば、コマンドラインに閉じて.jar 作成=> .exeの流れを作れるので、古風に言えばmakeファイル、というかjavaなので、ant等なビルドツールに含めたbuild手順を作れることになる。

 Windowのexeを出力する仕掛けは、launch4jにGNU binutils のldが3OS分(+linux64bit版)含まれていて、さらにWindowsのlibcにあたるいくらかのファイルまで含まれている。これに設定そのものと設定により制御されるjarを起動するコンパイルされた手順コードを、ldを使って実行形式をリンクしている。その手順は、net.sf.launcher4j.Buildの中にある。

起動しているコマンドラインはこんな感じ

windres --preprocessor=[type|cat] -J rc -O coff -F pe-i386 rcfile rcoutfile 
ld -mi386pe --oformat pei-i386 --dynamicbase --nxcompat --no-seh --subsystem [windows|console] -s headobjs rcoutfile libfiles -o outfile

 実は、windresというコマンドがGNU binutilisに入ってるの知らなかった。Windowsの実行形式をエクスプローラで参照するとき出てくるバージョン番号とかをリソースファイル(.rc)で書いてsdkのrc.exeでコンパイルすると思うが、rc.exeがgnuでwindresというコマンドだったということ。当然windows専用なわけである。

 libc相当の必要なファイルをそろえれば、linuxないし、macのwrapper実行形式も出力できそうな気がしたのだが、このlaunch4jを改変してそれをするのはすぐには無理っぽい。まずrcファイルに”リソース”要素としてjarファイル名などが入っているので、RC(リソースファイル)という仕組みを持たないlinuxないし、macではなにか別の手段が必要*2。さらにソースツリー上のhead_srcが、launch4jでのjar起動制御をやっていて、これがWinAPI依存で書かれている。

 ひとつ勝手な憶測で、Windowsのために何かしらexe形式wrapperが必要で生まれたのかもで、Linux/macOs/その他ならば、sh/bashスクリプトでラップするのが適しているのだと思う。

追記)jpackageというjreバンドル作るコマンドがjdk16から登場しているので、もう市井のwrapper作成は不要なのかもです。

*1:jarを内包するオプションがありました。動作を試してませんが。。。

*2:設定xmlをそのまま参照でいいのかもしれないが