[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