DynaLoader seeing wrong values in @INC
I have multiple versions of Perl installed; each under a different directory. e.g. C:\Perl\5.x.y
. I switch between them in a shell by setting PERL5LIB and altering my PATH so that only one version is visible at a time. Normally, this works fine, but when trying to run the version of pp
(PAR::Packer) installed under 5.10.1 I have problems loading XS components. parll2nc.exe complains:
This application has failed to start because perl512.dll was not found...
I set PERL_DL_DEBUG and see the following when DynaLoader initializes:
DynaLoader.pm loaded (C:/Perl/5.10.1/site/lib C:/Perl/5.12.1/lib ., \lib)
The stuff before the comma is @INC
. The first entry is correct, the second is not. I can't figure out how DynaLoader is getting a 5.12 lib path as running perl directly shows what I would expect:
C:\>perl -e "print join ' ', @INC"
C:/Perl/5.10.1/site/lib C:/Perl/5.10.1/lib .开发者_Go百科
How is DynaLoader picking up the wrong path and how do I prevent it from doing so?
Similar to the approach I suggested for this question, put a trace on @INC
and see when it gets updated.
At the very top of your script, before any other use
statements, put:
use Tie::Trace;
BEGIN { Tie::Trace::watch @INC };
Then you will get a warning message when another module edits your @INC
array.
I figured it out. The problem is caused by an interaction of several things:
- I have *.pl files associated with perl.exe (for the most recent version of Perl installed -- 5.12.1).
- I have ".PL" in my PATHEXT environment variable so that I can run Perl scripts without typing the extension. e.g.
C:\>foo
instead ofC:\>foo.pl
- My installation of the
pp
utility does not have a batch file wrapper created withpl2bat
. (I'm not sure why.)
The net result is that when I ran pp @myconfig
it effectively did this:
C:\Perl\5.12.1\bin\perl.exe C:\Perl\5.10.1\site\bin\pp.pl @myconfig
i.e. it ran the version of pp.pl in my path using the version of perl associated with *.pl files, not the version of perl in my PATH. Thus the mix of libs in @INC
between what came from the executable (C:\Perl\5.12.1\lib) and what came from the PERL5LIB environment variable (C:\Perl\5.10.1\site\lib).
The solution is to either run pp
as perl pp.pl
or (better, because you don't have to remember anything) to create a batch wrapper. Assuming that .BAT is in PATHEXT before .PL, when you type pp
Windows will run pp.bat
instead of pp.pl
, and pp.bat
invokes perl
(using the version in your path).
sigh
精彩评论