perltutorial
crenz
<p>Note-- Not everyone thinks that packing up perl applications into executables is a good idea. I am aware of the drawbacks (and do mention them, see "caveats"), but think there are some cases where it is useful. After fiddling around with <tt>App::Packer</tt>, I thought I'd share a step-by-step tutorial for those who need it.</p>
<h2>Preface</h2>
<p>Have you had .EXE-envy? That is, have you ever wished it would be as easy to
ship your perl applications as it is with C/C++ or VisualBasic programs, without
having to make sure perl is installed on the user's computer? If yes, you probably
heard of <a href="http://www.indigostar.com/perl2exe.htm">perl2exe</a>. And
probably were discouraged by the steep price tag. Mattia Barbon created a wonderful
set of modules distributed as <tt>App::Packer</tt> that can do the same thing
for you. For free, and with source included.</p>
<p>This tutorial is geared towards not-so-experienced users of perl on Win32 platforms.
Much of it should apply for Linux/Unix as well.</p>
<readmore>
<h2>Caveats</h2>
<p><tt>App::Packer</tt> is <i>not</i> a compiler. It merely packs up your script
as well as all the modules needed in a nice bundle. This means:</p>
<ul>
<li>Your application will remain an interpreted perl script.</li>
<li>Your source code will still be accessible.</li>
<li>The run-time behaviour will be the same.</li>
<li>The startup time will actually be <i>longer</i>, because the "bundle"
needs to be unpacked when the application is started.</li>
<li>You will need to ship additional DLL files.</li>
</ul>
<p>For some applications, it might be much more practical to create a perl "distribution"
on CD containing ActivePerl or IndigoPerl and the additional modules you are
using, together with your application.</p>
<h2>Installing App::Packer</h2>
<p>First, do a binary install using ppm:</p>
<p><tt>ppm install http://wwwstud.dsi.unive.it/~mbarbon/p2e/App-Packer.ppd</tt></p>
<p>Additionally, you need a modified version of <tt>Module::Info</tt>, available
from <a href="http://wwwstud.dsi.unive.it/%7Embarbon/p2e/">http://wwwstud.dsi.unive.it/~mbarbon/p2e/</a>.
Install it using the usual procedure:</p>
<p><tt>perl Makefile.PL<br>
nmake<br>
nmake install</tt></p>
<p>If you don't have nmake yet, get it by downloading <a href="http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe">nmake15.exe</a>.
</p>
<h2>Creating an executable</h2>
<p>There is a script <tt>p2e.pl</tt> supplied with <tt>App::Packer</tt>, which
should be inside the directory <tt>perl\site\lib\App</tt>. You might want to
copy it to another directory for your convenience. The first step to create
an executable is</p>
<p><tt>perl p2e.pl myapp.pl -o myapp.exe</tt></p>
<p>If your script is using a lot of modules, this might take a while, because
</p>
<p><tt>App::Packer</tt> needs to find out the dependencies between the modules
used, so if your script is using a lot of modules, this might take a while.
This is especially true for large GUI packages like Wx. Future calls of <tt>p2e.pl</tt>
will be much faster because the information about the modules analyzed is stored
in a cache.</p>
<h2>Something's missing... (1)</h2>
<p>When starting the newly generated program, you might encounter a Windows error
message about missing library files. This is probably because you are using
a XS module. On Win32, perl stores the binary code in XS modules as DLL files
inside your module paths. Unfortunately, Windows doesn't tell you the exact
name of the DLL. If you have no idea which file is missing, get <a href="http://www.dependencywalker.com/">Dependency
Walker</a>. Run it, drag'n'drop your executable on it and select <i>Profile|Start
Profiling</i> from the menu. After a while, your program will abort and Dependency
Walker displays the name of the DLL that is missing. Go to your perl directory,
search it for that DLL (usually it is somewhere in <tt>perl\site\lib\auto</tt>)
and copy it over into your executable's directory. If your PATH variable doesn't
include your perl directory, you will also need to copy the perl DLL (usually
called something like <tt>perl\bin\perl56.dll</tt>).</p>
<h2>Something's missing... (2)</h2>
<p>Having done that, you might still encounter perl error messages that tell you
that a certain module could not be found. Sometimes modules use other modules
in weird ways that <tt>App::Packer</tt> doesn't understand. For example, <tt>XML::Parser</tt>
uses <tt>File::Spec</tt>. In this case, call p2e.pl as follows:</p>
<p><tt>perl p2e.pl myapp.pl -o myapp.exe --add-module File::Spec</tt></p>
<p>You can use <tt>--add-module</tt> several times to add several modules.</p>
<h2>Shipping your application</h2>
<p>When sharing your application with others, make sure you include all the DLL
files needed. Even if you do not use any other module and your executable runs
"out of the box" on your computer, you will still need to include
the perl DLL as mentined above, or else others will not be able to execute your
application. </p>
<h2>The finishing touches</h2>
<p>The created executable is a <i>console application</i>, so you will still see
a console window after you started it. To prevent this, you need to change the
executable type. Download the source code for <a href="http://jenda.krynicky.cz/perl/GUIscripts.html">exetype.pl</a>,
then do a</p>
<p><tt>perl exetype.pl myapp.exe WINDOWS</tt></p>
<p>Voilà!</p>
<h2>Final thoughts</h2>
<p>More information about <tt>App::Packer</tt> can be found on <a href="http://search.cpan.org/search?query=App::Packer">CPAN</a>.
If you like it, consider sending Mattia Barbon an e-mail to praise him for his
work. If you have any amendments or corrections for this tutorial, please drop
me a line. Thanks to [Valdez] for telling me about <tt>App::Packer</tt>.</p>
<p>Large apps can take quite a while to start up, e.g. when using Wx, XML::Parser etc. Small apps tend to start very quickly. A "Hello world" can amount to ~15 KB (+ perl DLL) and run faster than you can blink, so don't hesitate to use this approach for small utilities, designed to be run e.g. on Windows startup.
<p><font size="-2"><i>EDIT: added readmore tag, edited final thoughts</i></font></p>