-2003-05-21 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> with JPR
+2003-05-22 Benoit Regrain <Benoit.Regrain@creatis.insa-lyon.fr>
+ * Modification of setup.py to compile vtk part too. Then, we have 2
+ wrappers which must work with same distutils. For that, we have a
+ generic distutils in distusiltsWrapping.py ; with :
+ - build_extWrap class to wrap generically all extensions,
+ - ExtensionWrap base class for all wrapping extension that contains
+ a wrapper
+ - Wrapper interface which wrap sources
+ + In WrapSwig.py we have extension and wrapper for Swig
+ + In WrapVTK.py we have extension and wrapper for VTK
+ * MANIFEST.in : modifications to consider vtk directory and new python
+ files for compilation
+
+2003-05-21 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> with Benoit Regrain
* Added python wrappers of vtkGdcmReader vtk class (see the
source in vtk/vtkGdcmReader.cxx) :
- vtk/Makefile.am now builds a library
-include distutilsSwigCPlusPlus.py
+include *.py
recursive-include src *.h
+recursive-include vtk *.h
recursive-include Dicts *.dic
recursive-include Data *.*
--- /dev/null
+from distutilsWrapping import *
+from types import ListType
+import os
+
+class SwigWrapper(Wrapper):
+ """
+ This distutils command is meant to be used with MyExtension extension,which
+ defines a swig_include attribute.
+ """
+ def WrapSources(self,distutil,extWrap,sources):
+ """Walk the list of source files in 'sources',looking for SWIG
+ interface(.i) files. Run SWIG on all that are found,and
+ return a modified 'sources' list with SWIG source files replaced
+ by the generated C(or C++) files.
+ """
+
+ new_sources=[]
+ swig_sources=[]
+ swig_targets={}
+
+ # XXX this drops generated C/C++ files into the source tree,which
+ # is fine for developers who want to distribute the generated
+ # source -- but there should be an option to put SWIG output in
+ # the temp dir.
+
+ ## Modified lines(compared to buil_exts.wig_sources original method)
+ if extWrap.swig_cpp:
+ target_ext='_wrap.cpp'
+ else:
+ target_ext='_wrap.c'
+ ## End of modification
+
+ for source in sources:
+ (base,ext)=os.path.splitext(source)
+ if ext==".i": # SWIG interface file
+ new_sources.append(base + target_ext)
+ swig_sources.append(source)
+ swig_targets[source]=new_sources[-1]
+ elif ext==".h":
+ continue
+ else:
+ new_sources.append(source)
+
+ if not swig_sources:
+ return new_sources
+
+ swig=distutil.find_swig()
+
+ ## Modified lines(compared to buil_exts.wig_sources original method)
+ swig_cmd=[swig,"-python"]
+ if extWrap.swig_cpp:
+ swig_cmd.append("-c++")
+
+ if extWrap.swig_include:
+ for pth in extWrap.swig_include:
+ swig_cmd.append("-I%s"%pth)
+ ## End of modification
+
+ for source in swig_sources:
+ target=swig_targets[source]
+ distutil.announce("swigging %s to %s" %(source,target))
+ distutil.spawn(swig_cmd + ["-o",target,source])
+ ## Modified lines(compared to buil_exts.wig_sources original method)
+ # When swig generated some shadow classes,place them under
+ # self.build_lib(the build directory for Python source).
+ if extWrap.swig_cpp:
+ # Generate the full pathname of the shadow classes file
+ import string
+ swig_shadow=string.split(os.path.basename(source),".")[0]
+ swig_shadow=swig_shadow + '.py'
+ # On win32 swig places the shadow classes in the directory
+ # where it was invoked. This is to be opposed to posix where
+ # swig places the shadow classes aside the C++ wrapping code
+ #(the target in our context).
+ if(os.name=='posix'):
+ infile=os.path.join(os.path.dirname(source),swig_shadow)
+ else:
+ infile=swig_shadow
+ if os.path.isfile(infile):
+ outfile=[distutil.build_lib,distutil.distribution.get_name()]
+ outfile.append(swig_shadow)
+ outfile=apply(os.path.join,outfile)
+ distutil.copy_file(infile,outfile,preserve_mode=0)
+ else:
+ distutil.announce("Warning: swig shadow classes not copied")
+ ## End of modification
+
+ return new_sources
+
+class SwigExtension(ExtensionWrap):
+ """
+ This class extends basic distutils Extension class,adding two keyword
+ arguments :
+ * swig_cpp,which triggers -c++ mode when swigging
+ * swig_include,which specifies -I flag when swigging
+ This class is meant to be build with mybuild_ext distutils command.
+ """
+ def __init__(self,swig_include=None,swig_cpp=None,**args):
+ ExtensionWrap.__init__(self,SwigWrapper(),**args)
+
+ assert((swig_include==None or type(swig_include) is ListType),
+ "swig_include must be a list of strings")
+
+ self.swig_include=swig_include or []
+ self.swig_cpp=swig_cpp
+
--- /dev/null
+from distutilsWrapping import *
+import types
+import string
+import os
+
+class VTKWrapper(Wrapper):
+ """
+ This distutils command is meant to be used with MyExtension extension, which
+ defines a swig_include attribute.
+ """
+ def WrapSources(self,distutil,extWrap,sources):
+ """
+ Walk the list of source files in 'sources', looking for VTK
+ interface (vtk*.cxx) files. Compile vtkWrapPythonInit.
+ Run vtkWrapPython on all that are found, and
+ return a modified 'sources' list with SWIG source files replaced
+ by the generated C (or C++) files.
+
+ FIXME nierk
+ """
+ self.__extWrap=extWrap
+
+ newSources=[]
+ vtkSources=[]
+ vtkTargets={}
+
+ # Wrapping of sources
+ target_ext='Python.cxx'
+
+ for source in sources:
+ (base,ext)=os.path.splitext(source)
+ fileName=os.path.split(base)
+ if((ext==".cxx")and(fileName[-1][0:3]=="vtk")):
+ newSources.append(source)
+ newSources.append(base+target_ext)
+ vtkSources.append(base+'.h')
+ vtkTargets[base+'.h']=newSources[-1]
+ else:
+ newSources.append(source)
+
+ # Find vtkWrapPython
+ wrapper=self.FindvtkWrapPython()
+ if(not self.__extWrap.vtkHints):
+ self.__extWrap.vtkHints="toto"
+
+ wrapCmd=[wrapper]
+ for source in vtkSources:
+ target=vtkTargets[source]
+ distutil.announce("VTK wrapping %s to %s" % (source,target))
+ distutil.spawn([wrapper,source,self.__extWrap.vtkHints,target])
+
+ # Compilation of vtkWrapPythonInit
+ vtkWrapInit=self.__extWrap.vtkModule+"Init"+target_ext
+ distutil.announce("VTK init wrapping to %s" % vtkWrapInit)
+ self.WrapInit(vtkSources,vtkWrapInit)
+ newSources.append(vtkWrapInit)
+
+ return newSources
+
+ def FindvtkWrapPython(self):
+ assert(os.path.isfile(self.__extWrap.vtkWrapper),
+ "Write an heuristic in FindvtkWrapPython")
+ return(self.__extWrap.vtkWrapper)
+
+ def WrapInit(self,vtkSource,target):
+ dllName=string.split(self.__extWrap.vtkModule,'.')[-1]
+ f=open(target,"w")
+
+ f.write('#include <string.h>\n')
+ f.write('#include "Python.h"\n\n')
+
+ for src in vtkSource:
+ src=os.path.split(src)[-1]
+ (src,_)=os.path.splitext(src)
+ f.write('extern "C" { ')
+ if(os.name!="posix"):
+ f.write('__declspec( dllexport ) ')
+ f.write('PyObject *PyVTKClass_%sNew(char *); }\n'% src)
+
+ # Lib Init
+ f.write('\nstatic PyMethodDef Py%s_ClassMethods[] = {\n'% dllName)
+ f.write('{NULL, NULL}};\n\n')
+
+ f.write('extern "C" { ')
+ if(os.name!="posix"):
+ f.write('__declspec( dllexport ) ')
+ f.write('void init%s();}\n\n'% dllName)
+
+ f.write('void init%s()\n{\n'% dllName)
+ f.write(' PyObject *m, *d, *c;\n\n')
+ f.write(' static char modulename[] = "%s";\n'% dllName)
+ f.write(' m = Py_InitModule(modulename, Py%s_ClassMethods);\n'% dllName)
+
+ f.write(' d = PyModule_GetDict(m);\n')
+ f.write(' if (!d) Py_FatalError("can''t get dictionary for module %s!");\n\n'% dllName)
+
+ # New function
+ for src in vtkSource:
+ src=os.path.split(src)[-1]
+ (src,_)=os.path.splitext(src)
+ f.write(' if ((c = PyVTKClass_%sNew(modulename)))\n'% src)
+ f.write(' if (-1 == PyDict_SetItemString(d, "%s", c))\n'% src)
+ f.write(' Py_FatalError("can''t add class %s to dictionary!");\n\n'% src)
+ f.write('}\n\n')
+
+ f.close()
+
+class VTKExtension(ExtensionWrap):
+ """
+ This class extends basic distutils Extension class, adding two keyword
+ arguments :
+ * swig_cpp, which triggers -c++ mode when swigging
+ * swig_include, which specifies -I flag when swigging
+ This class is meant to be build with mybuild_ext distutils command.
+ """
+ def __init__(self,name,vtkHints=None,
+ vtkWrapper=None,**args):
+ ExtensionWrap.__init__(self,name=name,wrapper=VTKWrapper(),**args)
+
+ assert(type(name)==types.StringType,"vtk Module must be a string")
+
+ self.vtkHints=vtkHints
+ self.vtkModule=name
+ self.vtkWrapper=vtkWrapper
+
+++ /dev/null
-from distutils.command.build_ext import build_ext
-from distutils.core import Extension
-from types import ListType
-import os
-
-class mybuild_ext(build_ext):
- """
- This distutils command is meant to be used with MyExtension extension, which
- defines a swig_include attribute.
- """
- build_ext.user_options.append(('swig-include=','S',
- "list of directories for swig to search in" +
- "for header files"))
-
- def initialize_options (self):
- build_ext.initialize_options(self)
- self.swig_include = None
-
- def finalize_options (self):
- build_ext.finalize_options(self)
- if self.swig_include!=None:
- self.swig_include=self.swig_include.split(":")
-
- def build_extension(self, ext):
- # command-line arguments prevail over extension arguments
- # but if no command-line argument is defined, extension argument is
- # taken into account
- if self.swig_include==None:self.swig_include=ext.swig_include
- if self.swig_cpp==None:self.swig_cpp=ext.swig_cpp
-
- build_ext.build_extension(self,ext)
-
- def swig_sources (self, sources):
-
- """Walk the list of source files in 'sources', looking for SWIG
- interface (.i) files. Run SWIG on all that are found, and
- return a modified 'sources' list with SWIG source files replaced
- by the generated C (or C++) files.
- """
-
- new_sources = []
- swig_sources = []
- swig_targets = {}
-
- # XXX this drops generated C/C++ files into the source tree, which
- # is fine for developers who want to distribute the generated
- # source -- but there should be an option to put SWIG output in
- # the temp dir.
-
- ## Modified lines (compared to buil_exts.wig_sources original method)
- if self.swig_cpp:
- target_ext = '_wrap.cpp'
- else:
- target_ext = '_wrap.c'
- ## End of modification
-
- for source in sources:
- (base, ext) = os.path.splitext(source)
- if ext == ".i": # SWIG interface file
- new_sources.append(base + target_ext)
- swig_sources.append(source)
- swig_targets[source] = new_sources[-1]
- elif ext == ".h":
- continue
- else:
- new_sources.append(source)
-
- if not swig_sources:
- return new_sources
-
- swig = self.find_swig()
-
- ## Modified lines (compared to buil_exts.wig_sources original method)
- swig_cmd = [swig, "-python"]
- if self.swig_cpp:
- swig_cmd.append("-c++")
-
- if self.swig_include:
- for pth in self.swig_include:
- swig_cmd.append("-I%s"%pth)
- ## End of modification
-
- for source in swig_sources:
- target = swig_targets[source]
- self.announce("swigging %s to %s" % (source, target))
- self.spawn(swig_cmd + ["-o", target, source])
- ## Modified lines (compared to buil_exts.wig_sources original method)
- # When swig generated some shadow classes, place them under
- # self.build_lib (the build directory for Python source).
- if self.swig_cpp:
- # Generate the full pathname of the shadow classes file
- import string
- swig_shadow = string.split(os.path.basename(source), ".")[0]
- swig_shadow = swig_shadow + '.py'
- # On win32 swig places the shadow classes in the directory
- # where it was invoked. This is to be opposed to posix where
- # swig places the shadow classes aside the C++ wrapping code
- # (the target in our context).
- if(os.name=='posix'):
- infile = os.path.join(os.path.dirname(source), swig_shadow)
- else:
- infile = swig_shadow
- if os.path.isfile(infile):
- outfile = [self.build_lib, self.distribution.get_name()]
- outfile.append(swig_shadow)
- outfile = apply(os.path.join, outfile)
- self.copy_file(infile, outfile, preserve_mode=0)
- else:
- self.announce("Warning: swig shadow classes not copied")
- ## End of modification
-
- return new_sources
-
-class MyExtension(Extension):
- """
- This class extends basic distutils Extension class, adding two keyword
- arguments :
- * swig_cpp, which triggers -c++ mode when swigging
- * swig_include, which specifies -I flag when swigging
- This class is meant to be build with mybuild_ext distutils command.
- """
- def __init__(self,swig_include=None,swig_cpp=None,**args):
- Extension.__init__(self,**args)
-
- assert ((swig_include==None or type(swig_include) is ListType),
- "swig_include must be a list of strings")
-
- self.swig_include = swig_include or []
- self.swig_cpp = swig_cpp
-
-"""
-Example of use of these classes in distutils setup method :
-
-from Transfert.tcDistUtils import mybuild_ext,MyExtension
-setup(name="xxx",
- version="X.Y",
- description="blah blah blah",
- author="John Doe",
- author_email="i.hate@spam.com",
- url="http://www.fakeurl.com",
- packages=["yyy"],
- cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext
- ext_modules=[MyExtension(name="src/xxx, # instance of our Extension class
- sources=["src/xxx.cpp",
- "src/xxx.i"],
- include_dirs=["/usr/include/python2.1",
- "/usr/include/vtk"],
- libraries=["vtkGraphics"],
- swig_cpp=1, # C++ support
- swig_include=["src"] # SWIG include dirs
- )
- ]
- )
-
-and then run "python setup.py build"...
-"""
--- /dev/null
+from distutils.command.build_ext import build_ext
+from distutils.core import Extension
+from types import ListType
+import os
+
+class build_extWrap(build_ext):
+ """
+ This distutils command is meant to be used with all wrapper defined for
+ this format.
+ To realize it,we can't have command-line parameters
+ """
+ def build_extension(self,ext):
+ # command-line arguments prevail over extension arguments
+ # but if no command-line argument is defined,extension argument is
+ # taken into account
+ self.__ext=ext
+ build_ext.build_extension(self,ext)
+
+ def swig_sources(self,sources):
+ """Walk the list of source files in 'sources',looking for SWIG
+ interface(.i) files. Run SWIG on all that are found,and
+ return a modified 'sources' list with SWIG source files replaced
+ by the generated C(or C++) files.
+ """
+ try:
+ return(self.__ext.wrapper.WrapSources(self,self.__ext,sources))
+ except Exception,e:
+ print Exception,e
+ self.announce("Warning: wrapping error")
+ return(sources)
+
+class Wrapper:
+ def WrapSources(self,distutil,extWrap,sources):
+ pass
+
+class ExtensionWrap(Extension):
+ """
+ This class extends basic distutils Extension class,adding two keyword
+ arguments :
+ * swig_cpp,which triggers -c++ mode when swigging
+ * swig_include,which specifies -I flag when swigging
+ This class is meant to be build with mybuild_ext distutils command.
+ """
+ def __init__(self,wrapper=None,**args):
+ Extension.__init__(self,**args)
+
+ self.wrapper=wrapper
+
+"""
+Example of use of these classes in distutils setup method :
+
+from Transfert.tcDistUtils import mybuild_ext,MyExtension
+setup(name="xxx",
+ version="X.Y",
+ description="blah blah blah",
+ author="John Doe",
+ author_email="i.hate@spam.com",
+ url="http://www.fakeurl.com",
+ packages=["yyy"],
+ cmdclass={'build_ext':build_extWrap},# redirects default build_ext
+ ext_modules=[ExtensionWrap(name="src/xxx,# instance of our Extension class
+ sources=["src/xxx.cpp",
+ "src/xxx.i"],
+ include_dirs=["/usr/include/python2.1",
+ "/usr/include/vtk"],
+ libraries=["vtkGraphics"],
+ )
+ ]
+ )
+
+and then run "python setup.py build"...
+"""
from distutils.core import setup
import glob, os, sys, shutil
-from distutilsSwigCPlusPlus import *
+from distutilsWrapping import *
+from WrapSwig import *
+from WrapVTK import *
ThisModule='gdcmPython'
gdcmPythonSrcDir=ThisModule
gdcmSrcDir ="src"
+gdcmvtkSrcDir ="vtk"
gdcmDictsDir ="Dicts"
gdcmTestDir ="Test"
# Due to a disutil oddity on Unices : see
# http://aspn.activestate.com/ASPN/Mail/Message/distutils-sig/588325
if(os.name=='posix'):
- targetDir=os.path.join('lib','python'+sys.version[:3],'site-packages')
- libraries=["stdc++"]
- macros =[('__STDC_LIMIT_MACROS', '1')]
+ targetDir=os.path.join('lib','python'+sys.version[:3],'site-packages')
+ libraries=["stdc++"]
+ macros =[('__STDC_LIMIT_MACROS', '1')]
+
+ VTK_PATH="/usr"
+ vtkWrapper="vtkWrapPython"
else:
- targetDir=os.path.join('lib','site-packages')
- libraries=["WSOCK32"]
- macros =[]
+ targetDir=os.path.join('lib','site-packages')
+ libraries=["WSOCK32"]
+ macros =[]
+
+ try:
+ VTK_PATH=os.environ['VTK_PATH']
+ except KeyError,e:
+ err=str(e)
+ print "Environment variable",err[err.rfind(':')+1:],'not defined, '\
+ 'please fix it!'
+ VTK_PATH="c:\\Creatis\\vtkDistrib"
+ vtkWrapper=os.path.join(VTK_PATH,"bin","vtkWrapPython")
targetDir=os.path.join(targetDir, ThisModule)
+# For the Swig compilation
Sources = []
Sources.extend(glob.glob(os.path.join(gdcmSrcDir,"*.cxx")))
Sources.extend(glob.glob(os.path.join(gdcmSrcDir,"*.h")))
Sources.append(os.path.join(gdcmPythonSrcDir,"gdcm.i"))
+# For the VTK compilation
+VTK_INCLUDE_DIR=os.path.join(VTK_PATH,"include","vtk")
+VTK_LIB_DIR=os.path.join(VTK_PATH,"lib","vtk")
+
+vtkSources = []
+vtkSources.extend(glob.glob(os.path.join(gdcmvtkSrcDir,"vtk*.cxx")))
+vtkSources.extend(glob.glob(os.path.join(gdcmSrcDir,"*.cxx")))
+# vtkSources.extend(glob.glob(os.path.join(gdcmvtkSrcDir,"vtk*.h")))
+
+vtkLibraries=["vtkCommon","vtkCommonPython",
+ "vtkIO","vtkIOPython",
+ "vtkFiltering","vtkFilteringPython"]
+
setup(name=ThisModule,
- version="0.1",
+ version="0.2",
description="...",
author="frog",
author_email="frog@creatis.insa-lyon.fr",
url="http://www.creatis.insa-lyon.fr/",
packages=[ gdcmPythonSrcDir,
gdcmPythonSrcDir + '.demo' ],
- cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext
- ext_modules=[MyExtension(
- name='_gdcm',
- sources=Sources,
- include_dirs=[gdcmSrcDir],
- libraries=libraries,
- define_macros=macros,
- swig_cpp=1,
- swig_include=[ gdcmSrcDir] ) ],
+ cmdclass={'build_ext':build_extWrap}, # redirects default build_ext
+ ext_modules=[SwigExtension(name='_gdcm',
+ sources=Sources,
+ include_dirs=[gdcmSrcDir],
+ libraries=libraries,
+ define_macros=macros,
+ swig_cpp=1,
+ swig_include=[gdcmSrcDir]
+ ),
+ VTKExtension(name='gdcmPython.vtkgdcmPython',
+ sources=vtkSources,
+ include_dirs=[gdcmSrcDir,gdcmvtkSrcDir,VTK_INCLUDE_DIR],
+ libraries=libraries+vtkLibraries,
+ define_macros=macros,
+ library_dirs=[VTK_LIB_DIR],
+ vtkWrapper=vtkWrapper,
+ ),
+ ],
data_files=[(os.path.join(targetDir,gdcmTestDir),
glob.glob(os.path.join(gdcmTestDir,"*.acr"))),
(os.path.join(targetDir,"Dicts"),