[Distutils] Better SWIG C++ support
Joerg Baumann
Joerg.Baumann@stud.informatik.uni-erlangen.de
Fri Oct 6 07:24:02 2000
Hi,
I had troubles with distutils 1.0 and the way I use SWIG.
I couldn't find any support for the -shadow option and no way to pass an
extra include dir to swig (like it=B4s possible for the c compiler)
Therefore I wrote a patch.
It adds an extra_swig_args (list of string) option to Extension.
All the strings are passed to swig without modification, but
if extra_swig_args contains "-c++" or "-shadow" there is some special
action:
"-c++": behaves like build_ext --swig-cpp
"-shadow":
Normally swig generates a file:
foo.c -> foo.so=20
In this case SWIG generates two files:
foo.py (python shadow classes, imports fooc)
fooc.c -> fooc.so
With this patch build_ext can handle this und generates for foo.i
(foo.py, fooc.c) compiles them and installs them.=20
=20
Below is the diff against disutils 1.0, apply in your Distutils-1.0
directory with:
patch -p5 < file
I hope it doesn=B4t break anything, isn=B4t against distutils design
principles and is so useful that it might become part of distutils.
Please answer me directly, because I didn=B4t not subscribe ths list.
Regards=20
joerg
=20
Joerg Baumann joerg.baumann@stud.informatik.uni-erlangen.de
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ =20
Beware of bugs in the above code; I have only proved it correct,=20
not tried it.
Don Knuth=20
diff -r -C 2 -x *pyc /home/jgbauman/download/Distutils-1.0/distutils/comman=
d/build_ext.py ./command/build_ext.py
*** /home/jgbauman/download/Distutils-1.0/distutils/command/build_ext.py=09=
Sat Sep 30 20:27:54 2000
--- ./command/build_ext.py=09Fri Oct 6 01:23:08 2000
***************
*** 386,390 ****
# SWIG on 'em to create .c files, and modify the sources list
# accordingly.
! sources =3D self.swig_sources(sources)
=20
# Next, compile the source code to object files.
--- 386,398 ----
# SWIG on 'em to create .c files, and modify the sources list
# accordingly.
! sources,extra_modules =3D self.swig_sources(sources,ext.extra=
_swig_args)
! =20
! # if there are extra_modules after running swig due to -shado=
w option
! # copy them to build/lib.xxx
! for module in extra_modules:
! outfile =3D os.path.join(self.build_lib,os.path.basename(=
module))
! dir =3D os.path.dirname(outfile)
! self.mkpath(dir)
! self.copy_file(module, outfile, preserve_mode=3D0)
=20
# Next, compile the source code to object files.
***************
*** 444,448 ****
=20
=20
! def swig_sources (self, sources):
=20
"""Walk the list of source files in 'sources', looking for SWIG
--- 452,456 ----
=20
=20
! def swig_sources (self, sources, extra_swig_args):
=20
"""Walk the list of source files in 'sources', looking for SWIG
***************
*** 453,456 ****
--- 461,465 ----
=20
new_sources =3D []
+ new_modules =3D []
swig_sources =3D []
swig_targets =3D {}
***************
*** 461,464 ****
--- 470,479 ----
# the temp dir.
=20
+ if "-c++" in extra_swig_args:=20
+ self.swig_cpp=3D1
+ if "-shadow" in extra_swig_args:=20
+ shadow=3D1
+ else:
+ shadow=3DNone
if self.swig_cpp:
target_ext =3D '.cpp'
***************
*** 469,473 ****
(base, ext) =3D os.path.splitext(source)
if ext =3D=3D ".i": # SWIG interface file
! new_sources.append(base + target_ext)
swig_sources.append(source)
swig_targets[source] =3D new_sources[-1]
--- 484,492 ----
(base, ext) =3D os.path.splitext(source)
if ext =3D=3D ".i": # SWIG interface file
! if shadow:=20
! new_modules.append(base + ".py")
! new_sources.append(base + "c" + target_ext)
! else:
! new_sources.append(base + target_ext)
swig_sources.append(source)
swig_targets[source] =3D new_sources[-1]
***************
*** 476,480 ****
=20
if not swig_sources:
! return new_sources
=20
swig =3D self.find_swig()
--- 495,499 ----
=20
if not swig_sources:
! return new_sources,new_modules
=20
swig =3D self.find_swig()
***************
*** 482,486 ****
if self.swig_cpp:
swig_cmd.append("-c++")
!=20
for source in swig_sources:
target =3D swig_targets[source]
--- 501,507 ----
if self.swig_cpp:
swig_cmd.append("-c++")
! for arg in extra_swig_args:
! swig_cmd.append(arg)
! =20
for source in swig_sources:
target =3D swig_targets[source]
***************
*** 488,492 ****
self.spawn(swig_cmd + ["-o", target, source])
=20
! return new_sources
=20
# swig_sources ()
--- 509,513 ----
self.spawn(swig_cmd + ["-o", target, source])
=20
! return new_sources,new_modules
=20
# swig_sources ()
diff -r -C 2 -x *pyc /home/jgbauman/download/Distutils-1.0/distutils/comman=
d/install_lib.py ./command/install_lib.py
*** /home/jgbauman/download/Distutils-1.0/distutils/command/install_lib.py=
=09Tue Oct 3 05:32:37 2000
--- ./command/install_lib.py=09Fri Oct 6 01:11:21 2000
***************
*** 90,94 ****
=20
# (Optionally) compile .py to .pyc
! if outfiles is not None and self.distribution.has_pure_modules():
self.byte_compile(outfiles)
=20
--- 90,94 ----
=20
# (Optionally) compile .py to .pyc
! if outfiles is not None:
self.byte_compile(outfiles)
=20
diff -r -C 2 -x *pyc /home/jgbauman/download/Distutils-1.0/distutils/extens=
ion.py ./extension.py
*** /home/jgbauman/download/Distutils-1.0/distutils/extension.py=09Sun Sep =
17 02:45:18 2000
--- ./extension.py=09Fri Oct 6 01:18:12 2000
***************
*** 74,78 ****
extensions, which typically export exactly one symbol: "init" +
extension_name.
! """
=20
def __init__ (self, name, sources,
--- 74,84 ----
extensions, which typically export exactly one symbol: "init" +
extension_name.
! extra_swig_args : [string]
! any additional options for the swig tool. Unknown options will
! be passed unchanged.
! Known options:
! -c++: enable swig=B4s C++ support
! -shadow: generate shadow classes in python
! """
=20
def __init__ (self, name, sources,
***************
*** 87,90 ****
--- 93,97 ----
extra_link_args=3DNone,
export_symbols=3DNone,
+ extra_swig_args=3DNone,
):
=20
***************
*** 106,109 ****
--- 113,117 ----
self.extra_link_args =3D extra_link_args or []
self.export_symbols =3D export_symbols or []
+ self.extra_swig_args =3D extra_swig_args or []
=20
# class Extension
=20