Building executables with PAR

[ Perl tips index ]
[ Subscribe to Perl tips ]

One of Perl's greatest strengths is the huge number of modules available on the CPAN. Many really tricky problems can be made quite simple with just the use of a few appropriate modules.

Unfortunately, using CPAN modules results in another problem. Using modules makes development easier, but it makes installing code much more difficult. Not only do we have to ensure that the modules we use are installed, but we also need to ensure they modules they depend upon also get installed. Worst of all, we may be writing code for machines that don't even have Perl installed at all, or a version so old that none of our modules work on it.

If this seems familiar, then PAR, the Perl Archiver, may provide relief from your installation woes. PAR allows you to bundle all of your modules, configuration files, and other dependencies into a single compressed archive, and then distribute that along with, or instead of, your code.

Creating a PAR file (simple)

At the most basic level a PAR file is just a regular zip file, but with a .par extension. You can use any zip tool to create them, such as right-clicking a file in Windows XP, and selecting ``Send to -> compressed (zipped) folder'', by using the 'zip' command under Unix, or by using the Archive::Zip module in Perl.

        zip example.par Foo.pm Bar/Baz.pm

Using a PAR file

Before we show you how to create a PAR file, let's see how to use one. It's as simple as:

        use PAR "example.par";
        use Bar::Baz;           # Loads Bar::Baz from example.par

If you have a lot of .par files, you can even specify a file pattern match:

        use PAR "/home/mylibs/*.par";
        use Bar::Baz;

The PAR module itself has very few dependencies, and so is very easy to install on your target system.

Creating a PAR file (advanced)

Being able to create a .par file using nothing but your system's zip management tools is very convenient, but it still means you have the effort of finding all your dependencies and adding them to the archive. Worse still, if your dependencies change, you have to go through the whole process again.

Fortunately, we can use the PAR Packager, pp, to do all the hard work for us. pp comes as part of the Par-Packer distribution on CPAN, and has quite a few dependencies. However you'll only need pp on your build system, not your target system.

Let's start with the situation where you have a program, and you want to find all its dependencies and wrap them up into a .par file. Using pp, we can simply write:

        pp -p -o archive.par hello.pl

The -o switch specifies our output file name, and the -p switch tells pp we're building a <.par> file, rather than anything else (like a stand-alone executable). The resulting archive.par contains all the dependencies for our program, and can be loaded with use PAR "archive.par", or opened using a zip tool, just like an archive we built ourselves.

However the resulting archive.par built by pp also contains our original program. If we're running on a system that already has PAR::Packer installed, we can run our program with parl:

        parl archive.par

Sometimes pp will miss a dependency, perhaps because it's loaded in a strange way, or perhaps we just want to bundle extra modules into our archive, even though our main program doesn't use them. We can always add additional modules with the -M switch. For example, the following adds the IPC::System::Simple module to our archive, as well as all the modules that hello.pl depends upon:

        pp -p -M IPC::System::Simple -o archive.par hello.pl

Creating a stand-alone Perl program

The <pp> program is able to create stand-alone Perl programs, saving us the effort of having to include all our modules into a .par file, modifying our program to use it, and then shipping them both together. To do this, we simply use -P instead of -p when building our archives:

        pp -P -o portable.pl hello.pl

The resulting portable.pl file contains hello.pl, and all the non-core modules it depends upon. It can be run with:

        perl portable.pl

As of PAR::Packer 0.977, the program still depends upon PAR having been installed on the target system.

Creating a stand-alone executable

One of the greatest uses of PAR is being able to create a stand-alone executable, which will work on systems that don't even have perl installed, or an extremely old version of perl that we'd rather not use.

Building an executable is what pp does by default, if not directed otherwise. Of course, it will only run on the same architecture as it was built, so to build a Windows executable you'll need to use pp on Windows, or to build a Linux binary you'll need to use pp on Linux.

To use our previous examples, we could write:

        pp -o hello.exe hello.pl           # Windows
        pp -o hello hello.pl               # Linux

to create a stand-alone hello.exe file that can be run without perl, PAR, or any additional modules.

You can also use pp to include additional shared libraries, or other dependencies that your program needs. For example, on a Unix flavoured system we can include the system libncurses.so with:

        pp -l ncurses -o hello hello.pl

For a more lengthy example of building a Windows executable which depends upon numerous .dll files, see the MakeExe.pl file for App::SweeperBot in the further references section below.


Conclusion

By using PAR, we can solve the most common problems when trying to distribute dependency-rich perl programs, with a minimum of work needed on the target system. By using pp, we can even distribute stand-alone perl executables to systems that don't even have perl installed at all.

PAR has many more features, and a very rich API, that have not been covered in this tip. See the further references section below for more information.


Further References

[ Perl tips index ]
[ Subscribe to Perl tips ]


This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.

If you have any questions please don't hesitate to contact us:

Email: contact@perltraining.com.au
Phone: 03 9354 6001 (Australia)
International: +61 3 9354 6001

Valid XHTML 1.0 Valid CSS