How to install VTK-9.1 on Ubuntu 18.04

Lynn
11 min readJul 10, 2022

--

This article describes the complete process of configuring, building, installing and uninstalling VTK-9.1 on Ubuntu 18.04.

Photo by Martin Adams on Unsplash

1. Prerequisites

Make sure we have the tools needed to build VTK. Run

$ sudo apt install build-essential cmake mesa-common-dev mesa-utils freeglut3-dev python3-dev python3-venv git-core ninja-build

The command above refers to the VTK brief installation documentation, which is comprehensive, but not specific. For me, since I have already installed some packages in advance, I only installed ninja-build, mesa-utils, doxygen, graphviz* and Qt5 additionaly. Use apt policy <packageName> to check installation.

For the update or installation of cmake, ccmake and Qt5, refer to articles below.

2. Configure VTK with CMake

Here we create the folder structure, get the VTK source and build it.

Go to the official website of VTK, and download the latest version (9.1.0 for this time). Here you can see the following list:

Choose the first one (VTK-9.1.0.tar.gz), put it on your desired directory, such as /opt/, and run

$ sudo tar -zxvf VTK-9.1.0.tar.gz -C /opt
$ cd /opt/VTK-9.1.0
$ sudo mkdir VTK-build
$ cd VTK-build
$ ccmake ..

And now, some entries will appear. Type c to configure, and CMake will then process the configuration files and if necessary display new options on top (for example, if you turn VTK_WRAP_PYTHON on, you will be presented with options for the location of Python executable, libraries and include paths). After re-configuration, type c again and continue this process until there are no new options. Then, you can press g to have CMake generate new makefiles and exit.

If you need to change build options in the future, simply re-run ccmake and follow the instructions above.

Here is my options, just for reference:

For variables which use the module system’s build settings, the valid values are as follows:

  • YES: Require the module to be built.
  • WANT: Build the module if possible.
  • DEFAULT: Use the settings by the module’s groups and VTK_BUILD_ALL_MODULES.
  • DONT_WANT: Don’t build the module unless required as a dependency.
  • NO: Do not build the module.

If you get some errors like:

(1) No CMAKE_CUDA_COMPILER could be found:

CMake Error at CMakeLists.txt:7 (project):
No CMAKE_CUDA_COMPILER could be found.
Tell CMake where to find the compiler by setting either the environment
variable "CUDACXX" or the CMake cache entry CMAKE_CUDA_COMPILER to the full
path to the compiler, or to the compiler name if it is in the PATH.

Put CUDACXX=/usr/local/cuda/bin/nvcc into /etc/environment so that it is applied when using sudo. Notice that this variable can’t be put into ~/.bashrc, and the reason can be seen in the supplements part of this article.

(2) Can’t find the OPENGL_GLES2_INCLUDE_DIR and OPENGL_GLES3_INCLUDE_DIR:

Just run

$ sudo apt policy libgles2-mesa-dev

And then, you’ll find the GLES2 and GLES3 directories in the /usr/include.

Notice, although the package only contains the name of gles2, but it also contains the contents of gles3 actually.

(3)Can’t find Doxygen files (This problem actually occurs during installation)

This problem only occurs when you set BUILD_DOCUMENTATION=ON in the CMake configuration.

First, install graphviz

sudo apt install graphviz*

Then, since we have already ran a command like make -j$(nproc), now we only need to build the Doxygen separately.

Change your directory to /opt/VTK-9.1.0/VTK-build, and run

make DoxygenDoc

The resulting documentation will be in

/opt/VTK-9.1.0/VTK-build/Utilities/Doxygen/doc/html

Or if you want to build from scratch, just run

$ sudo make uninstall
$ sudo make clean

Type make clean at the command line can allow you to get rid of your object and executable files. Sometimes the compiler will link or compile files incorrectly and the only way to get a fresh start is to remove all the object and executable files.

Then run as before

$ sudo make -j$(nproc)
$ sudo make install

3. Build VTK

Run

$ cd /opt/VTK-9.1.0/VTK-build
$ make -j$(nproc)

4. Install VTK

Run

$ cd /opt/VTK-9.1.0/VTK-build
$ sudo make install

Comprehensively summarize the above two steps. When you do something like “make all”, the make program executes a rule named “all” from a file in current directory named “Makefile”. This rule usually calls the compiler to compile some source code into binaries.

When you do “make install”, the make program takes the binaries from the previous step and copies them into some appropriate locations so that they can be accessed. In short, “make install” just copies compiled files into appropriate locations, which is /usr/local/ by default.

It is far easier for locally built software to live in one place and distribution-provided software to live in the “main directories”: /usr/bin/, and so on. (Packagers are very careful to never touch files in /usr/local/ -- they know it is exclusively for system administrators.)

To test the installation, run the following CylinderExample.py:

#!/usr/bin/env python3# This simple example shows how to do basic rendering and pipeline
# creation.
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersSources import vtkCylinderSource
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
def main():
colors = vtkNamedColors()
# Set the background color.
bkg = map(lambda x: x / 255.0, [26, 51, 102, 255])
colors.SetColor("BkgColor", *bkg)
# This creates a polygonal cylinder model with eight circumferential
# facets.
cylinder = vtkCylinderSource()
cylinder.SetResolution(8)
# The mapper is responsible for pushing the geometry into the graphics
# library. It may also do color mapping, if scalars or other
# attributes are defined.
cylinderMapper = vtkPolyDataMapper()
cylinderMapper.SetInputConnection(cylinder.GetOutputPort())
# The actor is a grouping mechanism: besides the geometry (mapper), it
# also has a property, transformation matrix, and/or texture map.
# Here we set its color and rotate it -22.5 degrees.
cylinderActor = vtkActor()
cylinderActor.SetMapper(cylinderMapper)
cylinderActor.GetProperty().SetColor(colors.GetColor3d("Tomato"))
cylinderActor.RotateX(30.0)
cylinderActor.RotateY(-45.0)
# Create the graphics structure. The renderer renders into the render
# window. The render window interactor captures mouse events and will
# perform appropriate camera or actor manipulation depending on the
# nature of the events.
ren = vtkRenderer()
renWin = vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# Add the actors to the renderer, set the background and size
ren.AddActor(cylinderActor)
ren.SetBackground(colors.GetColor3d("BkgColor"))
renWin.SetSize(300, 300)
renWin.SetWindowName('CylinderExample')
# This allows the interactor to initalize itself. It has to be
# called before an event loop.
iren.Initialize()
# We'll zoom in a little by accessing the camera and invoking a "Zoom"
# method on it.
ren.ResetCamera()
ren.GetActiveCamera().Zoom(1.5)
renWin.Render()
# Start the event loop.
iren.Start()
if __name__ == '__main__':
main()

Input these in your command line:

$ python3 CylinderExample.py

or

$ vtkpython CylinderExample.py

Under normal circumstances, both of these will get a Cylinder like:

Notice. If only vtkpython can run this .py file correctly, and get a ModuleNotFoundError: No module named ‘vtkmodules’ error when use python3, the problem may be that the location of shared libraries is not configured correctly.

The system always maps a shared library name to the location of the corresponding shared library file defined in /etc/ld.so.conf.d/*.conf.

The output of cat /etc/ld.so.conf.d/* will show you all the locations defined there. For me, it’s like:

/usr/local/cuda-11.3/targets/x86_64-linux/lib
/usr/lib/x86_64-linux-gnu/libfakeroot
# Multiarch support
/usr/local/lib/i386-linux-gnu
/lib/i386-linux-gnu
/usr/lib/i386-linux-gnu
/usr/local/lib/i686-linux-gnu
/lib/i686-linux-gnu
/usr/lib/i686-linux-gnu
# libc default configuration
/usr/local/lib
/usr/local/opencv4/lib
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

More specifically, the directories of shared libraries python will look for is defined in sys.path. To check or manipulate them, just run:

import sysprint ('\n'.join(sys.path))

In this case, the output of python3 and vtkpython shows that the loss of vtkmodules is caused by the lack of /usr/local/lib/python3.6/site-packages in the sys.path of python3.

Thus, to ensure the correct operation of codes, remember to specify the python interpreter as vtkpython, or just add /usr/local/lib/python3.6/site-packages in the sys.path of python3, like

import sys
sys.path.append ("/usr/local/lib/python3.6/site-packages")

And use the following command to remove it:

import sys
sys.path.remove('/usr/local/lib/python3.6/site-packages')

Or you also can set the PYTHONPATY settings to include /usr/local/lib/python3.6/site-packages.

For more details, refer to this article:

5. Uninstall VTK

When you want to uninstall the VTK, all you have to do is go back here and run

$ sudo make uninstall

This command will automatically remove all the files you copied in the /usr/local/ by default. But this will work only if the developer of the package has taken care of making a good uninstall rule.

If they didn’t, there is also other ways to uninstall packages build from source files manually.

The first one is checkinstall.

checkinstall is a program that monitors an installation procedure (such as make install, install.sh), and creates a standard package for your distribution (currently deb, rpm and tgz packages are supported) that you can install through your distribution’s package management system (dpkg, rpm or installpkg).

If you have already run make install, you can still use checkinstall. Normally checkinstall will overwrite everything that make install created. After that just use dpkg -r <package.deb>, and everything should be removed.

Just run

$ sudo checkinstall

A *.deb package will be created in the directory, and also installed to /usr/local/bin/, unless use --install=no which will only create a deb package without installation.

By default, apt stores the .deb files in /var/cacke/apt/archive/. If you can’t find some packages there, you may have run a clean-up command like sudo apt clean to clear up the .deb files.

To search all .deb files in your system by doing the following:

$ sudo updatedb

This will update lacate’s database to search for newly created/removed files.

$ locate *.deb

which will search your / folder recursively for all files ending with .deb.

For more details of using checkinstall, go to the Community Help Wiki.

5. Some supplements:

(1) Discrimination of Mesa and OpenGL

OPENGL_GLES2_INCLUDE_DIR / OPENGL_GLES3_INCLUDE_DIR: These two entries refer to different versions of OPENGL ES libraries.

OpenGL (Open Graphics Library) is a cross-language, cross-platform application programming interface (API) for rendering 2D and 3D vector graphics.The API is typically used to interact with a graphics processing unit (GPU), to achieve hardware-accelerated rendering.

OpenGL for Embedded systems (OpenGL ES or GLES) is a subset of the OpenGL computer graphics rendering application programming interface (API) for rendering 2D and 3D computer graphics such as those used by video games, typically hardware-accelerated using a graphics processing unit (GPU). It is designed for embedded systems like smartphones, tablet computers, video game consoles and PDAs.

The difference between Mesa and OpenGL is that Mesa provides the client side OpenGL interface for the open source GPU drivers based on the DRI2/DRM architecture. Or in other words: It’s also a part of a driver.

If you’ve got the proprietary drivers from NVidia or AMD installed you don’t need Mesa. If you want to use the open source drivers (nouveau, radeon, radeonhd, intel) you need Mesa.

Mesa, also called Mesa3D and The Mesa 3D Graphics Library, is an open-source software implementation of OpenGL, Vulkan, and other graphics API specifications. Mesa translates these specifications to vendor-specific graphics hardware drivers.

Its most important users are two graphics drivers mostly developed and funded by intel and AMD for their respective hardware (AMD promotes their Mesa drivers Radeon and RadeonSI over the deprecated AMD Catalyst, and Intel has only supported the Mesa driver). Proprietary graphics drivers (e.g., Nvidia GeForce driver and Catalyst) replace all of Mesa, providing their own implementation of a graphics API. An open-source effort to write a Mesa Nvidia driver called Nouveau is mostly developed by the community.

The LinuxQuestions.org forum also provided a good explanation for the difference between Mesa and OpenGL:

OpenGL and Mesa aren’t really two separate choices, but rather Mesa is a specific type of OpenGL.

OpenGL is simply an interface that defines a standard set of functions needed for drawing 3d graphics. It doesn’t involve the actual code that makes these functions happen, it only specifies what the functions are called and what they are supposed to do.

An openGL implementation provides the actual code that runs the methods specified by the OpenGL standard. Without an implementation installed, you cannot run any opengl programs.

Mesa is just one of many OpenGL implementations, and is the most standard one included in linux distributions. It does all the work in software, which is why it is slow.

When you install Nvidia or ATI drivers for a fancy graphics card, these drivers provide a new OpenGL implementation that runs on the graphics card. This implementation would take the place of the Mesa implementation, but it is still an openGL implementation. That is, all of Mesa/ATI/NVidia drivers implement the same set of functions, they just do it in different ways, and they are all openGL.

(2) The role of NVCC

Nvidia CUDA Compiler (NVCC) is a proprietary compiler by Nvidia intended for use with CUDA.

CUDA code runs on both the CPU and GPU. NVCC separates these two parts and sends host code (the part of code which will be run on the CPU) to a C compiler like GCC or Intel C++ Compiler (ICC) or Microsoft Visual C++ Compiler, and sends the device code (the part which will run on the GPU) to the GPU. The device code is further compiled by NVCC.

Any source file containing CUDA language extensions (.cu) must be compiled with nvcc. NVCC is a compiler driver which works by invoking all the necessary tools and compilers like cudacc, g++, cl, etc.

An executable with CUDA code requires: the CUDA core library (cuda) and the CUDA runtime library (cudart).

(3) The relationship between .banshrc and sudo

.bashrc is a configuration file of bash, only when it’s executed interactively. It’s only loaded when you start bash, not when you run some other program such as sh or ccmake(not even if bash is invoked via the name sh). And it’s only loaded when bash is interactive, not when it’s executing a script or a command with -c.

In a word, .bashrc would only run if you launched a child shell. Normally, when you run a program with sudo, there is no need to launch a shell, and therefore .bashrc does not get read/executed.

6. Reference

--

--