VTK/Build System Migration

From KitwarePublic
Revision as of 21:48, 10 September 2012 by Marcus.hanwell (Talk | contribs)

Jump to: navigation, search

The CMake based build system was rewritten for VTK 6, using a modular approach creating smaller libraries with less inter-library dependencies. This means that you will need to port your VTK based application's build system to work with the new library layout. The libraries are arranged in two levels, the top-level resembles the granularity of the kits in VTK 5.x, while the second level provides a greater degree of granularity.

Many classes that were in vtkCommon are now in vtkCommonCore, with some moving out to vtkCommonSystem and other modules. Moving between the class location to the library name is quite simple, all classes in Common/Core/ will be in the vtkCommonCore library for example, and the vtkRenderingOpenGL library's classes can be found in Rendering/OpenGL. Some modules such as vtkRenderingCore provide the interface classes, but require a concrete implementation module to do anything useful (such as vtkRenderingOpenGL). The implementation modules use the vtkObjectFactory to override the base classes with platform specific classes.

Building Against VTK 6

If you are building against VTK 6.0 a few things have changed as a result of the modularization and updates to the CMake infrastructure.

Finding and Linking to VTK

If you just want to find VTK and link to everything that was built not too much has changed. A simple CMakeLists.txt to accomplish this and build an application would be:

find_package(VTK 6.0 REQUIRED)
add_executable(myApplication application.cxx)
target_link_libraries(myApplication ${VTK_LIBRARIES})

This will work against a VTK build tree, or an installed VTK tree. It will find all modules built by VTK, and link to all of the C++ libraries produced. Including the VTK_USE_FILE will set up the include directories for the project, and add the appropriate compiler definitions to automatically initialize the object factory overrides. This is a reasonable starting point, but is not normally desired for applications in production. It is quite easy to find and link to only the components required, ensuring that they were built and only linking to the appropriate libraries.

find_package(VTK 6.0 COMPONENTS vtkChartsCore vtkGUISupportQt vtkViewsContext2D)
add_executable(myApplication application.cxx)
target_link_libraries(myApplication ${VTK_LIBRARIES})

The above snippet will find the vtkChartsCore, vtkGUISupportQt and vtkViewsContext2D, along with all of their dependencies. It will only add their include directories (along with their dependencies), and the appropriate compiler definitions to initialize the object factories. This is probably the most appropriate way to find and link to VTK 6 in the majority of projects.

It is possible to manually specify the libraries to be linked to, avoiding the directory scope compiler definitions and include directories, as all of the appropriate settings are loaded into CMake variables.

find_package(VTK 6.0 COMPONENTS vtkChartsCore vtkGUISupportQt vtkViewsContext2D)
include_directories(SYSTEM ${VTK_INCLUDE_DIRS})
add_executable(myApplication application.cxx)
target_link_libraries(myApplication vtkChartsCore vtkGUISupportQt vtkViewsContext2D)

The VTK libraries are exported by CMake, and so can be referred to as any normal target. The correct library will be linked to for debug/release, along with any required interface libraries. The find_package(VTK) command is safe to call multiple times in the same project, and allows different components to be selected in different applications or libraries in the same project.

Implementation Modules

Most of the rendering in VTK is done with OpenGL, and platform specific interactor/window classes are needed. In VTK this is accomplished using a combination of interface classes written in a platform independent fashion, that are then overridden at runtime using the vtkObjectFactory mechanism. The classes in vtkRenderingCore are normally used in application code, such as vtkRenderWindow, but a platform specific one will be returned by the classes New method. The pure interface classes will return a null pointer from their New method if no valid override was in place.

The application code such list vtkRenderingOpenGL in its components to use OpenGL for rendering, including the VTK_USE_FILE will add compiler definitions to ensure the object factory for the vtkRenderingOpenGL module will be initialized if any of the classes from vtkRenderingCore are included in your application code. If you notice the interface classes in these modules returning NULL pointers it is likely that one of these implementation modules providing appropriate overrides is missing from the dependency list.

Other modules, such as the SQL modules, add new functionality if they are linked to such as the ability to link to MySQL databases. They use alternative APIs to register additional database drivers at link time, but the same compiler definition mechanism to ensure that they are initialized upon application startup.