Mimsy Were the Borogoves

Hacks: Articles about programming in Python, Perl, PHP, and whatever else I happen to feel like hacking at.

Python Imaging Library on Leopard Intel

Jerry Stratton, July 13, 2008

Installing anything that uses mod_python on Leopard Intel has become a major pain. The problem is that Apache under Leopard runs as 64-bit, but most things are compiling as 32-bit. I’ve had to use SQLite for the backend Django database on our Leopard Server because of this. There is no MySQL package for 64-bit Intel, and that makes it very difficult to compile Python’s MySQLdb as x86_64, which in turn causes Django to fail when run under Apache, because Apache can’t “find” the right code for the architecture.

One of the things I want that Django install to do is manage images, so I thought I’d try installing django-photologue. However, photologue requires the Python Image Library; and the Python Imaging Library requires libjpeg.

The big problem with tracking this problem down is that Django and the Python Image Library hide the real error, and instead say that “The _imaging C module is not installed” (triggered by .load() in /Library/Python/2.5/site-packages/PIL/Image.py). Django hides it behind “Upload a valid image. The file you uploaded was either not an image or a corrupted image.” I discovered the real errors by commenting out the "try except" around that code.

It took a bit of searching to find the various mailing list and blog entries that address these issues, so I’m combining them here for my own future reference and yours.

Compile libjpeg as x86_64

First, libjpeg; in jpeg-6b/Makefile add -arch x86_64 in two places in the Makefile:

  • CFLAGS= -Os -I$(srcdir) -arch x86_64
  • # Link-time cc options:
  • LDFLAGS= -arch x86_64

then do “make all”.

Second, re-run GCC to create the dynamic library libjpeg.dylib.

  • gcc -dynamiclib -flat_namespace -undefined suppress -o .libs/libjpeg.62.0.0.dylib jcapimin.lo jcapistd.lo jctrans.lo jcparam.lo jdatadst.lo jcinit.lo jcmaster.lo jcmarker.lo jcmainct.lo jcprepct.lo jccoefct.lo jccolor.lo jcsample.lo jchuff.lo jcphuff.lo jcdctmgr.lo jfdctfst.lo jfdctflt.lo jfdctint.lo jdapimin.lo jdapistd.lo jdtrans.lo jdatasrc.lo jdmaster.lo jdinput.lo jdmarker.lo jdhuff.lo jdphuff.lo jdmainct.lo jdcoefct.lo jdpostct.lo jddctmgr.lo jidctfst.lo jidctflt.lo jidctint.lo jidctred.lo jdsample.lo jdcolor.lo jquant1.lo jquant2.lo jdmerge.lo jcomapi.lo jutils.lo jerror.lo jmemmgr.lo jmemnobs.lo -lc -install_name /usr/local/lib/libjpeg.62.dylib -compatibility_version 63 -current_version 63.0 -arch x86_64

You can now check that the correct architecture (x86_64) is present and install it if so:

  • file .libs/libjpeg.dylib
  • sudo make install-lib

That gets the right architecture into libjpeg.dylib so that the Python Imaging Library can use it.

Compile Python Imaging Library as x86_64

In PIL (Imaging-1.1.6) remove the build files if you’ve already tried building the library (rm -r build/*). Then, edit setup.py:

[toggle code]

  • OrigExtension = Extension
  • def Extension(*args, **kwargs):
    • extra_args = ['-arch', 'x86_64']
    • kwargs['extra_compile_args'] = extra_args + kwargs.get('extra_compile_args', [])
    • kwargs['extra_link_args'] = extra_args + kwargs.get('extra_link_args', [])
    • return OrigExtension(*args, **kwargs)

Now you can build and install the image library:

  • python setup.py build
  • sudo python setup.py install

Note that I’m pretty sure that other things, such as freetype, are still going to fail. If I have need to look at it, and successfully do so, I’ll add that to this article also.

  1. <- Regrouping Django
  2. Media file duration ->