|Think about Loose Coupling|
PARby rinceWind (Monsignor)
|on Jul 06, 2004 at 16:15 UTC||Need Help??|
Item Description: Packaging perl scripts as executables
Review Synopsis: A useful tool in advocacy
PAR has saved my day! It will go a long way towards helping me in my crusade of Perl advocacy in the present $CLIENT (who shall remain nameless) environment.2
The situation is that we have three Unix (Solaris) environments: dev, test and live. Although Solaris comes with a version of perl pre-installed, the admins have restricted access to it on all but the dev machine (under some historical edicts from senior management).
Now, as part of my activities in development, I have been producing a nice set of perl tools (as is my want), to get my job done. Many of these would benefit production, especially for production support, which is closer to what my current role is.
PAR for the course
+----+ foo.pl===>| pp |====>foo +----+Just like cc, pp turns your Perl file (and all called modules) into an executable. It's not actually compiling them, just packaging them up (and compressing).
My colleagues feel a lot happier about the (potentially) tamper proof nature of executables, and I can deploy my perl 'scripts' into test and live environments. Funnily enough, they haven't had a problem with deploying .ksh or .awk scripts.
Caveat removed (thanks are due to PodMaster for helping me sort this one out.
Peeping under the hoodAlthough PAR delivers applications that work out of the box1, it is worth examining what the output of pp actually is.
The resulting executable is a self extracting zip file, and tools such as winzip or unzip -l can reveal the contents of the file. Besides the various perl modules called, you will find script/foo.pl (this being your source script) and script/main.pl. Note that you don't see Perl itself or any of the magic glue that makes your application run.
script/main.pl is a small bootstrap script that calls your script, and it looks like this:
The first time a PAR application is run (or a new version of the application), it is unzipped into temporary directories: $TEMP/par_$USER/cache_nnnnnnnnnnn
the nnnnnnnnnnn here is an MD5 checksum, hence a new version of the PAR application will generate a new cache directory.
The first time the application is run, there will be a significant startup time, as the zip kit is unpacked. It is worthwhile explaining this to users.
Run time requiresUnfortunately, PAR (and Module::ScanDeps) will not detect all modules, especially those whose name is determined at run time. If you are missing a module or two, you need to include the modules in the build - either by adding explicit use or require statements in the script (useful for Tk widget modules), or by specifying -M to pp.
Parlez vous?There are circumstances where you don't want to bundle everything into a single executable. You may have several scripts (CGI scripts for example) calling the same bunch of modules, and you want to distribute this.
The PAR install delivers another utility called parl (PAR loader), which takes mostly the same parameters as perl. This provides the ability to run a perl script and call in one or more PAR libraries (built with pp, but called *.par).
Again, a Perl install is not needed on the target machine. You need to deliver parl, the scripts and the PAR libraries. On the Windows platform, you could package this up with Install Shield.
tkppFor those averse to command lines, there is a script provided called tkpp, which provides a very thin GUI Tk wrapper around pp. Far from it being a responsive GUI, it freezes while building the application. I find no benefit in using this over the command line, other than saving having to remember the command line options.
1 I like things that work straight out of the box. I am a great fan of Knoppix - a Linux distro that works straight off the CD.
2 This was the subject of a lightning talk I gave at YAPC::Europe 2004, the slides of which are here