You might have come across the same problem I have faced pretty often: You want to write a small snippet of code for a friend who's not into programming to solve some task. You want to use the scripting language of your choice (yeah, Perl). But for many people, especially Windows users, explaining them how to install perl, install some modules from CPAN, and finally how to use the script from the command line is tedious and often takes more time than writing it in the first place. And sometimes it even takes more time than solving the task by hand which is quite frustrating.
So I always wanted to build stand-alone applications with a GUI for those cases. But building GUIs is usually a huge pain in the ass, so I always avoided it; until I got the idea to build web applications with Mojolicious as GUI. Building stand alone executables without the need of installing perl, modules, or libraries can be solved with PAR-Packer. So far, that was just a thought.
A few days ago I got a small task: My brother wanted an application to automatically correct one kind of systemic error in large data sets. So I wanted to put that idea to the test. It worked out quite well!
First, building a Mojolicious application is fun in its own. Don't forget to write portable code if you're developing on Linux for Windows. The problem itself also was quite easy to solve. What took more time was getting PAR-Packer to work on Windows.
I tried it in cygwin first. I had to solve some problems in myldr/Makefile.PL where paths were created using \ instead of / (don't make that error, just use File::Spec). Alas, that wasn't the end of it, as PAR failed most of its tests and I couldn't find a solution for that in short order.
Next in line was ActiveState Perl. Using ppm was easy, but the pp executable was created using perl 5.16.0, while the perl version I got with ActivePerl was 5.16.3. That's not compatible. And old versions of ActivePerl aren't available for free. So I tried to install it using cpan, but the executable compiled during the installation just didn't work.
Finally I tried Strawberry Perl. The installation of PAR-Packer (and Mojolicious) using cpan went smoothly on the first try.
Okay, great. Now I could work out the details. First, your script might want to read some files that have to be packed into the executable. To do that conveniently you want to change in the directory PAR extracted the files packed within your executable. Also, you don't want the user to have to pass parameters to your Mojolicious start script ("just double click it"). So I added the following lines:
Second, how to pack the executable with all dependencies? The following things are needed:
- The Mojo and Mojolicious modules
- Some Mojo(licious) data files, namely the folders Mojolicious/public, Mojolicious/templates and the file Mojo/entities.txt
- The shared libraries libeay32__.dll, zlib1__.dll and ssleay32__.dll
- The folders containing your Mojolicious application: lib, public and templates
To pack all necessary Mojo and Mojolicious modules, just pass -x to pp. That executes the program one time to collect run-time dependencies.
Putting all together, the batch file
-l libeay32__.dll ^
-l zlib1__.dll ^
-l ssleay32__.dll ^
-a lib ^
-a public ^
-a templates ^
-a "C:\strawberry\perl\site\lib\Mojo\entities.txt;Mojo\entities.txt" ^
-a "C:\strawberry\perl\site\lib\Mojolicious\public;Mojolicious\public" ^
-a "C:\strawberry\perl\site\lib\Mojolicious\templates;Mojolicious\templates" ^
does the trick.
One last thing: To make the "just double click" experience work, I wanted the browser window to open automatically. That's easy, on Windows you can call "start" to open the default browser. I added the following lines to the end of my startup routine (make sure you do that after setting up the routes :).