Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl on Mac OS 10.10 Yosemite with strange @INC path

After upgrading to OS 10.10 I had to install all former used perl modules again. No problem. I thought.

Perl on OS 10.10 is "This is perl 5, version 16, subversion 3 (v5.16.3) built for darwin-thread-multi-2level" (from perl --version). The @INC looks to be (try perl -e 'print join("\n", @INC);' or perl -V):

/opt/local/lib/perl5/site_perl/5.16.3/darwin-thread-multi-2level /opt/local/lib/perl5/site_perl/5.16.3 /opt/local/lib/perl5/vendor_perl/5.16.3/darwin-thread-multi-2level /opt/local/lib/perl5/vendor_perl/5.16.3 /opt/local/lib/perl5/5.16.3/darwin-thread-multi-2level /opt/local/lib/perl5/5.16.3 /opt/local/lib/perl5/site_perl /opt/local/lib/perl5/vendor_perl

When I try to use an unknown module, perl throws: "Can't locate Mymodule.pm in @INC ... and then: @INC contains: ... /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 and all other known (and added 5.18 perl.pm folders). Every perl dev knows that message. But read literally: @INC links obviously to 5.18 folders ! And at a first glance I supposed to use Perl 5.18.

I installed my first bunch of new modules from Macports. 5.18 portfiles. And added the new module pathes to the list /Library/Perl/5.18/AppendToPath. Worked well. But when I installed a module - not available as 5.18 in Macports - with cpan, I got trouble. The module was compiled with 5.16 (of course, see above) and was not accepted as other path in the AppendToPath file. Dynaloader mismatch.

I do not know, where the @INC list is altered at runtime. In earlier Mac OS 10 versions, the new @INC included same version module versions. I.e. an active perl 5.14 included also 5.14 modules, 5.12 included 5.12 pathes a.s.o. Why does perl 5.16 on Yosemite include 5.18 module pathes ?


To add some confusion after my post: When I try a print $^V in program code, I get 5.18. That means, you don't get what you meant to get. May be my shebang #!/usr/bin/perl starts 5.18 and not 5.16.

like image 851
Luigi Avatar asked Mar 17 '23 23:03

Luigi


2 Answers

Experienced Perl developers will tell you to ignore the system perl. If you upgrade it, for a bugfix you need, you run the risk of breaking your OS. If you upgrade your OS, a modified system perl may break your code.

Macports and homebrew are both great, but not ideal for Perl. I'd clear the /opt/local/version from my PATH, or even my system.

Do yourself a big favor. Install Xcode with the Command Line Tools. Install perlbrew. Roll up your own perl. Heck, roll up 6 of your own perls and jump back and forth between them. Keep a threaded version around for when you need it. Keep a non-threaded around for speed. Best of all, whenever you change which version you are using, perlbrew updates your environment correctly for you. No fuss, No muss.

like image 76
tjd Avatar answered Mar 25 '23 02:03

tjd


Solved

OS Yosemite as an update from Maverick provides perl 5.16 and 5.18. When testing which perlyou will get /opt/local/bin/perl, which is a symlink to /opt/local/bin/perl5.16.

When you use #!/usr/bin/perlas standard shebang in perl programs (portable i.e. to Linux), you will run this program with another perl version, because #!/usr/bin/perl really exists as a binary with version 5.18.

When you use cpan / cpanm (cpanminus) for easy and quick installation of new modules, you'll get the modules compiled as 5.16 versions. Because this is assumed as standard path / version (see above).

You will find cpanm at /opt/local/libexec/perl5.16/sitebin/ You also will find /opt/local/libexec/perl5.18/ but no sitebin and no cpanm.

And now: Create a folder sitebin in /opt/local/libexec/perl5.18/ and copy the file /opt/local/libexec/perl5.16/sitebin/cpanm to /opt/local/libexec/perl5.18/sitebin/ (use sudo ... to get permissions).

cpanm is a normal perl program file, independent from versions - but watch the shebang of this file! Open the file and edit the first two lines from

#!/opt/local/bin/perl5.16 
eval 'exec /opt/local/bin/perl5.16  -S $0 ${1+"$@"}'

to

#!/opt/local/bin/perl5.18 
eval 'exec /opt/local/bin/perl5.18  -S $0 ${1+"$@"}'

that means: simply change 5.16 to 5.18. That's all.

Now you are able to install new modules with this new cpanm. The new cpanm will deploy the modules in /opt/local/lib/perl5/site_perl/5.18/darwin-thread-multi-2level/. To let the new path know to perl 5.18 on Mac edit the file /Library/perl/5.18/AppendToPath and append a new line with /opt/local/lib/perl5/site_perl/5.18/darwin-thread-multi-2level (without slash at the end).

That's it.

like image 39
Luigi Avatar answered Mar 25 '23 03:03

Luigi