purinkle
purinkle

Reputation: 917

Two versions of Perl in Mac OS X?

I've installed the Template module via CPAN on my MacBook Pro and it seemed to install correctly.

But, when I try to run a script that includes the Template module, I get the following:

Can't locate Template.pm in @INC (@INC contains: /Users/purinkle/Sites/rob/modules /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .) at ./index.pl line 12.

BEGIN failed--compilation aborted at ./index.pl line 12.

I then think that something must have gone wrong during installation and try to install again via CPAN but receive the following message:

Template is up to date (2.22).

I've then ran the instmodsh command to try and find where the module is installed. instmodsh lists these directories:

/opt/local/bin
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template/Manual
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template/Namespace
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template/Plugin
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template/Stash
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template/Tools
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/Template/Tutorial
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level/auto/Template/Stash/XS
/opt/local/share/man/man1
/opt/local/share/man/man3

It looks like I have some how got two different versions of Perl installed (5.8.9 and 5.10.0) and this is causing confusion between CPAN and other Perl scripts.

How can I verify this and how can this issue be resolved?

I've ran the commands

which perl
which cpan

and they both return /opt/local/bin

Running

find / -name perl

returns

find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
/opt/local/bin/perl
/opt/local/etc/bash_completion.d/perl
/opt/local/var/macports/software/bash-completion/1.2_0/opt/local/etc/bash_completion.d/perl
/opt/local/var/macports/software/perl5.8/5.8.9_3/opt/local/bin/perl
/opt/local/var/macports/sources/rsync.macports.org/release/ports/perl
/usr/bin/perl
/usr/local/bin/perl
/usr/share/file/magic/perl

and

find / -name cpan

returns

/opt/local/bin/cpan
/opt/local/var/macports/software/perl5.8/5.8.9_3/opt/local/bin/cpan
/Users/purinkle/.cpan/build/CPAN-1.9402-KtN827/blib/script/cpan
/Users/purinkle/.cpan/build/CPAN-1.9402-KtN827/scripts/cpan
/Users/purinkle/.cpan/build/CPAN-1.9402-zb0AeX/blib/script/cpan
/Users/purinkle/.cpan/build/CPAN-1.9402-zb0AeX/scripts/cpan
/usr/bin/cpan

Running

perl -e 'print join "\n", @INC'

returns

/Users/purinkle/Sites/rob/modules
/opt/local/lib/perl5/site_perl/5.8.9/darwin-2level
/opt/local/lib/perl5/site_perl/5.8.9
/opt/local/lib/perl5/site_perl
/opt/local/lib/perl5/vendor_perl/5.8.9/darwin-2level
/opt/local/lib/perl5/vendor_perl/5.8.9
/opt/local/lib/perl5/vendor_perl
/opt/local/lib/perl5/5.8.9/darwin-2level
/opt/local/lib/perl5/5.8.9

Upvotes: 10

Views: 21120

Answers (7)

brian d foy
brian d foy

Reputation: 132720

The best advice is to install your own Perl that you completely control. You don't want the system changing perl for you, potentially leading to binary incompatibility with modules and so on. The other answers already cover this sort of stuff.

But, every time I answer similar questions, I have to remember the right variable that macOS uses, so here's that answer again.

macOS distributes its own "perl", which is actually two perls. I've compiled the list of the perl versions for each version of macOS.

One of those perls is the default (which was usually the higher version from the previous major release of macOS).

With no value in VERSIONER_PERL_VERSION, macOS uses the lower version perl. Ventura distributes perls v5.30.3 and v5.34.0, so the default is v5.30.3:

brian@M1-Mini ~ % unset VERSIONER_PERL_VERSION
brian@M1-Mini ~ % /usr/bin/perl -v

This is perl 5, version 30, subversion 3 (v5.30.3) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)

I can set VERSIONER_PERL_VERSION to the higher version to get that:

brian@M1-Mini ~ % export VERSIONER_PERL_VERSION=5.34
brian@M1-Mini ~ % /usr/bin/perl -v

This is perl 5, version 34, subversion 0 (v5.34.0) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)

With no value it's back to the low version rather than the previously selected version:

brian@M1-Mini ~ % unset VERSIONER_PERL_VERSION
brian@M1-Mini ~ % /usr/bin/perl -v

This is perl 5, version 30, subversion 3 (v5.30.3) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)

And, if the version I set does not correspond to a distributed version, I get the default version:

brian@M1-Mini ~ % export VERSIONER_PERL_VERSION=5.45
brian@M1-Mini ~ % /usr/bin/perl -v
perl: VERSIONER_PERL_VERSION environment variable error (ignored)

This is perl 5, version 30, subversion 3 (v5.30.3) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)

Upvotes: 1

sebbulon
sebbulon

Reputation: 623

I had the same problem, no idea how it happened. I suspect it somehow happened during an XCode Update. I fixed this by re-installing Perl on my Mac manually. I used the latest version as described here:

http://search.cpan.org/~shay/perl/README.macosx

  curl -O http://www.cpan.org/src/perl-5.26.1.tar.gz
  tar -xzf perl-5.26.1.tar.gz
  cd perl-5.26.1
  ./Configure -des -Dprefix=/usr/local/
  make
  make test
  sudo make install

Upvotes: 0

DanM
DanM

Reputation: 7197

I was running into a similar issue; in my case, the problem was that I'd been running cpan as myself instead of as root, so it was only installing the cpan modules in my user dir, which the global @INC didn't include. Just run 'sudo cpan' instead of 'cpan', install your modules, and they should be loaded in just fine.

Upvotes: 1

Anthony DiSante
Anthony DiSante

Reputation: 49

There's another solution which seems to me to be much simpler: just install another copy of the Perl module, and install it into the installation where you want to use it. For example, if you have two Perl installations on your system, one in /usr/bin and another in /opt/local/bin, and your cpan command by default installs the module into the /opt/local/bin installation, but your app (Apache or whatever) is looking for the module in the /usr/bin installation instead, then you just need to invoke cpan as "/usr/bin/cpan" when installing the module. That solves the problem without needing to edit your script, or your Apache config, etc.

Upvotes: 4

Dave Sherohman
Dave Sherohman

Reputation: 46187

I went through this process about a month and a half ago when setting up a new MacBook Pro. Getting the MacPorts perl installed, switching to /usr/bin/env perl, and updating my PATH (which, from comments on Schwern's answer, sounds like it's about where you are now) was straightforward and reasonably well-documented.

Figuring out how to get the right perl to show up first in apache's PATH, on the other hand, was hellish and involved way too much googling interspersed with periods of beating my head against the wall for relief.

So, to spare you that, the answer I eventually found was that you need to add a PATH key to /System/Library/LaunchDaemons/org.apache.httpd.plist with the PATH that you want apache to use. Assuming that you're just as unfamiliar with the .plist format as I was at the time, here's my complete current org.apache.httpd.plist, which has been working great for me:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabled</key>
        <true/>
        <key>Label</key>
        <string>org.apache.httpd</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/sbin/httpd</string>
                <string>-D</string>
                <string>FOREGROUND</string>
        </array>
        <key>OnDemand</key>
        <false/>
        <key>SHAuthorizationRight</key>
        <string>system.preferences</string>
        <key>EnvironmentVariables</key>
        <dict>
                <key>PATH</key>
                <string>/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string>
        </dict>
</dict>
</plist>

Copy/paste that to your system (or just add the EnvironmentVariables key and its accompanying dict to your existing file), restart apache, and you should be set. (Unless I misremembered and it was something else that actually got it working for me, but I'm pretty sure this was it.)

Upvotes: 3

ennuikiller
ennuikiller

Reputation: 46965

start with these 2 commands:

which perl
which cpan

if you get different paths to the executables then there is a good chance you have 2 versions or perl installed. If they are the same then chances are you have the perl @INC configured incorrectly. You can add paths to @INC bny including this in the very beginning of your script (after the shebang):

BEGIN {

        push @INC,"/path/to/cpan/modules";

        }  

In any case do this:

find / -name perl
find / -name cpan

see what you get. This will tell you if you have multiple versions or not.

Upvotes: 2

Schwern
Schwern

Reputation: 164629

OS X ships with two versions of Perl. 5.10.0 is the default, so /usr/bin/perl and /usr/bin/cpan should all talk to 5.10.0.

The problem is you have three. /opt/local indicates a MacPorts installation which probably installed Perl as a dependency when you weren't looking. That's /opt/local/bin/perl and its probably the default perl in your path. Check with which perl. That also means you're probably using MacPorts' cpan, check with which cpan, and thus installed Template Toolkit into the MacPorts version.

I'm going to guess either you're running a program with #!/usr/bin/perl at the top or you're using the built in mod_perl or you're running it as a user who is not you. All of which will reference OS X's default Perl and not your MacPorts install.

Macports has a 5.10 as well as 5.12, but "perl" in Macports is still 5.8. You can install 5.10 in Macports.

As to how to resolve this... if you're using using mod_perl on that machine, use Macports' Perl. It will be easier to install modules and it will be kept up to date better than the OS version.

To shield yourself from future confusion, you can add aliases into /usr/local/bin or ~/bin to perl, perldoc and cpan to the Perl of your choice. That will prevent something else from installing perl in your path and hijacking.

Upvotes: 17

Related Questions