http://qs321.pair.com?node_id=508876

richz has asked for the wisdom of the Perl Monks concerning the following question:

I've read several threads about the behavior of @INC, i.e. how it's constructed but haven't seen my question answered.

I have an installation of Perl that is bundled with another software application. If I run "perl -V" from the bin directory of this application where the perl executable is located, the @INC variable includes the appropriate perl module directories. If I copy the perl executable to a new directory and run it from this new directory the @INC variable only includes the '.' directory. I'm running windows 2000 and perl 5.6.1. Can anyone shed some light on why/how @INC is changing?

The reason I ask this question is because I have a complicated software build setup that runs some perl scripts by invoking a perl executable it expects to find in a particular directory. It is easier to try and locate a perl executable in this directory as opposed to modifying the build setup.

Thanks.

Replies are listed 'Best First'.
Re: Win32 @INC behavior
by pg (Canon) on Nov 16, 2005 at 04:35 UTC

    Set environment variable PERL5LIB to the directory list that you want in your @INC.

    set PERL5LIB=\perl\lib;\perl\site\lib

    . is automatically added, so don't need to worry about it.

    If I do:

    set PERL5LIB=foo;bar;%PERL5LIB%

    The last piece of perl -V shows:

    ...... %ENV: PERL5LIB="foo;bar;\perl\lib;\perl\site\lib" @INC: foo bar \perl\lib \perl\site\lib .
Re: Win32 @INC behavior
by blm (Hermit) on Nov 16, 2005 at 04:02 UTC

    What do you copy to the new computer? Just perl.exe or the whole bin directory? Do you update the PATH system variable?

      This is all on the same computer. I am not relying on my PATH to run perl and I am just copying perl.exe and the perl56.dll. I ran dependency walker and that is the only dynamically linked non-OS library linked in perl.exe.

      I was always under the impression that the @INC variable is fixed once you compile perl.exe but there was on thread here that mentioned it seems to be somewhat dynamic but not in the way I'm finding out. That thread seemed to indicate that moving perl.exe around would result in @INC being adjusted so the directories it contains have their path adjusted accordingly.

        In my attempts to mimick this problem I got an error about missing Config.pm when running perl -V when I removed all the perl except perl.exe and perl58.dll and perl5.8.0.exe (Yes I am doing this under perl 5.8 because that is all I have on Win32). The config.pm that it is refering to (I think) is c:\perl\lib\Config.pm and it contains alot of the info needed for the -V screen. I don't know if this helps you.

        @INC is the result of all perllib additions that have been made by perl upon startup. It is not fixed at all. Although there is a portion of it that is fixed at compile time. The @INC is a combination of compile time settings, PERLLIB environment variable, perl command line -I parameters and use lib statements.

        For example on linux, if you do:

        PERLLIB=envbar perl -I cmdfoo -V -e "use lib ('usebaz');"

        You will see the resulting @INC :

        @INC: usebaz cmdfoo envbar /usr/lib/perl5/5.6.1/i386-linux /usr/lib/perl5/5.6.1 /usr/lib/perl5/site_perl/5.6.1/i386-linux /usr/lib/perl5/site_perl/5.6.1 /usr/lib/perl5/site_perl/5.6.0/i386-linux /usr/lib/perl5/site_perl/5.6.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.6.1/i386-linux /usr/lib/perl5/vendor_perl/5.6.1 /usr/lib/perl5/vendor_perl .

        There appears to be an order of precidence here too. use lib is first, -I option is second, PERLLIB is third and compiled settings is fourth.

        Update: added use lib to the example.

        Hazah! I'm Employed! But this place sucks

        Note: I'm doing a lot of handwaving here... I seem to recall having read about this, but I've not looked it up to confirm my beliefs. I'll look it up later, I promise.
        I was always under the impression that the @INC variable is fixed once you compile perl.exe
        That's right. That's even the case for Perl on Windows... Except: perl itself changes the directories found in the hardwired @INC inside the perl exectutable, into directories relative to where it currently resides. That happens to lib (relative position to perl: ../lib) and site/lib (relative position: ../site/lib), where the perl executable resides in bin, relative to the perl installation root.

        You could say it's a simple s/^$HARDWIRED_ROOT/$CURRENT_ROOT/, done inside perl.

Re: Win32 @INC behavior
by jimbojones (Friar) on Nov 16, 2005 at 15:24 UTC
    Hi
    What I've managed to observe on windows for ActiveState 561 is that @INC is derived based on the invoked location of the perl.exe. Well, actually, the perl5x.dll that is loaded by perl.exe. Basically, it looks up one dir (out of bin/) for lib/ and site/lib. If you move perl.exe and perl56.dll to some remote location that doesn't follow that structure:
    bin/ lib/ site/lib
    you won't get @INC set. Here's little test, where I copied perl.exe and perl56.dll to a bin/ directory under my "Documents and Settings"
    C:\Documents and Settings\jim> C:\Progra~1\Perl\Perl561_638\bin\perl.e +xe -V Summary of my perl5 (revision 5 version 6 subversion 1) configuration: .... Built under MSWin32 Compiled at Apr 13 2004 19:24:21 @INC: C:/Program Files/Perl/Perl561_638/lib C:/Program Files/Perl/Perl561_638/site/lib . C:\Documents and Settings\jim>mkdir bin C:\Documents and Settings\jim>cp C:\Progra~1\Perl\Perl561_638\bin\perl +.exe bin\. C:\Documents and Settings\jim>cp C:\Progra~1\Perl\Perl561_638\bin\perl +56.dll bin\. C:\Documents and Settings\jim>set PATH=C:\Documents and Settings\jim\b +in;%PATH% C:\Documents and Settings\jim>perl.exe -V Can't locate Config.pm in @INC (@INC contains: .). BEGIN failed--compilation aborted. C:\Documents and Settings\jim>mkdir lib C:\Documents and Settings\jim>mkdir site\lib C:\Documents and Settings\jim>perl.exe -V Can't locate Config.pm in @INC (@INC contains: C:/Documents and Settin +gs/jim/lib C:/Documents and Settings/jim/site/lib .). BEGIN failed--compilation aborted.
    Note that only when I have a lib/ and site/lib directory does the @INC get set correctly. Also, the main functionality is driven by the location of the perl56.dll, not the perl.exe file. perl.exe loads the .dll through the PATH environment variable, and it appears @INC is set with respect to the location of the .dll. So, if I remove the .dll from my local bin/ dir, the .dll is loaded from its default location, and @INC is set with respect to that location.
    C:\Documents and Settings\jim>del bin\perl56.dll C:\Documents and Settings\jim>perl -V Summary of my perl5 (revision 5 version 6 subversion 1) ... ActivePerl Build 638 Built under MSWin32 Compiled at Apr 13 2004 19:24:21 @INC: C:/Program Files/Perl/Perl561_638/lib C:/Program Files/Perl/Perl561_638/site/lib .
    HTH, Jim
    (Update: fix cut and paste error)
      As a follow-up:

      The relevant parts of the .c code appear to be in win32.c

      char *win32_get_sitelib(const char *pl) { return win32_get_xlib(pl, "sitelib", "site"); } static char *win32_get_xlib(const char *pl, const char *xlib, const ch +ar *libname) { .... sprintf(pathstr, "%s/lib", libname); (void)get_emd_part(&sv2, pathstr, ARCHNAME, "bin", pl, Nullch); /* JJ -- get_emd_part strips 'bin' if possible from the path to the .dll (found in get_emd_part by calling set_w32_module_name(); ) and then adds 'site/lib' to that path */ ... }
      Thanks so much. What you describe is definitely the behavior I see. I didn't realize the perl executable would make the @INC directories relative to the location of the dll and if they weren't found it wouldn't include them. It's kind of annoying that perl.exe locates the perl5x.dll via %PATH%; I'd prefer it was done through the registry, but I digress.

      Thanks for the help!