VTK/Module Development
A new modular build system was developed for VTK 6.0, which makes it much simpler to add new modules to VTK and to express the dependencies between modules and other libraries. Before VTK 6 there were kits arranged in one directory level, such as Common, Charts, Rendering, Filtering, etc, in VTK 6 due to the growth of the toolkit the decision was taken to arrange modules in two levels. The top level can only be one word, camel-cased, and acts to organize modules into high level themes such as Common, Rendering, Filters, etc. The second level contains the actual classes, along with the relevant CMake code.
In order to facilitate a more dynamic toolkit, where source can be added or removed a more loosely coupled system was developed inspired by ITK and the Boost CMake build systems. VTK is configured in two passes, the first pass globs all directories two levels deep for a file called module.cmake. This file must be present for the module to be evaluated. Once found each of the module.cmake files is included by CMake calling the vtk_module macro and evaluating the module dependencies. Once all modules have been evaluated their dependencies are used to determine a valid order for the modules to be added dynamically at configure time.
module.cmake
The typical module.cmake file must declare the module name. Beyond the module name all other parameters are considered optional. A typical module.cmake for vtkCommonDataModel is shown below,
<source lang="cmake"> vtk_module(vtkCommonDataModel
DEPENDS vtkCommonSystem vtkCommonMath vtkCommonMisc vtkCommonTransforms TEST_DEPENDS vtkTestingCore vtkCommonExecutionModel vtkIOGeometry vtkRenderingCore )
</source>
The first argument is the module name, this is the name of the C++ library that will be compiled. Next is the DEPENDS argument which allows the developer to express the module's dependencies. The build system will ensure that each of those libraries is added before this module, and it will take care of linking the C++ library to these dependencies. The TEST_DEPENDS argument adds extra dependencies that the tests require, these will not be linked to the C++ library and by default the testing for the module will only be enabled if these dependencies are being built.
The vtkRenderingOpenGL module introduces a few more optional arguments that can be supplied to the vtk_module macro.
<source lang="cmake"> vtk_module(vtkRenderingOpenGL
GROUPS Rendering IMPLEMENTS vtkRenderingCore DEPENDS # These are likely to be removed soon - split Rendering/OpenGL further. vtkImagingHybrid # For vtkSampleFunction COMPILE_DEPENDS vtkParseOGLExt vtkUtilitiesEncodeString TEST_DEPENDS vtkInteractionStyle vtkTestingRendering vtkIOExport vtkRenderingFreeTypeOpenGL vtkRenderingImage vtkRenderingLOD vtkRenderingLabel vtkImagingGeneral vtkImagingSources vtkFiltersProgrammable vtkRenderingAnnotation )
</source>
The GROUPS parameter adds the module to a higher level group option that can be turned on or off to enable multiple modules. The IMPLEMENTS keyword informs us that the module implements some of the API classes in the vtkRenderingCore module, this means that the object factory override mechanism will be used by this module to override some of the interface classes in that module. COMPILE_DEPENDS informs us that this module needs the vtkParseOGLExt and vtkUtilitiesEncodeString modules to be available at build time, but that we do not want to link to them (although we could do so manually).
Parameters
Possible arguments to vtk_module include the following that affect dependencies of the library:
- DEPENDS - direct dependencies of the module, will be linked and in public interface libraries
- COMPILE_DEPENDS - dependencies required at compile time
- TEST_DEPENDS - test dependencies (in addition to other dependencies)
- IMPLEMENTS - indicate module IMPLEMENTS supplied module, and depends/links to library
Library naming is affected by the first argument to vtk_module (that sets the module name, used by other modules). If a module name has any numbers an alternative must be supplied because Tcl cannot handle module names with anything other than alphabetic characters:
- TCL_NAME - alternative name without numeric components for Tcl module
There are also a couple of parameters that handle grouping/user visible descriptions:
- GROUPS - one or more groups that the module belongs to
- DESCRIPTION - a free form description of the module to explain to users what the module does
There are some parameters that take no further arguments to control how a module is treated:
- EXCLUDE_FROM_ALL - exclude this module from the build all modules setting
- EXCLUDE_FROM_WRAPPING - do not attempt to wrap the module using VTK's wrapping tools
- EXCLUDE_FROM_WRAP_HIERARCHY - wrap the module, but do not use the wrap hierarchy tool. Use this when files up the include chain are not parseable.
Excluding Classes from Automated Tests
VTK has several automated tests that check for code style, as well as smoke tests ensuring that classes do not segfault when setters/getters are called etc. It is sometimes necessary to exclude some classes or methods from these automated tests. The VTK header tests are one such example, if you wish to exclude a header you must add the following line at the end of the header,
<source lang="cpp">// VTK-HeaderTest-Exclude: vtkVector.h</source>
The file name for the header being excluded is necessary, so this line is the last line in vtkVector.h stating that the header tests should ignore the vtkVector.h header. If this line is pasted into any other header, the name of the header must be substituted.
External modules
If you are using VTK as part of a larger project and wish to add libraries that behave as VTK modules do, there are several ways to accomplish this:
- If you include a copy of the VTK source inside your project, you can simply add new directories with module.cmake and CMakeLists.txt files in them.
- If you would like to keep your modules outside of the VTK source directory you can call
<source lang="cmake">
vtk_add_to_module_search_path($srcdir $builddir)
</source> This is how ParaView currently (as of Sep 14, 2012) extends VTK.
- If you would like to use an externally-built version of VTK, you may use the
vtkExternalModuleMacros.cmake
file included with recent versions of VTK (SHA1 29f4bf18 or newer; Sep 14, 2012). An exampleCMakeLists.txt
file for this approach, which adds a single module in a standalone external project, is below:
<source lang="cmake">
project(Example) cmake_minimum_required(VERSION 2.8) find_package(VTK REQUIRED COMPONENTS vtkFiltersGeometry NO_MODULE) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${VTK_CMAKE_DIR}) include(vtkExternalModuleMacros) include(module.cmake) set(Module_SRCS vtkExample.cxx ) vtk_module_library(vtkExample)
</source>
In addition to this file, the source directory must also have a module.cmake
file as specified above.
Since the first 2 methods include the additional modules as part of the build of VTK, they will automatically perform wrapping if it is turned on. Wrapping modules may require additional work if using the vtkExternalModuleMacros
approach.