How to handle cmake COMPONENTS name change between 8.2 and 9.

I’ve been using vtk8.2 successfully for a while now, with a basic

find_package(VTK REQUIRED COMPONENTS
  vtkCommonCore
  vtkCommonDataModel
  vtkIOXML)

however, vtk9 changed those component names. How do I know which component names I should ask for without already knowing which version of VTK find_package is going to find? Am I doing this wrong?

(edit: to be clear, I need to support both versions until everyone upgrades to 9)

Look at the CMakeLists.txt file in these Cxx examples, this may help.

Hi Andrew, thanks for the suggestion. The first couple of these just ask for the vtk-prefixed components which no longer exist in vtk9, as described by my post. Is there something else that I am supposed to be seeing?

This approach works with VTK 9.0. For old versions of VTK include(${VTK_USE_FILE}), just pulls in those modules, for VTK 9.0 all modules are pulled in: MODULES ${VTK_LIBRARIES}. Note that QUIET allows CMake to continue if a module doesn’t exist. The list of modules are the VTK 8 ones. Try an example. Alternatively test for each VTK version.

Hi Andrew, thanks for the information. So if I pass QUIET that silences the deprecation warnings that I get, but it’s still deprecated. Is there some modern replacement solution that isn’t deprecated?

CMake Deprecation Warning at /opt/homebrew/lib/cmake/vtk-9.0/vtk-config.cmake:64 (message):
  The new name for the 'vtkRenderingOpenGL2' component is 'RenderingOpenGL2'
Call Stack (most recent call first):
  CMakeLists.txt:5 (find_package)

(edit: grammar)

Yes there is, if you build VTK yourself then, for VTK 9+, there is this Python script FindNeededModules.py. This will look at your code and determine what modules are needed. To do this, it needs modules.json found in your build directory. This is probably the best approach. It does mean that you have two sets of modules, one for VTK 9+ and one for the old version of VTK.

For example, for CylinderExample, running the above Python script will give you:

find_package(VTK
 COMPONENTS
    CommonColor
    CommonCore
    FiltersSources
    RenderingCore
    # These modules are suggested since they implement an existing module.
    # Uncomment those you need.
    # InteractionStyle  # implements VTK::RenderingCore
    # RenderingFreeType # implements VTK::RenderingCore
    # RenderingOpenGL2  # implements VTK::RenderingCore
    # RenderingUI       # implements VTK::RenderingCore
)

I’m sort of lost.

I have never build vtk. Our HPC users don’t build vtk. They get it from dpkg, homebrew, spack, etc. (depending on if they have root or not), or from a system-installed module. I have no control over what version they have installed (I only use its IOXML layer in order to provide vtu/pvd for paraview visualization of simulation results), nor do I plan on building it as a dependency.

If I already knew that I was going to find vtk9 (and thus might be able to track down that python script and add python as a dependency and run some magic cmake code to get it to generate the COMPONENTS in time for find_package) I wouldn’t have this problem because I could just request the proper names to start with.

I think I have a basic misunderstanding of the problem I’m trying to solve. I don’t know the vtk version until I’ve called find_package, but I need the version-dependent COMPONENT names in order to call find_package… classic catch-22.

I guess I’m just going to live with the QUIET flag until it finally breaks and then come back to figuring this out.

How about this (this is untested). CommonCore will be always there so if find_package finds it you have VTK 9+, otherwise test for vtkCommonCore.
This gives you the VTK Version.
Then based on the version re-run find_package.

find_package(VTK  COMPONENTS CommonCore QUIET)
if (NOT VTK_FOUND)
  find_package(VTK  COMPONENTS vtkCommonCore QUIET)
  if (NOT VTK_FOUND)
    message("Skipping ${PROJECT_NAME}: ${VTK_NOT_FOUND_MESSAGE}")
    return ()
  endif()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
if (VTK_VERSION VERSION_LESS "8.90.0")
  # old system
    find_package(VTK COMPONENTS 
      vtkCommonColor
      vtkCommonCore
      vtkCommonDataModel
      vtkFiltersSources
      vtkInteractionStyle
      vtkRenderingContextOpenGL2
      vtkRenderingCore
      vtkRenderingFreeType
      vtkRenderingGL2PSOpenGL2
      vtkRenderingOpenGL2
  )
else()
  # new system
  find_package(VTK COMPONENTS
      CommonColor
      CommonCore
      CommonDataModel
      FiltersSources
      IOImage
      RenderingCore
      # These modules are suggested since they implement an existing module.
      # Uncomment those you need.
      InteractionStyle  # implements VTK::RenderingCore
      # RenderingFreeType # implements VTK::RenderingCore
      RenderingOpenGL2  # implements VTK::RenderingCore
  )
endif()
message(STATUS "VTK Libraries: ${VTK_LIBRARIES}")

I hope this helps. You may have to manually determine what other extra VTK 9 modules are needed.

1 Like

Ah, this helps a lot. I didn’t realize I could effectively call find_package multiple times with different COMPONENTS. Thank you!

Glad to help

The deprecation warning is just saying that the old names aren’t going to be supported forever. If you explicitly declare that you need 8.2+ (or something), it suppresses those as well since you need to use the old names to support the version you’re stating. If you say find_package(VTK 9.0), support for the old names is removed since you are saying you require 9.0 anyways (use of VTK_USE_FILE is also a hard error in this case).

I would recommend using the old names and declaring your minimum version (probably 8.0?). That will allow you to use the old names without warnings or any other complicated queries.

1 Like

Hi Ben,

Your suggestion makes complete sense, thank you.

Our initial support was for VTK6 but I removed a lot of that code once the slow-to-adopt-new-packages cluster moved up to 8. I stopped worrying about the version at that point. Then I independently realized that using the COMPONENTS style find_package meant I wasn’t looking for and linking the entire world. The change in component names threw me for a loop.

Luke