Tuesday, September 8, 2015

CPAN modules on Mac OSX

Got problems with PKG_CONFIG_PATH on Mac when trying to install Perl modules via CPAN?

Update: take care, see message at the bottom of this post BEFORE typing any of the commands listed here.

Maybe this will help.  First some background.

I wanted to write a Perl script and use the Text::Hunspell perl module plus whatever dependencies it required.  I know from experience its a pain to install a module with all its dependencies, so I usually use CPAN for that stuff.

To access CPAN on Mac just open a Terminal window and type

perl -MCPAN -e shell

That will take you into a shell environment for the CPAN command line utility, from where you can first configure CPAN (usually pretty much automatically by hitting return to accept all its defaults) then install packages via:

install Text::Hunspell

You can discover the names of packages you might want by browsing CPAN itself using your web browser.  For example if you're looking for XML parser modules just type "xml parser" in the search box.  There heaps and heaps of great free modules there for just about anything you can imagine.

Now the problem comes on Mac where your module you want to install depends on some binary program that you've installed, but which Perl cannot find.  Because Perl is built on C and has a Unix like behavior for compiling and otherwise dealing with binary programs it will fall back to trying to use the pkg-config utility to find the binary programs.

In my case I had installed Hunspell from the source package available on their website.  Once I had downloaded the .tar.gz file I built it via:

cd ~/build
tar xf ~/Download/hunspell-1.3.3.tar
cd hunspell-1.3.3
./configure
make
sudo make install

If you're trying to do the same thing, or trying to build some other software and are getting errors about the compiler and toolchain, make sure that first you have installed the command line version of the Xcode tools.  There's a good guide on this Rails site.  If you can type

gcc -v

and get something like

Apple LLVM version 7.0.0

Then you already have the tools.  Otherwise follow the guide to make sure you have Xcode installed and then run

xcode-select --install

...to install then.

OK.  We have a new binary program - in my case hunspell - installed in /usr/local - and now we want to hook up Perl to it but there is a problem.  Perl won't look in /usr/local by default and thus you will get failures from CPAN's shell when you try to install.

To fix this in my case I installed pkg-config from the handy installer on this page.  You want the link that says Download: PkgConfig.pkg - once downloaded install it as usual for .pkg files but note you'll need to right-click and "Open" it as its not signed.  Note that pkg-config gets installed under /opt/pkgconfig/bin.

Once its installed you'll need to tell your shell how to find the relevant files: add these lines to your bash profile by editing the appropriate file:

~/.bash_profile

...and adding the following lines:

export PATH="$PATH:/opt/pkgconfig/bin"
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"

Now you're ready to run the Perl CPAN shell again.  One more thing however:  if you are going to install CPAN modules for the whole of your Mac OS X system, rather than just to your local user account you may run into issues.

If you run the following command:

sudo perl -MCPAN -e shell

to install as root, or if you ask Perl to go to sudo for you, then your build environment may not get the environment variable that you so painstakingly added to your bash profile.  To fix this pass the -E switch to sudo like this:

sudo -E perl -MCPAN -e shell

Now you should be good to go ahead and install loads of cool Perl modules!  Have fun.


Update: If you run perl unprivileged by typing 

perl -MCPAN -e shell

Then you will get a prompt inside CPAN asking you if you want to use local::lib - if you accept that you'll get a mysterious environment variable added to your .bashrc that causes your perl installs to go into your home directory, e.g. ~/perl5

This just wasted several hours as following that CPAN could not find those modules and you get piles of errors about modules not found, wrong versions, and missing dependencies.  It's because the MakeMaker is installing its stuff into the ~/perl5 directory as instructed by PERL_MM_OPT.  But CPAN is not looking there.

To discover if you've hit this issue type 

env

in a Terminal and check if one of the variables is PERL_MM_OPT.  If it is then local::lib as implemented by the CPAN shell has modified your .bashrc for you.  Nice.

Just edit .bashrc to remove the offending lines (they're documented here) and then start a new Terminal window to get the shell environment minus the option.  Now to be safe delete the ~/perl5 directory, the ~/.cpan directory and start again from scratch with your privileged CPAN using sudo as above:

sudo -E perl -MCPAN -e shell

If you really want to use local::lib then try looking up separate doc for that.  Its beyond the scope of this post.