[Distutils] Compiling libraries

Greg Ward gward@cnri.reston.va.us
Thu, 2 Dec 1999 12:52:35 -0500


On 02 December 1999, Andrew M. Kuchling said:
> This reminds me of something; I've looked at using Distutils for the
> PyXML package, and ran aground on compiling Expat, a library required
> for the other stuff.  What I'd want to do is jump out of the Distutils
> framework and run 'cd expat ; make'.  How should that be done?
> Writing my own subclass for the build command?  Is there a 'run this
> set of shell commands' hook?  Or should I just list every single .c
> file in Expat as a dependency for the relevant module? (After all,
> running shell commands is a Unix-ism.)

Not handled yet.  I had the same problem writing the example setup.py
for PIL; it simply doesn't know how to build /F's libimaging.a, so
requires the user to do it.  Blecchhh.

The good news is that the Distutils compiler framework was designed to
be able to handle this sort of thing.  The bad news is I'm not sure how
the hint "please build library X first" should go into the setup file.
Perhaps a new command, "build_lib" or "build_clib" that -- like
"build_ext" -- uses the compiler framework to build C code, but with a
libX.a or X.lib file as the end result, rather than a Python extension
module.  My main concern is not limiting myself to C libraries; I
*assume* C++ libraries are much the same, but I know for a fact that
Java is very different (and yes, I still want to support Java extensions
for JPython someday).

For now, I would put something like this:

    if not os.path.exists libfile ("expat"):
        if os.plat == 'posix':
            system "cd expat ; make"
        else:
            raise SystemExit, "you have to build the expat library first"
        
where the function 'libfile' might look like this:

    def libfile (libname):
        from distutils.ccompiler import new_compiler
        compiler = new_compiler ()
        return compiler.library_filename (libname)

Paying attention to the directory where libexpat.a (or whatever it's
called) should live is left as an exercise for the reader.  Hint: the
'library_filename()' method doesn't know about directories (hmmm).

        Greg