This is PerlMonks "Mobile"

Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

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 App::Packer, I thought I'd share a step-by-step tutorial for those who need it.

Preface

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 perl2exe. And probably were discouraged by the steep price tag. Mattia Barbon created a wonderful set of modules distributed as App::Packer that can do the same thing for you. For free, and with source included.

This tutorial is geared towards not-so-experienced users of perl on Win32 platforms. Much of it should apply for Linux/Unix as well.

Caveats

App::Packer is not a compiler. It merely packs up your script as well as all the modules needed in a nice bundle. This means:

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.

Installing App::Packer

First, do a binary install using ppm:

ppm install http://wwwstud.dsi.unive.it/~mbarbon/p2e/App-Packer.ppd

Additionally, you need a modified version of Module::Info, available from http://wwwstud.dsi.unive.it/~mbarbon/p2e/. Install it using the usual procedure:

perl Makefile.PL
nmake
nmake install

If you don't have nmake yet, get it by downloading nmake15.exe.

Creating an executable

There is a script p2e.pl supplied with App::Packer, which should be inside the directory perl\site\lib\App. You might want to copy it to another directory for your convenience. The first step to create an executable is

perl p2e.pl myapp.pl -o myapp.exe

If your script is using a lot of modules, this might take a while, because

App::Packer 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 p2e.pl will be much faster because the information about the modules analyzed is stored in a cache.

Something's missing... (1)

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 Dependency Walker. Run it, drag'n'drop your executable on it and select Profile|Start Profiling 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 perl\site\lib\auto) 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 perl\bin\perl56.dll).

Something's missing... (2)

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 App::Packer doesn't understand. For example, XML::Parser uses File::Spec. In this case, call p2e.pl as follows:

perl p2e.pl myapp.pl -o myapp.exe --add-module File::Spec

You can use --add-module several times to add several modules.

Shipping your application

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.

The finishing touches

The created executable is a console application, 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 exetype.pl, then do a

perl exetype.pl myapp.exe WINDOWS

Voilà!

Final thoughts

More information about App::Packer can be found on CPAN. 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 App::Packer.

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.

EDIT: added readmore tag, edited final thoughts

Replies are listed 'Best First'.
Re: Shipping standalone perl apps on Win32
by Courage (Parson) on Nov 23, 2002 at 09:43 UTC
    Great!
    Really interesting, I think I'll use it.

    Could you please explain in two words:

    • how required module is unpacked from executable?
    • Is it "saved" in compressed format?
    • Am I right when I am thinking thatno extra temporary files or directories are required for execution?

    Also I want to share my own experience on creating independent distributions.

    I use similar approach manually for perl-5.6.0 on Win32 for a quite long time.
    I succeeded "packing" perl-5.6.1+Tk+Compress::Zlib+(some-other-modules) into some 20 files, most of which are dll-s on my Win32 machine and all text modules being packed into "modules.pm" file (~130Kb in size) which at bootstrap time is unpacked into normal perl modules set.
    Having in total 20 files with total size of ~2Mb I have perl with Tk and those selected modules, which I often use.
    Very convenient to make independent distributions...

    Courage, the Cowardly Dog

      Thanks for the good question, Courage; I should have mentioned that. I can't really give an authoritative answer about the internals of App::Packer, but I'll tell you what I know :-)

      App::Packer does use compression. My guess is that the main perl file and the module sources are all inside the executable file, in a compressed form. Smaller apps (I quickly tried one that uses a very small test module) don't seem to create temporary files. However, another app I "packaged" that uses Wx, XML::Parser and File::Spec) creates three temporary DLL files upon startup.

      Hope that helps...

      By the way -- thanks to the perl monks for the warm reception of this tutorial. I asked myself whether I should write it or not, and then decided to just do it, even if it is just to get it sorted out for myself again. The response encouraged me to be not so hesitant in the future.

      Hi, I followed the instructions and created the exe file. when i shipped it to another host, it didnt prompt me for the Perl58.dll So, is there way where i can have it packaged in the exe file itself following this pattern perl p2e.pl DCP_extract.pl -o LogMiner.exe add Perl58.dll My next biggest concern is: the user needs to enter some inputs while exe file runs. so i need to constantly view the console. How is this possible as the console closes as soon as i enter the first input?? Thankyou very much!!! Radhika
Re: Shipping standalone perl apps on Win32
by Jenda (Abbot) on Nov 28, 2002 at 01:11 UTC

    Just a question ... you say that after you generate the EXE you may need to copy the DLLs it uses into the same directory as is the EXE. But there's a big problem with this. Suppose you use two modules Foo::Something and Bar::Something. Both these modules have an XS part and therefore a DLL. But both DLLs are named Something.DLL !!!

    How do you solve this?

    I'm not sure about perl2exe, but PerlApp (from ActiveState's PDK) solves this by renaming the DLLs based on their MD5 hash (eg. 818b4489de35cc38bfbca181f20a1f1e.dll) and somehow changes the DLL loading so that the right DLL is found. Plus PerlApp and perl2exe packs the DLLs into the EXE so you do not have to care about them. To install your application you only have to copy the EXE.

    I don't say App::Packer is useless, far from it, but I'm afraid it'll take some time for it to get where perl2exe and PerlApp are now.

    Jenda

      You're perfectly right, although perl2exe and perlApp seem to have their own problems :-)

      It seems like PAR and App::Packer might be merging soon, so let's hope something good comes out of this marriage.

      On another note -- another solution I found proposed is to just put wperl.exe, perl56.dll, the script and the necessary libraries in lib/ into a directory and install it like that. It also works nicely, and starts up faster. You could always create a shortcut to start the app.

        I use tinyperl to do make small exe file, It is quite buggy but it works fine for very basics (not extra libraries used) things. Usually my exe are 94 Ko. plus the perl58.dll which is 380 ko. Do you think I can do stuff like that with a regular perl exe from your packager?? What would be the size of it?? thanx.. piČ
App::Packer vs. PAR
by laughingboy (Monk) on Nov 26, 2002 at 00:19 UTC
    Good info!

    Does anyone know the pros and cons of using this versus PAR?

    laughingboy

Re: Shipping standalone perl apps on Win32
by axelrose (Scribe) on Nov 25, 2002 at 17:58 UTC
    For MacPerl (classic MacOS) I build something similar. Anybody in need might contact me.

    Axel
      I am new to Mac world but have some perl scripts that I want to make as standalong apps for MacOS. Can you provide me some pointers or tutorials?
        Please make sure you mean MacOS 9. I can't help with MacOS X.
        Just drop a note with your email address and I'll send the stuff needed.
Re: Shipping standalone perl apps on Win32
by Hena (Friar) on Oct 23, 2006 at 10:00 UTC
    Just found a need to make a win32 binary from my two perl scripts. Is this package still usable and/or should I use something else nowdays? Eg. has it been merged with PAR and what is the result.