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

While running the Cygwin updater, I allowed it to upgrade my version of perl from 5.30 to 5.32. Now when I try to run perl scripts, I receive errors related to module locations. Here is a sample program:


#!/usr/bin/perl -w use strict; use WWW::Mechanize; printf("foo\n");

Here is the output:


Can't locate WWW/Mechanize.pm in @INC (you may need to install the WWW +::Mechanize module) (@INC contains: /home/Special_K/perl_modules /usr +/local/lib/perl5/site_perl/5.32/x86_64-cygwin-threads /usr/local/shar +e/perl5/site_perl/5.32 /usr/lib/perl5/vendor_perl/5.32/x86_64-cygwin- +threads /usr/share/perl5/vendor_perl/5.32 /usr/lib/perl5/5.32/x86_64- +cygwin-threads /usr/share/perl5/5.32) at ./test.pl line 3. BEGIN failed--compilation aborted at ./test.pl line 3.

After searching for help I modified my code to the following:


#!/usr/bin/perl5.30.3 -w use strict; use WWW::Mechanize; printf("foo\n");

Now the output is as follows:


Can't locate strict.pm in @INC (you may need to install the strict mod +ule) (@INC contains: /home/Special_K/perl_modules /usr/local/lib/perl +5/site_perl/5.30/x86_64-cygwin-threads /usr/local/share/perl5/site_pe +rl/5.30 /usr/lib/perl5/vendor_perl/5.30/x86_64-cygwin-threads /usr/sh +are/perl5/vendor_perl/5.30 /usr/lib/perl5/5.30/x86_64-cygwin-threads +/usr/share/perl5/5.30) at ./test.pl line 2. BEGIN failed--compilation aborted at ./test.pl line 2.

I'm not sure how to fix this. How do I locate strict.pm?

Also here are some related questions:

1. If I install a new version of perl, do I need to install new copies of every module that was installed for the prior version of perl I was using?

2. If I install a new version of perl but I want some scripts to use the prior version of perl, do I need to manually edit each of those scripts to point to the old version, as I have done in my second sample code block above?

Replies are listed 'Best First'.
Re: help fixing module paths after upgrading perl in cygwin
by kcott (Archbishop) on Oct 21, 2022 at 06:51 UTC

    G'day Special_K,

    I use Cygwin. I'm using the latest version, 3.3.6. I do a full update of "pending" components every week; my last update was about an hour ago. So, everything related to Cygwin below is up-to-date.

    I also run Perlbrew. I recommend you do the same. I completely ignore whatever Perl components Cygwin has installed. I can easily switch between whatever Perl versions I want to use:

    $ which perl /home/ken/perl5/perlbrew/perls/perl-5.36.0/bin/perl $ perlbrew list * perl-5.36.0 perl-5.34.0 perl-5.33.5 perl-5.32.0 perl-5.30.0 $ perlbrew switch perl-5.30.0 $ which perl /home/ken/perl5/perlbrew/perls/perl-5.30.0/bin/perl $ perlbrew switch perl-5.36.0 $ which perl /home/ken/perl5/perlbrew/perls/perl-5.36.0/bin/perl

    If you're up-to-date, I'm surprised you've even got /usr/bin/perl5.30.3. Here's what I got from Cygwin:

    $ ls -al /usr/bin/perl -rwxr-xr-x 2 ken None 12800 Aug 14 2021 /usr/bin/perl $ ls -al /usr/bin/perl* -rwxr-xr-x 2 ken None 12800 Aug 14 2021 /usr/bin/perl.exe -rwxr-xr-x 2 ken None 12800 Aug 14 2021 /usr/bin/perl5.32.1.exe -rwxr-xr-x 2 ken None 45259 Aug 14 2021 /usr/bin/perlbug -rwxr-xr-x 1 ken None 262 Aug 14 2021 /usr/bin/perldoc -rwxr-xr-x 1 ken None 57920 Feb 7 2021 /usr/bin/perli11ndoc -rwxr-xr-x 1 ken None 10813 Aug 14 2021 /usr/bin/perlivp -rwxr-xr-x 1 ken None 12047 Oct 4 17:26 /usr/bin/perlsh lrwxrwxrwx 1 ken None 48 Aug 13 10:59 /usr/bin/perltex -> /usr/shar +e/texmf-dist/scripts/perltex/perltex.pl -rwxr-xr-x 2 ken None 45259 Aug 14 2021 /usr/bin/perlthanks $ /usr/bin/perl -v This is perl 5, version 32, subversion 1 (v5.32.1) built for x86_64-cy +gwin-threads-multi (with 7 registered patches, see perl -V for more detail) ...

    I attempted to replicate what you're showing us, but couldn't. However, although you've shown the code and the output, you don't say how you ran it: ./script.pl; perl script.pl; /usr/bin/perl script.pl; /usr/bin/perl5.30.3 script.pl; etc.

    Try running variations of the following to see what's in @INC and where your modules are located (from %INC info):

    $ /usr/bin/perl5.32.1 -E 'use strict; use warnings; say for @INC; use +Data::Dumper; print Dumper \%INC;' /usr/local/lib/perl5/site_perl/5.32/x86_64-cygwin-threads /usr/local/share/perl5/site_perl/5.32 /usr/lib/perl5/vendor_perl/5.32/x86_64-cygwin-threads /usr/share/perl5/vendor_perl/5.32 /usr/lib/perl5/5.32/x86_64-cygwin-threads /usr/share/perl5/5.32 $VAR1 = { 'feature.pm' => '/usr/share/perl5/5.32/feature.pm', 'XSLoader.pm' => '/usr/share/perl5/5.32/XSLoader.pm', 'bytes.pm' => '/usr/share/perl5/5.32/bytes.pm', 'Exporter.pm' => '/usr/share/perl5/5.32/Exporter.pm', 'constant.pm' => '/usr/share/perl5/5.32/constant.pm', 'Data/Dumper.pm' => '/usr/lib/perl5/5.32/x86_64-cygwin-threa +ds/Data/Dumper.pm', 'warnings.pm' => '/usr/share/perl5/5.32/warnings.pm', 'overloading.pm' => '/usr/share/perl5/5.32/overloading.pm', 'Carp.pm' => '/usr/share/perl5/5.32/Carp.pm', 'strict.pm' => '/usr/share/perl5/5.32/strict.pm', 'warnings/register.pm' => '/usr/share/perl5/5.32/warnings/re +gister.pm' };
    "If I install a new version of perl, do I need to install new copies of every module that was installed for the prior version of perl I was using? "

    In general, you'll need to install all non-core modules (i.e. modules from CPAN, that you wrote yourself, that came from your $work, and so on). However, as you seem to have both a v5.30 and a v5.32, I'm not sure what you've done and what you need to do.

    I keep a list of all of my non-core modules and install them (using the cpan utility) every time I install a new Perl version via Perlbrew. I'm reasonably certain that there are short-cuts for doing this, but I like to keep a close eye on all module installations (and any problems they might have). Other monks may provide you with different ways to do this.

    "If I install a new version of perl but I want some scripts to use the prior version of perl, do I need to manually edit each of those scripts to point to the old version, as I have done in my second sample code block above?"

    I use this shebang for all of my scripts:

    #!/usr/bin/env perl

    I just switch to whatever Perl version I want (using Perlbrew) and run the script as is. Sometimes I want to test a script against several versions of Perl: this is an easy way to achieve that.

    Without Perlbrew, you can just use something like this:

    $ /usr/bin/perl5.30.3 script.pl $ /usr/bin/perl5.32.1 script.pl

    Continually making changes to the shebang is a pain and error-prone. I wouldn't recommend it.

    Also note the distinct absence of -w in any of my code in this response. I strongly recommend you use the warnings pragma instead. See "perlrun: -w" for more about that (note the "... normally, the lexically scoped use warnings pragma is preferred.").

    — Ken

      I see that you have multiple versions of perl installed via Cygwin. When a new perl version is installed via Cygwin, are older versions' modules uninstalled, as haukex suggested above? Based on your post, it seems like that is not the case.



      I attempted to replicate what you're showing us, but couldn't. However, although you've shown the code and the output, you don't say how you ran it: ./script.pl; perl script.pl; /usr/bin/perl script.pl; /usr/bin/perl5.30.3 script.pl; etc.

      I called it by using./test.pl


      Try running variations of the following to see what's in @INC and where your modules are located (from %INC info):

      If I run it using perl5.32.1, I receive the following output:



      > /usr/bin/perl5.32.1.exe -E 'use strict; use warnings; say for @INC; +use Data::Dumper; print Dumper \%INC;' /home/Special_K/perl_modules /usr/local/lib/perl5/site_perl/5.32/x86_64-cygwin-threads /usr/local/share/perl5/site_perl/5.32 /usr/lib/perl5/vendor_perl/5.32/x86_64-cygwin-threads /usr/share/perl5/vendor_perl/5.32 /usr/lib/perl5/5.32/x86_64-cygwin-threads /usr/share/perl5/5.32 $VAR1 = { 'feature.pm' => '/usr/share/perl5/5.32/feature.pm', 'Data/Dumper.pm' => '/usr/lib/perl5/5.32/x86_64-cygwin-threa +ds/Data/Dumper.pm', 'overloading.pm' => '/usr/share/perl5/5.32/overloading.pm', 'strict.pm' => '/usr/share/perl5/5.32/strict.pm', 'warnings.pm' => '/usr/share/perl5/5.32/warnings.pm', 'warnings/register.pm' => '/usr/share/perl5/5.32/warnings/re +gister.pm', 'bytes.pm' => '/usr/share/perl5/5.32/bytes.pm', 'Exporter.pm' => '/usr/share/perl5/5.32/Exporter.pm', 'constant.pm' => '/usr/share/perl5/5.32/constant.pm', 'XSLoader.pm' => '/usr/share/perl5/5.32/XSLoader.pm', 'Carp.pm' => '/usr/share/perl5/5.32/Carp.pm' };


      If however I try to run that command using perl5.30.3.exe, I receive the following error:



      > /usr/bin/perl5.30.3.exe -E 'use strict; use warnings; say for @INC; +use Data::Dumper; print Dumper \%INC;' Can't locate feature.pm in @INC (you may need to install the feature m +odule) (@INC contains: /home/Special_K/perl_modules /usr/local/lib/pe +rl5/site_perl/5.30/x86_64-cygwin-threads /usr/local/share/perl5/site_ +perl/5.30 /usr/lib/perl5/vendor_perl/5.30/x86_64-cygwin-threads /usr/ +share/perl5/vendor_perl/5.30 /usr/lib/perl5/5.30/x86_64-cygwin-thread +s /usr/share/perl5/5.30).


      Did my perl5.30.3.exe modules really get uninstalled when I installed 5.32? For some reason, /usr/share/perl5/5.30 is empty except for a CPAN directory, but /usr/share/perl5/5.32 appears to have all of the built-in modules. If you go to the /usr/share/perl5/<version>/ directories, does each one have a separate copy of each built-in module?
        "I see that you have multiple versions of perl installed via Cygwin."

        No, that's not what you're seeing. I'd guess you're making some incorrect assumptions; although, I don't know exactly what they might be. Let me be specific about what I have.

        Five versions of Perl installed via Perlbrew.

        $ perlbrew list * perl-5.36.0 perl-5.34.0 perl-5.33.5 perl-5.32.0 perl-5.30.0

        One version of Perl installed via Cygwin. This exists under three filenames which are hard copies; note the identical inode numbers. All are Perl v5.32.1.

        $ ls -ali /usr/bin/perl /usr/bin/perl* 1125899907799520 -rwxr-xr-x 2 ken None 12800 Aug 14 2021 /usr/bin/per +l 1125899907799520 -rwxr-xr-x 2 ken None 12800 Aug 14 2021 /usr/bin/per +l.exe 1125899907799520 -rwxr-xr-x 2 ken None 12800 Aug 14 2021 /usr/bin/per +l5.32.1.exe ... $ /usr/bin/perl -v | head -3 | tail -2 This is perl 5, version 32, subversion 1 (v5.32.1) built for x86_64-cy +gwin-threads-multi (with 7 registered patches, see perl -V for more detail) $ /usr/bin/perl.exe -v | head -3 | tail -2 This is perl 5, version 32, subversion 1 (v5.32.1) built for x86_64-cy +gwin-threads-multi (with 7 registered patches, see perl -V for more detail) $ /usr/bin/perl5.32.1.exe -v | head -3 | tail -2 This is perl 5, version 32, subversion 1 (v5.32.1) built for x86_64-cy +gwin-threads-multi (with 7 registered patches, see perl -V for more detail)
        "Did my perl5.30.3.exe modules really get uninstalled when I installed 5.32?"

        That would be my guess; but it is only a guess. When I run setup-x86_64.exe to do updates, I'm presented with a list of what will be uninstalled and what will be installed, and the option to proceed or not. I used to be very diligent and checked that list every time; over the years, as I've never had any problems, that diligence has somewhat fallen by the wayside. I assume you're not checking that list either.

        There are two logfiles: /var/log/setup.log & /var/log/setup.log.full. I haven't spent any time in the past looking at those, so this is as much discovery for me as it will presumably be for you. As far as I can tell, these are overwritten with each update, so you may want to make backup copies before doing anything else. Also note that these are likely to be huge files. Here's what I have (and bear in mind that I'm updating weekly). If you're updating less frequently, yours may be substantially larger.

        $ ls -l /var/log/setup.log /var/log/setup.log.full -rw-r--r-- 1 ken Administrators 10998164 Oct 21 16:19 /var/log/setup.l +og -rw-r--r-- 1 ken Administrators 1797726 Oct 21 16:19 /var/log/setup.l +og.full

        By the way, I've no idea why setup.log.full is so much smaller than setup.log. I'll leave you to research that and report back. :-)

        There were not many "perl" updates since I ran setup-x86_64.exe last week, so I find:

        $ grep 'Uninstalling perl' /var/log/setup.log.full 2022/10/21 16:10:37 Uninstalling perl-DateTime-TimeZone 2022/10/21 16:10:37 Uninstalling perl-Exporter-Tiny 2022/10/21 16:10:37 Uninstalling perl-HTML-Parser-debuginfo 2022/10/21 16:10:37 Uninstalling perl-Mojolicious 2022/10/21 16:10:38 Uninstalling perl-URI 2022/10/21 16:10:38 Uninstalling perl-HTTP-Message 2022/10/21 16:10:39 Uninstalling perl-HTML-Parser

        You may have some or all of those; you may have a lot more. If you open the logfile and search for those lines, you'll find a lot more information regarding individual components of those packages. There's also information about what was installed (which I didn't actually spend any time studying).

        "If you go to the /usr/share/perl5/<version>/ directories, does each one have a separate copy of each built-in module?"

        I don't have multiples of those directories. I just have this one:

        $ ls -ld /usr/share/perl5/5* drwxr-xr-x 1 ken None 0 Aug 13 10:48 /usr/share/perl5/5.32

        As I indicated earlier, I'm surprised you have both a v5.30.3 and a v5.32.1. Perhaps you (inadvertently) selected "keep" (for the program but not the modules) when doing the update. If you're prepared to spend the time to trawl through the logs, I suspect you'll find the answer there — they seem to be very thorough and detailed.

        So, there's a lot of work just to find out what went wrong. I think taking a pragmatic approach, putting the current problems behind you, installing Perlbrew, and not having these issues again, may be the best way to go.

        — Ken

Re: help fixing module paths after upgrading perl in cygwin (updated)
by haukex (Archbishop) on Oct 21, 2022 at 06:01 UTC
    I'm not sure how to fix this. How do I locate strict.pm?

    I don't have a copy of Cygwin at the moment, but since you also wrote that you upgraded your Perl version, I suspect that it actually deinstalled Perl 5.30, while for some reason leaving /usr/bin/perl5.30.3 behind. That would explain a core module like strict.pm missing.

    If I install a new version of perl, do I need to install new copies of every module that was installed for the prior version of perl I was using?

    Yes. Some modules may survive being used in the new version of Perl, but any XS modules won't. That's why it's generally not recommended to reinstall all modules. Note you may want to look at e.g. cpanfiles to document your required modules, as they make it easy to install them all in one go using cpanm.

    If I install a new version of perl but I want some scripts to use the prior version of perl

    Why would you want to do this? I don't think there were any major incompatibilities between 5.30 and 5.32, so you should be fine using the latter.

    ... do I need to manually edit each of those scripts to point to the old version, as I have done in my second sample code block above?

    Not necessarily, for example I use the shebang #!/usr/bin/env perl to use whatever perl is first in PATH, and for example tools like perlbrew make it easy to modify PATH to point to whatever version of Perl you want.

    However, in this case it would appear to me that your best course of action would be to install WWW::Mechanize to your Perl 5.32.

    Update: Fixed second paragraph (was originally "not recommended to reuse modules across versions" and I forgot to remove the "not" when changing it, sorry).

      I don't have a copy of Cygwin at the moment, but since you also wrote that you upgraded your Perl version, I suspect that it actually deinstalled Perl 5.30, while for some reason leaving /usr/bin/perl5.30.3 behind. That would explain a core module like strict.pm missing.

      So in this context, "deinstalling perl" means removing all built-in modules but leaving the actual perl executable?

      Why would you want to do this? I don't think there were any major incompatibilities between 5.30 and 5.32, so you should be fine using the latter.

      If the alternative is to reinstall all modules that I had installed via CPAN for 5.30, then maybe it would be easier to just revert to 5.30 if I don't specifically need any of the changes that 5.32 offers over 5.30.
        So in this context, "deinstalling perl" means removing all built-in modules but leaving the actual perl executable?

        Well, from your description in the root node that's my best guess as to what happened, though I find it strange that modules like strict.pm were removed while the 5.30 binary was left behind, since it's esentially left behind a broken 5.30 installation.

        if I don't specifically need any of the changes that 5.32 offers over 5.30

        That is up to you to decide, but note that there have been quite a few nice new features added, and more importantly security fixes made, that make a good argument for always using the newest version of Perl that is available. Have a look at perl5320delta.

        If the alternative is to reinstall all modules that I had installed via CPAN for 5.30

        Since I regularly install fresh copies of Perl, either because I'm setting up a new machine or because I'm upgrading a Perl version somewhere, I don't think installing all of the CPAN modules I need is a big hassle, because as I said I use tools like cpanfile and cpanm to make that really easy. Tools like scandeps.pl can help in building such a list (see e.g. Re: Using Cartons to automate module installs).

        If instead you just wanted a one-time reinstall of everything, there are ways to list all the modules you have installed (perlfaq3, Finding what modules are installed, List of Installed Perl Module in Unix Box, and many more), and you may want to look into CPAN's autobundle command.