Mar 19, 2011

Deploy a Perl application on Windows

Suppose you have a Perl application for an end user but

  • probably your user don't know Perl exists
  • your user uses Windows
  • your user want just to click on a .exe to launch your program

What you will read it worked for me, feel free to improve it, adapt it to fit your needs and/or automate it as you like.
The only requirement needed is Strawberry Perl
Let's define some names so I can explain with my example how to deploy your Perl program on Windows: my program is called pni.exe, has a red mushroom icon,

and it is based on a CPAN module I wrote, called PNI::GUI::Tk.

PNI stands for Perl Node Interface, and PNI::GUI::Tk is a Tk based GUI for PNI with a script to launch it. It is really similar to a so called App, except that it is not under the App:: namespace.

Prepare to build you Perl app

First of all, get a Windows machine, ( this is the most difficult part for a lot of people that is allergic to Microsoft :-) then install the Strawberry Perl distribution, it is a really good way to feel unix-like on Windows.

Now, type
cpan PNI::GUI::Tk
to install the module and its dependencies that are Tk, PNI::Node::Tk and the PNI core module.

Now create a folder, called for instance PerlNodeInterface-windows-0.11, put the script inside, a README.txt file to be kind ( don't forget the .txt extension, since you are on Windows ) and a lib folder containing all dependencies. This is how it looks like, see below how to compile pni.exe.

There is a which launches the app:

#! env perl
use strict;
use warnings;
use PNI::GUI::Tk::App;
my $app = PNI::GUI::Tk::App->new;

Don't forget the auto folder for Tk since it is an XS module.

The dir tree it looks something like this:

Everything was there, from the beginning

Yes, but you know, most of the people in the world never typed
perldoc ExtUtils::Embed
I started from there, and I found all the informations to compile pni.exe ... so here we go!
perl -MExtUtils::Embed -e xsinit
will produce perlxsi.c, rename it pni.c and add a main function, like the interp.c from
perldoc perlembed
Then change the arguments in the main function and hardcode a -Ilib and the name of the script .

Something like this :

//argv[0] stores the relative path of the executable
argv[1] = "-Ilib";
//argv[2] is for programfile
argv[2] = "";

 Get a cool mushroom icon :-) and create a text file pni.rc containing this line
ID ICON "pni.ico"
then launch
windres pni.rc -o coff -o pnirc.o
Now you can compile pni.exe with gcc using options
-Wall -mwindows -o pni pnirc.o pni.c
and options coming from the output of
perl -MExtUtils::Embed -e ccopts
perl -MExtUtils::Embed -e ldopts

You can automate compilation with few lines of code:

use ExtUtils::Embed;
use PNI;
print "\nBuilding PNI $PNI::VERSION\n";
my $gcc_cmd = join( ' ' , 'gcc -Wall -mwindows -o pni pnirc.o pni.c' , &ccopts , &ldopts );
print STDOUT $gcc_cmd , "\n";
system( $gcc_cmd );


Finally zip your folder, since zip is supported natively on Windows, and you will get a ready for an user-friendly deploy.
If this procedure works and make sense for most of the perlish folks, Trawberry Perl could become a sort of JRE for Perl on Windows.
There are a lot of users out there that need our Perl programs, but they don' t need all the complexities behind.


  1. Hi Gianluca,

    I've just tried to follow Your instructions, but the command
    cpan PNI::GUI::Tk
    failed. Do You know the reason?


    C:\Documents and Settings\someone>cpan PNI::GUI::Tk
    CPAN: CPAN::SQLite loaded ok (v0.202)
    Database was generated on Fri, 15 Jun 2012 11:27:02 GMT
    Warning: Cannot install PNI::GUI::Tk, don't know what it is.
    Try the command

    i /PNI::GUI::Tk/

    to find objects with matching identifiers.
    CPAN: Time::HiRes loaded ok (v1.9724)

    1. Hi gimmi, that's because the module was deleted from CPAN ... you should try with an existing module.

    2. Why isn't the moduel in CPAN anymore?

    3. It was a too ambitious project for me, a graphic programming interface for genetic engineers: by now I suspended the project cause nobody joined and helped me. Anyway PNI::GUI::Tk was dropped cause I switched to an HTML interface with Mojolicious. The old repository is still online

  2. These directions are very ambiguous, I am trying to embed an existing Perl application into C. I don't use Perl. I downloaded the PNI package from you link in the comments, I tried executing the commands up to the line "perl -MExtUtils::Embed -e xsinit" in windows prompt, but nothing happened after that command, no error.

    I would recommend to please re-organize your instructions into step by step, including what folder to execute which commands from, so people can use this for reference when building Perl application in C.