Sunday, June 14, 2009

installing GNU gettext for use with Python on OS X

I've been working on my blog post about Python's gettext module for the past couple of mornings, and ran into a snag. The documentation claims that the Python source distribution includes all the tools you'll need, but when I got to the point where I wanted to write examples of internationalizing plural strings, pygettext.py wasn't working.

It worked great for extracting individual string messages up to that point, but refused to extract messages wrapped in the ungettext() call, even when I used what seemed to be the appropriate command line options. I ended up installing the GNU gettext tools and using xgettext instead. Installation took me longer than I expected, so I'm documenting the process I went through here.

Fink or MacPorts: Not so much.

Since OS X doesn't ship with a version of gettext by default, and there doesn't seem to be one in the Xcode package (Apple has their own internationalization tools), I needed to find a copy elsewhere.

Ages ago I had installed fink as an "easy" way to grab copies of these sorts of utilities. However, it seems that somewhere along the line the version of fink I have stopped working (probably due to upgrading to 10.5, I haven't tried using fink or FinkCommander directly in some time). After wiping and reinstalling, I was pleased to find a slightly old version (0.14.5) of gettext installed as part of the default set of packages. Unfortunately, xgettext wasn't included in the package at all.

Next, I grabbed a copy of MacPorts, a competitor to fink. Although I've been warned off of MacPorts by a few people I trust, others have had no problems with it. Installation was fairly easy, and as with fink it installed everything to its own directory tree (under /opt/local). Once I had the port program installed, the next step was to run:

$ sudo port install gettext


It downloaded several dependencies, patched the source, compiled everything, and installed it. Voila! Well, not so much.

Even though the most current version of gettext (0.17) was installed, and the documentation clearly described the included Python language support, the binary refused to recognize any language other than C.

Scratch that.

Compiling from Source: Partial Success

Since MacPorts had to download the package and compile it anyway, I decided to go ahead and do that on my own. I was a little wary because I wasn't exactly sure what port was doing in its "patching" step, but I thought I would give it a try anyway. I snagged the most recent tarball from the gettext site and ran the usual

$ ./configure
$ make


That gave me a binary for xgettext inside the source directory, and testing it against my Python source yielded the results I wanted. A simple .pot file was extracted with the original message strings and placeholders for singular and plural translations.

Next, I thought I'd get clever and install the results into the virtualenv I use for working on PyMOTW. Re-configuring with my --prefix set to $VIRTUAL_ENV, rebuilding, then running make install copied the binaries and a bunch of associated data files right where I expected them to be. And the binary only recognized the C language.

After a little more fighting, I did manage to get it working by installing with a prefix of $VIRTUAL_ENV/gettext and adding $VIRTUAL_ENV/gettext/bin to my PATH. I'm not sure if the problem was solved by clearing out an older, bad version of xgettext from elsewhere in my path or if using $VIRTUAL_ENV as the prefix somehow confused the install script.

Conclusion: I think I understand why internationalization is frequently the last feature dealt with in a project.

4 comments:

jay@thecapacity said...

I've had the same types of problems with Fink, e.g. their site shows a package but my installation won't find it.

Oh well at least I can get enough so my mac feels like linux and not BSD :D

edlo said...

I've had similar problems with both fink and MacPorts over time usually associated with an OS or porting system upgrade. All of which is fine if you can do an OS wipe and reinstall but if not it can be a critical blocker.

Doug Hellmann said...

@edlo - I haven't tried yet, but both fink and MacPorts seem to imply you can just delete their directory and install from scratch. Has that worked for you, or did you really have to re-install the OS?

Anonymous said...

I used to use macports and fink, I've finally moved to NetBSD's pkgsrc. It works fairly well; I just checked and some package I installed also installed gettext-lib as a dependency.

It's worked fairly well, I've been able to build a great many packages for both 10.4 and 10.5.