ITK/Release 4/Wrapping/BuildProcess

From KitwarePublic
Jump to navigationJump to search

Wrapping build is done in several steps.

Configuration

The configuration is done with with the tool used to build ITK: CMake. All the files cited in this section are located in the ITK/Wrapping/WrapITK directory.

During this step, the template instantiations are generated with a several CMake macros. For each macro call of the template instantiation process, some callback macros specific of each language generator are called to generate the files and the commands needed to build the wrappers. The template instantiation and the code generation are completely separated.

Template instantiation

Everything is done in the `Libraries` directory. The instantiations are separated in two levels:

  • the libraries, which are grouping several modules. Generally, one binary for a target language contains all the instantiations from one library;
  • the modules, inside those libraries. Each module groups several template instantiations. The swig interface generator generates one '.i' file per module.

Even if it is usually a good idea to follow this structure, the generators are not forced to respect this structure. They are free to generate what they wan how they want.

Several macros are available to simplify the template instantiations. They are defined in TypedefMacros.cmake.

WRAP_LIBRARIES and END_WRAP_LIBRARIES

WRAP_LIBRARIES is called before generating any library. The generator should use the call back on this macro if they need to perform some initialization step. END_WRAP_LIBRARIES is called after the last instantiation in the last library is done. The generators should use the callback on this macro to create some extra step — for example to build the tests.

WRAPPER_LIBRARY_GROUPS

WRAPPER_LIBRARY_GROUPS macro specifies tbe order in which the .wrap files in WrapITK/Libraries are picked up for code generation. The order specified is important to generate the code properly.

WRAP_LIBRARY and END_WRAP_LIBRARY

Formely BEGIN_WRAPPER_LIBRARY and WRAPPER_LIBRARY_CREATE_LIBRARY.

INCLUDE_LIBRARY

AUTO_INCLUDE_MODULES

Formely WRAPPER_LIBRARY_CREATE_WRAP_FILES.

INCLUDE_MODULE

Formely INCLUDE_WRAP_CMAKE.

WRAP_MODULE and END_WRAP_MODULE

WRAP_CLASS and END_WRAP_CLASS

Special case: WRAP_NAMED_CLASS

WRAP_NON_TEMPLATE_CLASS

Special case: WRAP_NAMED_NON_TEMPLATE_CLASS

WRAP_INCLUDE

ADD_SIMPLE_TYPEDEF

ADD_ONE_TYPEDEF

WRAP_TEMPLATE

WRAP_IMAGE_FILTER

Several deprecated specializations are available:

  • WRAP_IMAGE_FILTER_ALL_TYPES
  • WRAP_IMAGE_FILTER_SCALAR
  • WRAP_IMAGE_FILTER_VECTOR
  • WRAP_IMAGE_FILTER_USIGN_INT
  • WRAP_IMAGE_FILTER_SIGN_INT
  • WRAP_IMAGE_FILTER_INT
  • WRAP_IMAGE_FILTER_REAL
  • WRAP_IMAGE_FILTER_RGB
  • WRAP_IMAGE_FILTER_RGBA
  • WRAP_IMAGE_FILTER_VECTOR_REAL
  • WRAP_IMAGE_FILTER_COV_VECTOR_REAL
  • WRAP_IMAGE_FILTER_COMPLEX_REAL

WRAP_IMAGE_FILTER_COMBINATIONS

FILTER_DIMS

Code generation

  • Everything is done in the 'Languages' directory.

Installation

The following major macros control the installation of files with WrapITK. A certain usage of these macros in the Wrapping/WrapITK/CMakeLists.txt and the CMakeLists.txt for each language allow the generated files (& modules) to be installed in the proper directory(ies).

  • CMAKE_INSTALL_PREFIX
    • This macro specifies the root ITK installation directory and by default points to /usr/local/.
  • WRAP_ITK_INSTALL_PREFIX
    • This macro specifies a subpath where where most of WrapITK files will be installed.
    • It is set in the file Wrapping/WrapITK/CMakeLists.txt to one of lib/cmake/ITK-4.0/WrapITK(default) or lib/InsightToolkit/WrapITK/.
    • This macro in part (along with the WRAP_ITK_INSTALL macro) controls the installation of WrapITK configuration and generated files.

WRAP_ITK_INSTALL

    • This macro is set in Wrapping/WrapITK/ConfigureWrapping.cmake and in adjunct to WRAP_ITK_INSTALL_PREFIX controls the installation of wrapped files (mostly the generated files)
    • This macro will be commonly encountered in the CMakeLists.txt for each language in lines like these: WRAP_ITK_INSTALL("/Configuration/Typedefs/python" "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/python/${group_name}_ext.i")

WRAP_ITK_BINDINGS_INSTALL

    • This new macro is introduced to take care of installation of the generated files specifically
    • With the introduction of this macro, the earlier WRAP_ITK_INSTALL macro will now be installing all the WrapITK configuration files in the directory pointed to by ${CMAKE_INSTALL_PREFIX} and ${WRAP_ITK_INSTALL_PREFIX}, Whereas the new macro will put all the generated proxies(python) and modules(java,python) in the directory ${CMAKE_INSTALL_PREFIX}/lib/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}


Build

Generation XML descriptions of instantiations

Generation of XML documentation

Generation of swig interfaces

Generation of Language specific C++ code

Compilation of C++ code

Linking of libraries

Compilation of tests

Installation

WrapITK installation is composed of installing the following set(s) of files:

  1. cmake files - distributed over various subdirectories of WrapITK
  2. python proxies (.py) files which reside in WrapITK/lib
  3. python modules (.so) which reside in WrapITK/lib
  4. Java modules which reside in WrapITK/lib
  5. Typedefs (.i, .mdx, .includes) files which reside in WrapITK/Configuration/Typedefs
  6. Manually written python files which reside in WrapITK/Python
  7. Language specific (.i, .in) files in WrapITK/Configuration/Languages.

To summarize, WRAP_ITK_BINDINGS_INSTALL macro takes care of installation of 2,3, 4 and 6. Whereas the WRAP_ITK_INSTALL macro takes care of 1, 5 and 7.


External Project

With WrapITK, an external project is a way to extend the wrapping with custom classes outside ITK. The exact same macros are reused, but a single library is generally produced. External projects can be built using ITK from its build tree or from its installed tree.

Example

Here is an example to wrap a new dummy class. All the files are in the same directory.

CMakeLists.txt:

 project(dummy)
 
 cmake_minimum_required(VERSION 2.8)
 
 find_package(ITK REQUIRED)
 find_package(WrapITK REQUIRED)
 
 WRAP_LIBRARY("${PROJECT_NAME}")
   set(WRAPPER_LIBRARY_DEPENDS Base)
   AUTO_INCLUDE_MODULES()
 END_WRAP_LIBRARY()

itkDummy.wrap:

 WRAP_CLASS(itk::Dummy POINTER)
   foreach(t ${WRAP_ITK_SCALAR} ${WRAP_ITK_COLOR} ${WRAP_ITK_COMPLEX_REAL})
     WRAP_TEMPLATE("${ITKM_${t}}" "${ITKT_${t}}")
   endforeach(t)
 END_WRAP_CLASS()

itkDummy.h:

 #ifndef __itkDummy_h
 #define __itkDummy_h
 
 #include "itkProcessObject.h"
 #include "itkImage.h"
 
 namespace itk
 {
 /** \class Dummy
  * \brief a dummy class to return a dummy value
  */
 template< class TValue >
 class ITK_EXPORT Dummy: public Object
 {
 public:
   /** Standard class typedefs. */
   typedef Dummy                      Self;
   typedef Object                     Superclass;
   typedef SmartPointer< Self >       Pointer;
   typedef SmartPointer< const Self > ConstPointer;
 
   /** Method for creation through the object factory. */
   itkNewMacro(Self);
 
   /** Run-time type information (and related methods). */
   itkTypeMacro(Dummy, Object);
 
   TValue GetValue() const
   {
     return NumericTraits<TValue>::OneValue();
   }
  protected:
   Dummy() {};
   virtual ~Dummy() {};
 
 private:
   Dummy(const Self &);    //purposely not implemented
   void operator=(const Self &); //purposely not implemented
 };
 } // end namespace itk
 
 #endif

Then, after building and installing the external project, you can run that code in a python interpreter:

 >>> import itk
 
 >>> df = itk.Dummy.F.New()
 
 >>> df.GetValue()
 1.0
 
 >>> drgb = itk.Dummy.RGBUC.New()
 
 >>> drgb.GetValue()
 itkRGBPixel(1  1  1)