[Python-Dev] addressing distutils inability to track file dependencies

Jeremy Hylton jeremy@zope.com
Fri, 14 Jun 2002 04:25:15 -0400


>>>>> "MS" =3D=3D Martin Sj=F6gren <martin@strakt.com> writes:

  >> But this is wrong: it's not foo1.c that depends on bar.h, it's
  >> foo1.o.

  MS> You're right.

On the other hand, distutils setup scripts don't talk about .o files
directly.  They talk about the .c file and assume there is a
one-to-one correspondence between .c files and .o files.

  >> With the latest CVS, on Unix or Linux, try this:
  >>
  >> - Run Make to be sure you are up to date
  >> - Touch Modules/socketobject.h
  >> - Run Make again
  >>
  >> The latest setup.py has directives that tell it that the _socket
  >> and _ssl modules depend on socketmodule.h, and this makes it
  >> rebuild the necessary .o and .so files (through the changes to
  >> distutils that Jeremy made).

  MS> Cool. But my module consists of several .c files, how do I
  MS> specify which .o files depend on which .h files?

I did something simpler, as Guido mentioned.  I added global
dependencies for an extension.  This has been fine for all the
extensions that I commonly build because they have only one or several
source files.  Recompiling a few .c files costs little.

I agree that it would be nice to have fine-grained dependency
tracking, but that costs more in the implementation and to use.
Thomas Heller has a patch on SF (don't recall the number) that handles
per-file dependencies.  I didn't care for the way the dependencies are
spelled in the setup script, but something like the dict that Martin
(the other Martin, right?) suggested seems workable.

  MS> Now, it's a shame I have to maintain compatability with the
  MS> Python 2.1 and Python 2.2 distributions in my setup.py ;)
  MS> I suppose I could try/except...

We should come up with a good hack to use in setup scripts.  This is
my first try.  It's got too many lines, but it works.

# A hack to determine if Extension objects support the depends keyword =
arg.
if not "depends" in Extension.__init__.func_code.co_varnames:
    # If it doesn't, create a local replacement that removes depends
    # from the kwargs before calling the regular constructor.
    _Extension =3D Extension
    class Extension(_Extension):
        def __init__(self, name, sources, **kwargs):
            if "depends" in kwargs:
                del kwargs["depends"]
            _Extension.__init__(self, name, sources, **kwargs)

Jeremy