Hi Toby,
long mail ahead. Sorry.
Toby C via RT wrote:
Show quoted text> Tue Feb 03 00:35:06 2009: Request 42986 was acted upon.
> Queue: PAR
> Subject: PAR-based modules use system XS modules over included modules
Show quoted text> I have created a PAR file which contains my script, and the included
> modules include an XS module.
> However if I try to run the script, the XS module fails to load with
> DynaLoader, as the system-installed .so file has been loaded, rather
> than the one included with the PAR file.
Very strange. I did essentially exactly as you say and I could not
reproduce the problem.
What happens when you try to run the .par with "par.pl test.par"?
What's the architectures and perl and PAR::Packer versions that were
used to create the parl's you're using to execute the test.par? I guess
you can find out like this:
mkdir tmp
cd tmp
cp `which parl` .
# save extract_embedded.pl from this mail to the directory
perl extract_embedded.pl parl .
grep archname Config.pm
# --> should print something like
# archname => 'i686-linux-thread-multi',
grep "version =>" Config.pm
# version => '5.10.0',
To find out the PAR (not PAR::Packer unfortunately) version, you can
then do:
grep "VERSION" PAR.pm
With this information, you'll be able to verify or disprove the
following guess of mine:
"The architectures or perl versions of your target machine's pArl and
your development machine's pErl aren't really compatible."
Let me explain with some more detail:
- When you use pp to generate .par or ".exe" files, it puts a small
script into the archive as "script/main.pl". That script is executed
when you try to run a script from the archive via "parl" or "par.pl" and
also for stand-alone executables.
- The contents of main.pl are different depending on context.
Specifically, if generating a stand-alone executable or using the -B
option to pp, then main.pl will include some code that clears out the
@INC before running the script. After all what you're executing is
supposed to be stand-alone.
- If you're using the -p option and not -B, i.e. creating a dependent
.par file that expects a full perl installation, then it *naturally*
doesn't clear @INC before running the user code.
- Your case is the second one.
- Since (I think) the perl installations (and specifically the pArl on
the target machine and the pErl on your dev machine that runs pp) aren't
entirely compatible, the XS.so in the .par will not be loaded. Instead,
it will try to find a XS.so on the target system that's compatible to
the target system's parl.
- Such an XS.so is found, but after loading it, it turns out to be an
incompatible VERSION!
Let's suppose this is the case. I still wouldn't exactly call this a
mistake on your part. It's simply a darned complicated situation. It's
also one of the reasons why I don't like the "parl FOO.par" use case or
PAR::Packer. But still, I don't think it's a downright PAR bug either.
It's the behaviour you're implicitly asking for by not bundling the
whole perl environment (i.e. "please use what's already there").
I hope this clears up confusion and doesn't add to it :)
Best regards,
Steffen
P.S.: Food for thought and discussion: I just found out that adding -B
to the "pp -p -o foo.par foo.pl" doesn't make "main.pl" clear @INC. I
expected it would. We'll have to think about what the right behaviour is
in that case. After all, it's bundling the core modules, so it should
probably clear @INC before running, no?