]> Creatis software - gdcm.git/blob - distutilsSwigCPlusPlus.py
* Eventually, python/gdcmPython was renamed to gdcmPython. This
[gdcm.git] / distutilsSwigCPlusPlus.py
1 from distutils.command.build_ext import build_ext
2 from distutils.core import Extension
3 from types import ListType
4 import os
5
6 class mybuild_ext(build_ext):
7         """
8         This distutils command is meant to be used with MyExtension extension, which
9         defines a swig_include attribute.
10         """
11         build_ext.user_options.append(('swig-include=','S',
12                                                                                          "list of directories for swig to search in" +
13                                                                                          "for header files"))
14                                                                                          
15         def initialize_options (self):
16                 build_ext.initialize_options(self)
17                 self.swig_include = None
18                 
19         def finalize_options (self):
20                 build_ext.finalize_options(self)
21                 if self.swig_include!=None:
22                         self.swig_include=self.swig_include.split(":")
23         
24         def build_extension(self, ext):
25                 # command-line arguments prevail over extension arguments
26                 # but if no command-line argument is defined, extension argument is
27                 # taken into account
28                 if self.swig_include==None:self.swig_include=ext.swig_include
29                 if self.swig_cpp==None:self.swig_cpp=ext.swig_cpp
30                                 
31                 build_ext.build_extension(self,ext)
32         
33         def swig_sources (self, sources):
34
35                 """Walk the list of source files in 'sources', looking for SWIG
36                 interface (.i) files.  Run SWIG on all that are found, and
37                 return a modified 'sources' list with SWIG source files replaced
38                 by the generated C (or C++) files.
39                 """
40
41                 new_sources = []
42                 swig_sources = []
43                 swig_targets = {}
44
45                 # XXX this drops generated C/C++ files into the source tree, which
46                 # is fine for developers who want to distribute the generated
47                 # source -- but there should be an option to put SWIG output in
48                 # the temp dir.
49
50                 ## Modified lines (compared to buil_exts.wig_sources original method)
51                 if self.swig_cpp:
52                         target_ext = '_wrap.cpp'
53                 else:
54                         target_ext = '_wrap.c'
55                 ## End of modification
56
57                 for source in sources:
58                         (base, ext) = os.path.splitext(source)
59                         if ext == ".i":             # SWIG interface file
60                                 new_sources.append(base + target_ext)
61                                 swig_sources.append(source)
62                                 swig_targets[source] = new_sources[-1]
63                         elif ext == ".h":
64                                 continue
65                         else:
66                                 new_sources.append(source)
67
68                 if not swig_sources:
69                         return new_sources
70
71                 swig = self.find_swig()
72                 
73                 ## Modified lines (compared to buil_exts.wig_sources original method)
74                 swig_cmd = [swig, "-python"]
75                 if self.swig_cpp:
76                         swig_cmd.append("-c++")
77
78                 if self.swig_include:
79                         for pth in self.swig_include:
80                                 swig_cmd.append("-I%s"%pth)
81                 ## End of modification
82
83                 for source in swig_sources:
84                         target = swig_targets[source]
85                         self.announce("swigging %s to %s" % (source, target))
86                         self.spawn(swig_cmd + ["-o", target, source])
87                         print swig_cmd + ["-o", target, source]
88                         ## Modified lines (compared to buil_exts.wig_sources original method)
89               # When swig generated some shadow classes, place them under
90               # self.build_lib (the build directory for Python source).
91                         import string
92                         swig_shadow = string.split(os.path.basename(source), ".")[0]
93                         swig_shadow = swig_shadow + '.py'
94                         infile      = os.path.join(os.path.dirname(source), swig_shadow)
95                         if os.path.isfile(infile):
96                                 outfile = [self.build_lib, self.distribution.get_name()]
97                                 outfile.append(swig_shadow)
98                                 outfile = apply(os.path.join, outfile)
99                                 self.copy_file(infile, outfile, preserve_mode=0)
100                         ## End of modification
101         
102                 return new_sources
103
104 class MyExtension(Extension):
105         """
106         This class extends basic distutils Extension class, adding two keyword 
107         arguments :
108                 * swig_cpp, which triggers -c++ mode when swigging
109                 * swig_include, which specifies -I flag when swigging
110         This class is meant to be build with mybuild_ext distutils command.
111         """
112         def __init__(self,swig_include=None,swig_cpp=None,**args):
113                 Extension.__init__(self,**args)
114                 
115                 assert ((swig_include==None or type(swig_include) is ListType),
116                                   "swig_include must be a list of strings")
117                                   
118                 self.swig_include = swig_include or []
119                 self.swig_cpp = swig_cpp
120
121 """
122 Example of use of these classes in distutils setup method :
123
124 from Transfert.tcDistUtils import mybuild_ext,MyExtension
125 setup(name="xxx",
126                 version="X.Y",
127                 description="blah blah blah",
128                 author="John Doe",
129                 author_email="i.hate@spam.com",
130                 url="http://www.fakeurl.com",
131                 packages=["yyy"],               
132                 cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext
133                 ext_modules=[MyExtension(name="src/xxx, # instance of our Extension class
134                                                                                  sources=["src/xxx.cpp",
135                                                                                                          "src/xxx.i"],
136                                                                                  include_dirs=["/usr/include/python2.1",
137                                                                                                                         "/usr/include/vtk"],
138                                                                                  libraries=["vtkGraphics"],
139                                                                                  swig_cpp=1, # C++ support
140                                                                                  swig_include=["src"] # SWIG include dirs
141                                                                                 )
142                                                 ]
143                 )
144                 
145 and then run "python setup.py build"...
146 """