[Distutils] Suggested additions to function argument list

Lyle Johnson jlj@cfdrc.com
Fri, 12 May 2000 11:19:22 -0500


All,

In trying to implement the compiler class for Borland's C++ compiler I've
run up against a minor snag or two.

First, some background. For extension modules on Windows, we want to support
the specification of an optional module definition file (a.k.a. a .DEF
file). On Unix I believe it's true that all of the symbols in a shared
library are "exported" so this is a non-issue. On Windows, however, you must
specify in one way or another which symbols in a DLL are to be exported. One
way to do this is to provide the exported symbols' names in a .DEF file
which you must write (it's a specially-formatted ASCII text file). Another
way to do this is list each of the exported symbols' names on the linker
command line using a linker-specific switch.

Currently, a module developer can tell the Distutils which DEF file to use
for each extension module with the "def_file" key, e.g.:

    setup (...,
        ext_modules = [
            ('module1',
                { 'sources' : ['module1.c'],
                  'def_file' : ['module1.def']
                }
            ),
            ('module2',
                { 'sources' : ['module2.c'],
                  'def_file' : ['module2.def']
                }
            ),
        ]
    )

If the "def_file" information for an extension module is not explicitly
specified, there is code in the build_ext command which guesses a likely
name for the .DEF file (basically module_name + ".def") and sees if that
file exists. If so, it uses that file. Otherwise, we adopt a reasonable
fallback position and guess the initialization function's name to be "init"
+ module_name and ask the linker to export that symbol for us.

OK, we have now arrived at the problem part ;)

The way to specify either the .DEF file name or the exported symbol name(s)
is linker-specific. For Microsoft's linker they are passed along as
straightforward arguments, either:

	/DEF:module1.def

or

	/EXPORTS:initmodule1

but for Borland's linker this information comes in very differently -- not
as simple arguments which you can just append to the linker's argument list.

Since only the compiler class knows for sure how to specify the .DEF file
name (or alternatively the exported symbols list) it seems that we should
pass this information directly to the compiler through the
link_shared_object() function's argument list, instead of cooking up those
arguments in the build_ext command. I'd propose adding an additional
argument to the function's signature (its default could be None and could be
ignored by non-Windows compilers).

Changing the subject, it might also be appropriate to pass down the
temporary files directory for the current extension's build, unless this
kind of code:

	build_ext = self.find_peer ('build_ext')
      build_temp = build_ext.build_temp

is considered safe. If this doesn't violate encapsulation (for the compiler
object to know that the build_ext object has an attribute named
"build_temp") then I'll just do this and sleep soundly ;)

Sorry for the rambling e-mail!

Lyle