3 VTK 8.2 and older contained a module system which was based on variables and
4 informed CMake's migration to target-based properties and interactions. This
5 was incompatible with the way VTK ended up doing it. With VTK 9, its module
6 system has been reworked to use CMake's targets.
8 This document may be used as a guide to updating code using old VTK modules into
9 code using new VTK modules.
13 If your project is just using VTK's modules and not declaring any of your own
14 modules, porting involves a few changes to the way VTK is found and used.
16 The old module system made variables available for using VTK.
24 include(${VTK_USE_FILE})
26 add_library(usesvtk ...)
27 target_link_libraries(usesvtk ${visibility} ${VTK_LIBRARIES})
28 target_include_directories(usesvtk ${visibility} ${VTK_INCLUDE_DIRS})
30 # Pass any VTK autoinit defines to the target.
31 target_compile_definitions(usesvtk PRIVATE ${VTK_DEFINITIONS})
34 This causes problems if VTK is found multiple times within a source tree with
35 different components. The new pattern is:
39 #9.0 # Compatibility support is not provided if 9.0 is requested.
42 # Old component names are OK, but deprecated.
45 # New names reflect the target names in use.
48 # No longer needed; warns or errors depending on the version requested when
50 #include(${VTK_USE_FILE})
52 add_library(usesvtk ...)
53 # VTK_LIBRARIES is provided for compatibility, but not recommended.
54 #target_link_libraries(usesvtk ${visibility} ${VTK_LIBRARIES})
55 target_link_libraries(usesvtk ${visibility} VTK::CommonCore VTK::RenderingOpenGL2)
57 # Rather than defining a single `VTK_DEFINITIONS` for use by all relevant
58 # targets, the definitions are made as needed with the exact set needed for the
62 #MODULES ${VTK_LIBRARIES} # Again, works, but is not recommended.
63 MODULES VTK::CommonCore VTK::RenderingOpenGL2)
68 The old module system had CMake code declare modules in `module.cmake` files.
69 This allowed logic and other things to happen within them which could cause
70 module dependencies to be hard to follow. The new module system now provides
71 facilities for disabling modules in certain configurations (using `CONDITION`)
72 and for optionally depending on modules (using `OPTIONAL_DEPENDS`).
77 if (SOME_OTHER_OPTION)
78 list(APPEND depends vtkSomeDep)
80 vtk_module(vtkModuleName
82 # groups the module belongs to
84 # the kit the module belongs to
86 # modules containing vtkObjectFactory instances that are implemented here
89 #${depends} # no analogy in the new system
91 # private dependencies
94 # modules which must be built before this one but which are not actually
99 # optional test dependencies
101 #EXCLUDE_FROM_WRAPPING
102 # present for modules which cannot be wrapped
107 This is now replaced with a declarative file named `vtk.module`. This file is
108 not CMake code and is instead parsed as an argument list in CMake (variable
109 expansions are also not allowed). The above example would translate into:
117 # groups the module belongs to
119 # the kit the module belongs to
120 #IMPLEMENTABLE # Implicit in the old build system. Now explicit.
122 # modules containing vtkObjectFactory instances that are implemented here
124 # public dependencies
126 # private dependencies
130 # modules which must be built before this one but which are not actually
134 TEST_OPTIONAL_DEPENDS
135 # optional test dependencies
138 # present for modules which cannot be wrapped
141 Modules may also now be provided by the current project or by an external
142 project found by `find_package` as well.
146 Sources used to be listed just as `.cxx` files. The module system would then
147 search for a corresponding `.h` file, then add it to the list. Some source file
148 properties could be used to control header-only or private headers.
150 In this example, we have a module with the following sources:
152 - `vtkPublicClass.cxx` and `vtkPublicClass.h`: Public VTK class meant to be
153 wrapped and its header installed.
154 - `vtkPrivateClass.cxx` and `vtkPrivateClass.h`: Priavte VTK class not meant
155 for use outside of the module.
156 - `helper.cpp` and `helper.h`: Private API, but not following VTK's naming
158 - `public_helper.cpp` and `public_helper.h`: Public API, but not following
159 VTK's naming conventions.
160 - `vtkImplSource.cxx`: A source file without a header.
161 - `public_header.h`: A public header without a source file.
162 - `template.tcc` and `template.h`: Public API, but not following VTK's naming
164 - `private_template.tcc` and `private_template.h`: Private API, but not
165 following VTK's naming conventions.
166 - `vtkPublicTemplate.txx` and `vtkPublicTemplate.h`: Public template sources.
167 Wrapped and installed.
168 - `vtkPrivateTemplate.txx` and `vtkPrivateTemplate.h`: Private template
170 - `vtkOptional.cxx` and `vtkOptional.h`: Private API which requires an
173 The old module's way of building these sources is:
185 vtkPublicTemplate.txx
186 vtkPrivateTemplate.txx
187 template.tcc # Not detected as a template, so not installed.
193 # Mark some files as only being header files.
194 set_source_files_properties(
199 # Mark some headers as being private.
200 set_source_files_properties(
205 vtkImplSource.cxx # no header
207 PROPERTIES SKIP_HEADER_INSTALL 1
210 set(${vtk-module}_HDRS # Magic variable
213 #helper.h # private headers just go ignored.
216 # Optional dependencies are detected through variables.
217 if (Module_vtkSomeDep)
218 list(APPEND Module_SRCS
219 # Some optional file.
223 vtk_module_library(vtkModuleName ${Module_SRCS})
226 While with the new system, source files are explicitly declared using argument
248 set(private_template_classes
252 set(private_templates
253 private_template.tcc)
255 # Optional dependencies are detected as targets.
256 if (TARGET vtkSomeDep)
257 # Optional classes may not be public (though there's no way to actually
258 # enforce it, optional dependencies are always treated as private.
259 list(APPEND private_classes
263 vtk_module_add_module(vtkModuleName
264 # File pairs which follow VTK's conventions. The headers will be wrapped and
267 # File pairs which follow VTK's conventions, but are not for use outside the
269 PRIVATE_CLASSES ${private_classes}
270 # Standalone sources (those without headers or which do not follow VTK's
273 # Standalone headers (those without sources or which do not follow VTK's
274 # conventions). These will be installed.
275 HEADERS ${public_headers}
276 # Standalone headers (those without sources or which do not follow VTK's
277 # conventions), but are not for use outside the module.
278 PRIVATE_HEADERS ${private_headers}
280 # Templates are also supported.
282 # Template file pairs which follow VTK's conventions. Both files will be
283 # installed (only the headers will be wrapped).
284 TEMPLATE_CLASSES ${template_classes}
285 # Template file pairs which follow VTK's conventions, but are not for use
286 # outside the module.
287 PRIVATE_TEMPLATE_CLASSES ${private_template_classes}
288 # Standalone template files (those without headers or which do not follow
289 # VTK's conventions). These will be installed.
290 TEMPLATES ${templates}
291 # Standalone template files (those without headers or which do not follow
292 # VTK's conventions), but are not for use outside the module.
293 PRIVATE_TEMPLATES ${private_templates}
297 Note that the arguments with `CLASSES` in their name expand to pairs of files
298 with the `.h` and either `.cxx` or `.txx` extension based on whether it is a
299 template or not. Projects not using this convention may use the `HEADERS`,
300 `SOURCES`, and `TEMPLATES` arguments instead.
304 Previously, object factories were made using implicit variable declaration magic
305 behind the scenes. This is no longer the case and proper CMake APIs for them are
310 vtkObjectFactoryImpl.cxx
311 # This path is made by `vtk_object_factory_configure` later.
312 "${CMAKE_CURRENT_BINARY_DIR}/${vtk-module}ObjectFactory.cxx")
314 # Make a list of base classes we will be overriding.
315 set(overrides vtkObjectFactoryBase)
316 # Make a variable declaring what the override for the class is.
317 set(vtk_module_vtkObjectFactoryBase_override "vtkObjectFactoryImpl")
318 # Generate a source using the list of base classes overridden.
319 vtk_object_factory_configure("${overrides}")
321 vtk_module_library("${vtk-module}" "${sources}")
324 This is now handled using proper APIs instead of variable lookups.
328 vtkObjectFactoryImpl)
330 # Explicitly declare the override relationship.
331 vtk_object_factory_declare(
332 BASE vtkObjectFactoryBase
333 OVERRIDE vtkObjectFactoryImpl)
334 # Collects the set of declared overrides and writes out a source file.
335 vtk_object_factory_declare(
336 # The path to the source is returned as a variable.
337 SOURCE_FILE factory_source
338 # As is its header file.
339 HEADER_FILE factory_header
340 # The export macro is now explicitly passed (instead of assumed based on the
341 # current module context).
342 EXPORT_MACRO MODULE_EXPORT)
344 vtk_module_add_module(vtkModuleName
346 SOURCES "${factory_source}"
347 PRIVATE_HEADERS "${factory_header}")
350 ## Building a group of modules
352 This was not well supported in the old module system. Basically, it involved
353 setting up the source tree like VTK expects and then including the
354 `vtkModuleTop` file. This is best just rewritten using the following CMake APIs:
356 - [vtk_module_find_modules]
357 - [vtk_module_find_kits]
361 [vtk_module_find_modules]: @ref vtk_module_find_modules
362 [vtk_module_find_kits]: @ref vtk_module_find_kits
363 [vtk_module_scan]: @ref vtk_module_scan
364 [vtk_module_build]: @ref vtk_module_build