]> Creatis software - gdcm.git/commitdiff
* Modification of setup.py to compile vtk part too. Then, we have 2
authorregrain <regrain>
Thu, 22 May 2003 10:44:30 +0000 (10:44 +0000)
committerregrain <regrain>
Thu, 22 May 2003 10:44:30 +0000 (10:44 +0000)
        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
      -- BeNours

ChangeLog
MANIFEST.in
WrapSwig.py [new file with mode: 0644]
WrapVTK.py [new file with mode: 0644]
distutilsSwigCPlusPlus.py [deleted file]
distutilsWrapping.py [new file with mode: 0644]
setup.py

index a7f655fe5cb91240f0b5d39edf5b99febb5404c2..eae0cf63fa97389485285716628b8dc4f1023d18 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,17 @@
-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
index 0d9954129c88ef97434df66d08cfbe4ca2b66ac1..9865aca3404801630a5b92b469a48a320327ce52 100644 (file)
@@ -1,4 +1,5 @@
-include distutilsSwigCPlusPlus.py
+include *.py
 recursive-include src *.h
+recursive-include vtk *.h
 recursive-include Dicts *.dic
 recursive-include Data *.*
diff --git a/WrapSwig.py b/WrapSwig.py
new file mode 100644 (file)
index 0000000..f8e02f9
--- /dev/null
@@ -0,0 +1,106 @@
+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
+
diff --git a/WrapVTK.py b/WrapVTK.py
new file mode 100644 (file)
index 0000000..49772bc
--- /dev/null
@@ -0,0 +1,125 @@
+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
+
diff --git a/distutilsSwigCPlusPlus.py b/distutilsSwigCPlusPlus.py
deleted file mode 100644 (file)
index d4e8e40..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-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"...
-"""
diff --git a/distutilsWrapping.py b/distutilsWrapping.py
new file mode 100644 (file)
index 0000000..96152a9
--- /dev/null
@@ -0,0 +1,72 @@
+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"...
+"""
index d36e0517cfcc024ca99b88aea0cdfc3514a90992..b1f59235ab8dcdbdcb6ef49f385743db015f988b 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -1,48 +1,86 @@
 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"),