How to turn a perl script into a windows exe

Created: 2009-02-03

Background

This page documents what I did to build a windows exe from a perl script originally developed under Solaris. The windows machine I used was running Windows XP Home.

One-time install and setup

Building a simple program

  C:\Documents and Settings\chad\My Documents\code\perl\test>dir
   Volume in drive C has no label.
   Volume Serial Number is 70E4-9676
  
   Directory of C:\Documents and Settings\chad\My Documents\code\perl\test
  
  01/20/2009  10:05 PM    <DIR>          .
  01/20/2009  10:05 PM    <DIR>          ..
  01/20/2009  10:05 PM                57 hello.pl
                 1 File(s)             57 bytes
                 2 Dir(s)  77,325,348,864 bytes free
  
  C:\Documents and Settings\chad\My Documents\code\perl\test>type hello.pl
  #!/usr/bin/perl -w
  use strict;
  print "hello world\n";
  
  C:\Documents and Settings\chad\My Documents\code\perl\test>perl hello.pl
  hello world
  
  C:\Documents and Settings\chad\My Documents\code\perl\test>pp -o hello.exe hello
  .pl
  
  C:\Documents and Settings\chad\My Documents\code\perl\test>dir
   Volume in drive C has no label.
   Volume Serial Number is 70E4-9676
  
   Directory of C:\Documents and Settings\chad\My Documents\code\perl\test
  
  01/20/2009  10:05 PM    <DIR>          .
  01/20/2009  10:05 PM    <DIR>          ..
  01/20/2009  10:05 PM         2,703,269 hello.exe
  01/20/2009  10:05 PM                57 hello.pl
                 2 File(s)      2,703,326 bytes
                 2 Dir(s)  77,322,547,200 bytes free
  
  C:\Documents and Settings\chad\My Documents\code\perl\test>hello.exe
  hello world
  
  C:\Documents and Settings\chad\My Documents\code\perl\test>

Building a program that requires modules be included

"pp" is supposed to be good at including dependencies but sometimes it does not succeed. For example consider a script that used these modules:
 use Data::Dumper;
 use Fcntl ':flock';
 use File::Basename;
 use Getopt::Long;
 use IO::Seekable;
 use Readonly;
 use Text::CSV;
The .exe was built using "pp -o foo.exe foo.pl". It built successfully but when the .exe was run it printed this out:
 Can't locate Text/CSV_PP.pm in @INC (@INC contains: CODE(0x128fa5c) C:\DOCUME~1\
 chad\LOCALS~1\Temp\par-chad\cache-22cedcf26d155b3cbc3f513345bd3309658f7e12\inc\l
 ib C:\DOCUME~1\chad\LOCALS~1\Temp\par-chad\cache-22cedcf26d155b3cbc3f513345bd330
 9658f7e12\inc CODE(0x114c1ec) CODE(0x11434a4)) at (eval 22) line 3.
  at script/foo.pl line 16
 Compilation failed in require at script/foo.pl line 16.
 BEGIN failed--compilation aborted at script/foo.pl line 16.
Reading the error message we conclude it can't find "Text::CSV_PP". So we try building the .exe using "pp -M Text::CSV_PP -o foo.exe foo.pl". This time the resulting .exe ran fine.