Compiling or packaging an executable from perl code on windows

From Svendsen Tech PowerShell Wiki
Jump to: navigation, search

NB! The MingW package is gone from PPM as of 2014 (not sure about which Perl version is the latest supported, at least 5.12.4, as used here)! This means the method described here won't work with ActiveState Perl anymore. Better keep your old installs around...?

Here I'll describe how to compile/package a 32-bit portable, standalone Windows executable from Perl code using PAR with ActiveState or Strawberry Perl, on Windows 2000 and later Windows versions. Possibly other versions too; I haven't tested them. Read more about Perl on Windows here.




Creating a 32-bit Executable

The test environment is using ActiveState Perl 5.12.4 build 1205 x86 (File name: ActivePerl-5.12.4.1205-MSWin32-x86-294981.msi). Date tests were performed: 2011-07-29. The 64-bit ActiveState Perl repositories don't offer a MingW package at the time being (not in the Theoryx repository either). This works with the x86/32-bit ActiveState Perl version, on Windows 2000/XP/2003 (32-/64-bit), Vista/2008 (32-/64-bit), Windows 7 (32-/64-bit) and 2008 R2 (64-bit).

If you're using Strawberry Perl, just use cpan -i to install PAR as well, as described below.

Installing

First, install PAR and MingW with ppm:

From PowerShell or cmd.exe (I recommend PowerShell), issue the following commands, in this order - or at least make sure you run the last CPAN command after MingW is successfully installed, because you need dmake for compiling:

> ppm install PAR
> ppm install MingW

Then issue the following command to install PAR::Packer from CPAN (this took like 15-20 minutes for me, on a Core 2 Quad 2.8 GHz, maxing one core):

> cpan -i PAR::Packer

The version of PAR::Packer I currently have in the test environment is 1.010 and the PAR version is 1.002 as shown below. By the way, if you're using cmd.exe instead of PowerShell, these one-liners will fail. See this article about Perl from PowerShell for more information about quoting differences; basically, just use double quotes instead - in this case.

PS C:\> perl -MPAR::Packer -le 'print $PAR::Packer::VERSION'
Set up gcc environment - 3.4.5 (mingw-vista special r3)
1.010
PS C:\> perl -MPAR -le 'print $PAR::VERSION'
1.002

Creating an Executable

The command pp can then be used for compiling/packaging executables. Here's a simple example:

PS E:\temp> type .\perlcode.pl
use warnings;
use strict;
print "This is the Perl code!\n";

PS E:\temp> pp -o perlcode.exe .\perlcode.pl

Set up gcc environment - 3.4.5 (mingw-vista special r3)
Set up gcc environment - 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Set up gcc environment - 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


PS E:\temp> .\perlcode.exe
This is the Perl code!

As you can see, the command I used is:

> pp -o perlcode.exe .\perlcode.pl

Including Modules / Unexpected Errors

Sometimes you'll get various errors, which usually ultimately reference some module (but not always, I guess). I've found that it's often necessary to include modules manually with -M Module::Name as a parameter to pp. Sometimes it's also necessary to include modules that modules you use in your script depend on. One specific case for me once was with Socket which was needed by Win32::FileOp, if I remember correctly.

Example:

> pp -o something.exe -M Some::Module -M Some::Other::Module -M And::So::On perlscript.pl