]> Creatis software - gdcm.git/blob - distutilsSwigCPlusPlus.py
* The subdirectory Data (containing all the images used for the
[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                         ## Modified lines (compared to buil_exts.wig_sources original method)
88                         # When swig generated some shadow classes, place them under
89                         # self.build_lib (the build directory for Python source).
90                         if self.swig_cpp:
91                                 # Generate the full pathname of the shadow classes file
92                                 import string
93                                 swig_shadow = string.split(os.path.basename(source), ".")[0]
94                                 swig_shadow = swig_shadow + '.py'
95                                 # On win32 swig places the shadow classes in the directory
96                                 # where it was invoked. This is to be opposed to posix where
97                                 # swig places the shadow classes aside the C++ wrapping code
98                                 # (the target in our context).
99                                 if(os.name=='posix'):
100                                         infile = os.path.join(os.path.dirname(source), swig_shadow)
101                                 else:
102                                         infile = swig_shadow
103                                 if os.path.isfile(infile):
104                                         outfile = [self.build_lib, self.distribution.get_name()]
105                                         outfile.append(swig_shadow)
106                                         outfile = apply(os.path.join, outfile)
107                                         self.copy_file(infile, outfile, preserve_mode=0)
108                                 else:
109                                         self.announce("Warning: swig shadow classes not copied")
110                         ## End of modification
111
112                 return new_sources
113
114 class MyExtension(Extension):
115         """
116         This class extends basic distutils Extension class, adding two keyword
117         arguments :
118                 * swig_cpp, which triggers -c++ mode when swigging
119                 * swig_include, which specifies -I flag when swigging
120         This class is meant to be build with mybuild_ext distutils command.
121         """
122         def __init__(self,swig_include=None,swig_cpp=None,**args):
123                 Extension.__init__(self,**args)
124
125                 assert ((swig_include==None or type(swig_include) is ListType),
126                                   "swig_include must be a list of strings")
127
128                 self.swig_include = swig_include or []
129                 self.swig_cpp = swig_cpp
130
131 """
132 Example of use of these classes in distutils setup method :
133
134 from Transfert.tcDistUtils import mybuild_ext,MyExtension
135 setup(name="xxx",
136                 version="X.Y",
137                 description="blah blah blah",
138                 author="John Doe",
139                 author_email="i.hate@spam.com",
140                 url="http://www.fakeurl.com",
141                 packages=["yyy"],               
142                 cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext
143                 ext_modules=[MyExtension(name="src/xxx, # instance of our Extension class
144                                                                                  sources=["src/xxx.cpp",
145                                                                                                          "src/xxx.i"],
146                                                                                  include_dirs=["/usr/include/python2.1",
147                                                                                                                         "/usr/include/vtk"],
148                                                                                  libraries=["vtkGraphics"],
149                                                                                  swig_cpp=1, # C++ support
150                                                                                  swig_include=["src"] # SWIG include dirs
151                                                                                 )
152                                                 ]
153                 )
154                 
155 and then run "python setup.py build"...
156 """