[Distutils] Building PIL with Distutils

Greg Ward gward@cnri.reston.va.us
Fri, 4 Feb 2000 22:17:35 -0500

Content-Type: text/plain; charset=us-ascii

Hi all --

I've just finished hacking in the feature that allows Distutils to build
a standalone C library before building any extension modules.  This
model is used by PIL, and I've used it in the past for a Perl extension,
so I'm sure it's a useful thing to have.

To demonstrate, I've just released a new code snapshot:


If you want to try it out, you'll need
  * the 2000-02-04 Distutils code snapshot installed on your system
  * the PIL source distribution
  * a C compiler

It's entirely possible that this will work under Windows, but I expect
it will take some messing around.  The first hurdle is to generate
libImaging/ImConfig.h; under Unix, this is a snap:

  cd libImaging ; ./configure

Fredrik, do you perchance have a version of ImConfig.h that you use to
build PIL on Windows?

Next, you have to (ugh) edit the setup script.  I hate this, but there's
going to have to be a heckuva lot of code written before it's no longer
required (can you say "Autoconf in Python"?).  You need to a) specify
which optional libraries (from jpeglib, zlib, tcl, and tk) you have
installed, and b) where they are installed.  This is the bit that, in
principle, ought to work under Windows as long as you have the .h and
.lib files and know where they are.

Then just run the setup script.  If you like doing things in small

    python setup.py build_lib
    python setup.py build_ext

Or, if you prefer medium sized chunks:

    python setup.py build

And if you really enjoy biting off a lot at once:

    python setup.py install

Please let me know how this works for you -- it worked great for me
under Linux, with the four optional libraries all in /usr/{lib,include}.
When I tried it on Solaris, I had to hack up the setup script to have
the big editable section at the top ("Oh yeah, not every Unix system has
all of these libraries installed...").  Now it works for me on Solaris.
As usual, I'd love to hear if anyone gets it to work under Windows.


PS. I've attached the example PIL setup script in case you're curious,
but not curious enough to download the Distutils snapshot.  Just to be
sure you know: this WILL NOT WORK with Distutils 0.1.3!  It needs the
2000-02-04 snapshot.

Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pil_setup.py"

#!/usr/bin/env python

"""Example setup.py for Fredrik Lundh's Imaging library (the PIL

# created 1999/09/19, Greg Ward

__rcsid__ = "$Id: pil_setup.py,v 1.7 2000/02/05 03:00:07 gward Exp $"

import os
from distutils.core import setup
from distutils.ccompiler import new_compiler
from glob import glob

lib_dir = 'libImaging'
lib_name = "Imaging"
lib_sources = glob (os.path.join (lib_dir, "[A-Z]*.c"))

# PIL can build against several optional libraries: jpeglib, zlib, and
# Tcl/Tk.  Since the Distutils hasn't yet tackled the job of rewriting
# Autoconf in Python, you have to supply some vital data here: which of
# these libraries to use, where to find their header files, and where to
# find the libraries themselves.
# 'optional_libs' just lists the library names -- in a Unix environment,
# each of these strings will be translated to eg. "-ljpeg" on the
# link command line, meaning you have to have libjpeg.a somewhere.
# 'include_dirs' is a list of directories to search for header files for
# the optional libraries plus PIL's own internal support library
# (libImaging/libImaging.a under Unix).  You should only customize the
# entries after 'lib_dir'.  For a typical Unix installation
# "/usr/local/include" is probably what you want, since that's the
# traditional place to install third-party libraries.  (Your mileage may
# vary, so check with your system administrator if you're not sure
# whether these libraries are installed and where they are installed.)
# Most Linux distributions should include those libraries
# out-of-the-box, so the header files should be in /usr/include, meaning
# you don't have to add anything to include_dirs.
# Finally, 'library_dirs' lists the locations of PIL's internal support
# library as well as the optional third-party libraries.  Again, the
# traditional Unix location is "/usr/local/lib", and you probably don't
# need to list any extra library directories for most Linux
# distributions.

optional_libs = ['jpeg', 'z', 'tcl8.0', 'tk8.0']  # good sysadmin
#optional_libs = []                               # lazy sysadmin

include_dirs = [lib_dir, '/usr/local/include']   # typical Unix
#include_dirs = [lib_dir, '/depot/sundry/include'] # CNRI's setup
#include_dirs = [lib_dir]                          # most Linux distributions

library_dirs = [lib_dir, '/usr/local/lib']        # typical Unix
#library_dirs = [lib_dir, '/depot/sundry/plat/lib']# CNRI's setup
#library_dirs = [lib_dir]                          # most Linux distributions

# ------------------------------------------------------------------------
# You should't have to change anything below this point!

# Figure out macros to define based on whether Tcl/Tk are in the
# 'optional_libs' list.
use_tcl = use_tk = 0
for lib in optional_libs:
    if lib[0:3] == 'tcl':
        use_tcl = 1
    if lib[0:2] == 'tk':
        use_tk = 1

if use_tcl and use_tk:
    ext_macros = [('WITH_TKINTER', None)]
    ext_macros = None

# arg -- still haven't written autoconf in Python, so we rely on
# the user to run the configure script
config_header = os.path.join (lib_dir, "ImConfig.h")
if not os.path.exists (config_header):
    raise SystemExit, \
          "%s not found -- did you run the configure script in %s?" % \
          (config_header, lib_dir)

setup (name = "PIL",
       version = "1.0",
       description = "Python Imaging Library",
       author = "Fredrik Lundh",
       author_email = "fredrik@pythonware.com",
       url = "http://www.pythonware.com/downloads.htm",

       # Hmm, we don't install the sane module or PIL's "Scripts"
       # directory.  We could handle sane (in a slightly ugly way -- since
       # it's in a directory of its own, it would necessarily be the only
       # top-level module in the distribution), but Distutils as yet has no
       # facilities for installing scripts.

       libraries = [('%s/%s' % (lib_dir, lib_name),
                     { 'sources': lib_sources,
                       'include_dirs': include_dirs,
                       'macros': [('HAVE_CONFIG_H', None)],

       packages = ['PIL'],
       ext_modules = \
             { 'sources': ['_imaging.c', 'decode.c', 'encode.c',
                           'map.c', 'display.c', 'outline.c', 'path.c'],
               # This must include the directories with the JPEG,
               # zlib, and Tcl/Tk header files (if installed)
               'include_dirs': include_dirs,

               # Keep this for Tcl/Tk support
               'macros': ext_macros,

               # This must include the directories with the JPEG, zlib,
               # and Tcl/Tk libraries (whatever's available)
               'library_dirs': library_dirs,

               # And this, of course, lists which of those external
               # libraries to link against (plus libImaging, which *must*
               # be included!)
               'libraries': ['libImaging/Imaging'] + optional_libs