1 from distutils.command.build_ext import build_ext
2 from distutils.core import Extension
3 from types import ListType
6 class mybuild_ext(build_ext):
8 This distutils command is meant to be used with MyExtension extension, which
9 defines a swig_include attribute.
11 build_ext.user_options.append(('swig-include=','S',
12 "list of directories for swig to search in" +
15 def initialize_options (self):
16 build_ext.initialize_options(self)
17 self.swig_include = None
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(":")
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
28 if self.swig_include==None:self.swig_include=ext.swig_include
29 if self.swig_cpp==None:self.swig_cpp=ext.swig_cpp
31 build_ext.build_extension(self,ext)
33 def swig_sources (self, sources):
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.
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
50 ## Modified lines (compared to buil_exts.wig_sources original method)
52 target_ext = '_wrap.cpp'
54 target_ext = '_wrap.c'
55 ## End of modification
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]
66 new_sources.append(source)
71 swig = self.find_swig()
73 ## Modified lines (compared to buil_exts.wig_sources original method)
74 swig_cmd = [swig, "-python"]
76 swig_cmd.append("-c++")
79 for pth in self.swig_include:
80 swig_cmd.append("-I%s"%pth)
81 ## End of modification
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).
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
104 class MyExtension(Extension):
106 This class extends basic distutils Extension class, adding two keyword
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.
112 def __init__(self,swig_include=None,swig_cpp=None,**args):
113 Extension.__init__(self,**args)
115 assert ((swig_include==None or type(swig_include) is ListType),
116 "swig_include must be a list of strings")
118 self.swig_include = swig_include or []
119 self.swig_cpp = swig_cpp
122 Example of use of these classes in distutils setup method :
124 from Transfert.tcDistUtils import mybuild_ext,MyExtension
127 description="blah blah blah",
129 author_email="i.hate@spam.com",
130 url="http://www.fakeurl.com",
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",
136 include_dirs=["/usr/include/python2.1",
138 libraries=["vtkGraphics"],
139 swig_cpp=1, # C++ support
140 swig_include=["src"] # SWIG include dirs
145 and then run "python setup.py build"...