Monday, October 03, 2005

MCPAN is for wimps, OR libexpat and I

Hi. If you're like me, you spend most of your time trying to do neat things in Perl.

OK, so no you're not. And frankly, neither am I. However, if you're trying to do XML stuff in Perl, like slurping it into a DOM object and/or doing XSLT transformations, you need XML::XSLT. Unfortunately, it isn't that simple. XML::XSLT depends on XML::Parser, which depends on other modules. XML::XSLT also depends on XML::Parser::Expat, which isn't actually installed by XML::Parser, but libxml. Now, MCPAN will pretend it handles all the dependencies behind the one you're trying to install, but there's a hitch. Two, really.

One, MCPAN is unavailable to non-root users, because it can't do local installs of Perl modules. At home on a Debian Sarge box or my dual G5, this is not a problem. At work, where I'm using my employer's Solaris box, I don't have the privileges to run MCPAN, so I have to manually discover all the dependencies and perl Makefile.PL install each module in turn, by hand from source, being sure to point the installation at a local location.

Two, MCPAN is excellent at handling dependencies -- so long as what it needs are other Perl modules. The heart of XML work in Perl (and Python, for that matter) is a little tiny non-Perl library called Expat. It's a C library which is usually located under /usr/local.

Except that it isn't really a default installation on *nixes. Debian Sarge, yes. OS X/BSD, no. Solaris, yes but not necessarily in /usr/local where XML::Parser expects it, and it certainly isn't part of Windows, either. This is annoying enough that PHP's designers reverse-engineered their own expat-compatible library into PHP.

Moreover, MCPAN ain't apt-get. If it can't handle a dependency, it cries and wets its pants, leaving you to dredge through all its reports in hopes of figuring out what to do. At least apt-get tells you what you might need to do, rather than just suggesting you force the install.

Google "libexpat OS X" to witness the wailing and moaning of the damned (Perl, Python and others) unable to understand how they were left behind. Life is hell.

If you're one of them and you found this blog, here's what you have to do. First off, log in as root on your Mac and open a browser. Go here to get the source code archive for expat. You're going to do this old-school and compile it yourself. Relax, I'll hold your hand through this.

Now that you have the tar.gz file on your desktop, resist the impulse to double-click it. If you have, delete the folder. Open the Terminal:
$ cd ~/Desktop
$ ls
expat-1.95.8.tar.gz
Applications
[yada yada]
$ gunzip expat-1.95.8.tar.gz
$ tar -xvf expat-1.95.8.tar
$ cd expat-1.95.8
$ ./configure
$ make
$ make install


That's it. Go back to MCPAN and install XML::XSLT; the rest should fall into place.

[As nice as the OS X and Stuffit utilities are for decompressing tar.gz, gunzip and tar do what *nixes expect down to the letter, and desktop decompression utilities have been known to do strange things to filenames. WinZip, for example, creates the expat folder seemingly flawlessly, but your shell will insist to high heaven that there's no configure file to ./ even as you see it there.]

Fink's the OS X version of apt-get. The downside to Fink is that like apt-get, you're stuck with what's available in the current repository, and worse, each new release of OS X has unpleasant repercussions for Fink. When Debian has a new release, the repository tends to be ready; when OS X has a new release, there's endless bitching about what's broken in Fink.

FWIW, I ran the MCPAN XML::XSLT installs on Debian Sarge and Tiger simultaneously. Debian handled it flawlessly, only occasionally asking yes/no questions to which the Enter key was sufficient. OS X tried to do the same, but gargled on its own vomit until I manually installed expat and started over. Ironically, when I tried to use perldoc to verify that XML::XSLT was installed on Linux, perldoc wasn't there and had to be installed using apt-get.

It's conceivable that a default install of Debian doesn't have expat, either. Nevertheless, this thing should be integrated into all *nix default installs. MCPAN should be as good as apt-get.