Hi,

after private communication with Richard we were able to determine the reason
why pp failed on this machine:

- the machine runs Perl 5.8.9

- the PAR::Packer PPM that he installed from the trouchelle PPM repository was
  built against Perl 5.8.8

This combination can't work - for a rather lengthy explanation see below.
There are only two possible solutions: either downgrade Perl to 5.8.8 or
install a version of PAR::Packer built against 5.8.9.


Explanation: Perl 5.8.9 has a different C-API than 5.8.8 - a few functions
(e.g. Perl_hv_common_key_len) got added. Since the C-API was only amended,
5.8.9 in general is backward compatible with 5.8.8, i.e. XS modules
built against 5.8.8 will run under 5.8.9 with no problem.

But PAR::Packer is special, but first I have to explain how
a pp'ed executable works. If you do

pp -o hello.exe hello.pl

the executable hello.exe consists of 3 parts that are simply concatenated:

(A) an executable that contains (as data) a special purpose Perl
interpreter and the Perl shared library (e.g. perl58.dll)

(B) the minimal set of Perl modules that is required to "use PAR;"
(including PAR.pm itself)

(C) hello.pl plus all modules dircetly or indirectly needed to run this
script (as determined by Module::ScanDeps) excluding
the modules from set (B); all these files are organized in a par archive,
i.e. essentially a zip file

When hello.exe runs it does the following:

(1) it extracts from part (A) the custom Perl interpreter and the Perl
shared library (into a temp directory)

(2) it executes this Perl interpreter with a little prelude script that extracts
the contents of (B) into the temp directory; this script is carefully
crafted not to use any modules at all

(3) the Perl interpreter from (2) is set up so that it only looks for modules
in the temp directory; it then does:

use PAR "hello.exe";               # PAR.pm and its dependencies are
already extracted
do "hello.pl";                           # will be extracted from part
(C) by PAR


Where does pp assemble these three parts from?

Part (A) is always the same for any given combination of architecture,
OS and Perl version (you need a C compiler to build it).
That's why it's delivered in the PPM (in uuencoded form) in

PAR/StrippedPARL/Static.pm

When the maintainers of the  trouchelle repository built the PPM with
Perl 5.8.8, the included perl58.dll was from Perl 5.8.8, hence implements
only the Perl C-API as of 5.8.8.

Part (B) and (C) are assembled from the system where pp is run.
If the system runs Perl 5.8.9 then (B) gets a copy of, say, IO.pm and its
companion shared libary IO.dll. But IO.dll references (because it's
built for Perl 5.8.9)
Perl_hv_common_key_len. Hence at step (3) it will fail: PAR.pm requires IO.pm
which tries to load IO.dll, but this has unresolved references with respect to
the perl58.dll extracted in step (2).

Cheers, Roderich

Reply via email to