Missing prebuilds for IGT extensions for Preview Release 5.9

Hello, I’m developing slicelet for image guided therapy, particularly a scripted slicelet for simpler R&D. Ideally we’d like to use the Preview Release of Slicer 5.9 that ships with a more recent version of Python 3.12, however, it seems like a number of core IGT extensions are missing as of revision 33856 built 2025-08-19:

Inspecting the Extensions-Nightly build status for IGT extensions of interest:

The build errors for both SlicerIGSIO and SlicerOpenIGTLink are quite nondescript, while cmake error for SlicerIGT from the missing SlicerIGSIO simple enough.

[  2%] Creating directories for 'YASM'
[  5%] Performing download step (git clone) for 'YASM'
Cloning into 'YASM'...
Already on 'master'
Your branch is up to date with 'origin/master'.
gmake[5]: *** read jobs pipe: Bad file descriptor.  Stop.
gmake[5]: *** Waiting for unfinished jobs....
[  8%] Generate version-YASM.txt and license-YASM.txt

Any idea what may be blocking the build server here? Only one test is failing atm:

IGT Extension Test Results:
ruffsl@box ~/w/s/S/inner-build> make test
Running tests...
Test project /home/ruffsl/ws/slicer/SlicerIGSIO-Release/inner-build
    Start 1: vtkEncodeUncompressedSequenceTest
1/3 Test #1: vtkEncodeUncompressedSequenceTest ................   Passed    0.25 sec
    Start 2: qSlicerMetafileImporterModuleGenericTest
2/3 Test #2: qSlicerMetafileImporterModuleGenericTest .........   Passed    2.08 sec
    Start 3: qSlicerMetafileImporterModuleWidgetGenericTest
3/3 Test #3: qSlicerMetafileImporterModuleWidgetGenericTest ...   Passed    2.33 sec

100% tests passed, 0 tests failed out of 3

Label Time Summary:
qSlicerMetafileImporterModule    =   4.42 sec*proc (2 tests)
qSlicerVideoUtilModule           =   0.25 sec*proc (1 test)

Total Test time (real) =   4.67 sec
ruffsl@box ~/w/s/SlicerIGT-Release> make test
Running tests...
Test project /home/ruffsl/ws/slicer/SlicerIGT-Release
      Start  1: qSlicerBreachWarningModuleGenericTest
 1/36 Test  #1: qSlicerBreachWarningModuleGenericTest ..................................   Passed    1.67 sec
      Start  2: qSlicerBreachWarningModuleWidgetGenericTest
 2/36 Test  #2: qSlicerBreachWarningModuleWidgetGenericTest ............................   Passed    1.85 sec
      Start  3: py_BreachWarningSelfTest
 3/36 Test  #3: py_BreachWarningSelfTest ...............................................   Passed    9.96 sec
      Start  4: qSlicerCollectPointsModuleGenericTest
 4/36 Test  #4: qSlicerCollectPointsModuleGenericTest ..................................   Passed    1.56 sec
      Start  5: qSlicerCollectPointsModuleWidgetGenericTest
 5/36 Test  #5: qSlicerCollectPointsModuleWidgetGenericTest ............................   Passed    1.74 sec
      Start  6: qSlicerCreateModelsModuleGenericTest
 6/36 Test  #6: qSlicerCreateModelsModuleGenericTest ...................................   Passed    1.56 sec
      Start  7: qSlicerCreateModelsModuleWidgetGenericTest
 7/36 Test  #7: qSlicerCreateModelsModuleWidgetGenericTest .............................   Passed    1.82 sec
      Start  8: qSlicerFiducialRegistrationWizardModuleGenericTest
 8/36 Test  #8: qSlicerFiducialRegistrationWizardModuleGenericTest .....................   Passed    2.35 sec
      Start  9: qSlicerFiducialRegistrationWizardModuleWidgetGenericTest
 9/36 Test  #9: qSlicerFiducialRegistrationWizardModuleWidgetGenericTest ...............   Passed    2.55 sec
      Start 10: py_nomainwindow_qSlicerFiducialsToModelRegistrationModuleGenericTest
10/36 Test #10: py_nomainwindow_qSlicerFiducialsToModelRegistrationModuleGenericTest ...   Passed    2.43 sec
      Start 11: py_FiducialsToModelRegistration
11/36 Test #11: py_FiducialsToModelRegistration ........................................   Passed    4.24 sec
      Start 12: py_Guidelet
12/36 Test #12: py_Guidelet ............................................................   Passed    3.26 sec
      Start 13: qSlicerLandmarkDetectionModuleGenericTest
13/36 Test #13: qSlicerLandmarkDetectionModuleGenericTest ..............................   Passed    1.66 sec
      Start 14: qSlicerLandmarkDetectionModuleWidgetGenericTest
14/36 Test #14: qSlicerLandmarkDetectionModuleWidgetGenericTest ........................   Passed    1.77 sec
      Start 15: vtkLandmarkDetectionTest
15/36 Test #15: vtkLandmarkDetectionTest ...............................................   Passed    0.28 sec
      Start 16: qSlicerLandmarkDetectionModuleGenericTest
16/36 Test #16: qSlicerLandmarkDetectionModuleGenericTest ..............................   Passed    1.56 sec
      Start 17: qSlicerLandmarkDetectionModuleWidgetGenericTest
17/36 Test #17: qSlicerLandmarkDetectionModuleWidgetGenericTest ........................   Passed    1.79 sec
      Start 18: py_nomainwindow_qSlicerModelRegistrationModuleGenericTest
18/36 Test #18: py_nomainwindow_qSlicerModelRegistrationModuleGenericTest ..............   Passed    2.43 sec
      Start 19: py_ModelRegistration
19/36 Test #19: py_ModelRegistration ...................................................   Passed    4.13 sec
      Start 20: qSlicerPathExplorerModuleGenericTest
20/36 Test #20: qSlicerPathExplorerModuleGenericTest ...................................   Passed    2.49 sec
      Start 21: qSlicerPathExplorerModuleWidgetGenericTest
21/36 Test #21: qSlicerPathExplorerModuleWidgetGenericTest .............................   Passed    2.65 sec
      Start 22: vtkPivotCalibrationTest
22/36 Test #22: vtkPivotCalibrationTest ................................................   Passed    0.29 sec
      Start 23: qSlicerPivotCalibrationModuleGenericTest
23/36 Test #23: qSlicerPivotCalibrationModuleGenericTest ...............................   Passed    1.68 sec
      Start 24: qSlicerPivotCalibrationModuleWidgetGenericTest
24/36 Test #24: qSlicerPivotCalibrationModuleWidgetGenericTest .........................   Passed    1.87 sec
      Start 25: py_nomainwindow_qSlicerTextureModelModuleGenericTest
25/36 Test #25: py_nomainwindow_qSlicerTextureModelModuleGenericTest ...................   Passed    2.41 sec
      Start 26: py_TextureModel
26/36 Test #26: py_TextureModel ........................................................   Passed    9.46 sec
      Start 27: qSlicerTransformProcessorModuleGenericTest
27/36 Test #27: qSlicerTransformProcessorModuleGenericTest .............................   Passed    1.50 sec
      Start 28: qSlicerTransformProcessorModuleWidgetGenericTest
28/36 Test #28: qSlicerTransformProcessorModuleWidgetGenericTest .......................   Passed    1.69 sec
      Start 29: qSlicerUltrasoundSnapshotsModuleGenericTest
29/36 Test #29: qSlicerUltrasoundSnapshotsModuleGenericTest ............................   Passed    1.65 sec
      Start 30: qSlicerUltrasoundSnapshotsModuleWidgetGenericTest
30/36 Test #30: qSlicerUltrasoundSnapshotsModuleWidgetGenericTest ......................   Passed    1.84 sec
      Start 31: py_nomainwindow_qSlicerViewpointModuleGenericTest
31/36 Test #31: py_nomainwindow_qSlicerViewpointModuleGenericTest ......................   Passed    2.51 sec
      Start 32: py_Viewpoint
32/36 Test #32: py_Viewpoint ...........................................................   Passed    3.03 sec
      Start 33: qSlicerWatchdogModuleGenericTest
33/36 Test #33: qSlicerWatchdogModuleGenericTest .......................................   Passed    1.70 sec
      Start 34: qSlicerWatchdogModuleWidgetGenericTest
34/36 Test #34: qSlicerWatchdogModuleWidgetGenericTest .................................   Passed    1.78 sec
      Start 35: py_nomainwindow_qSlicerSequenceReplayModuleGenericTest
35/36 Test #35: py_nomainwindow_qSlicerSequenceReplayModuleGenericTest .................   Passed    2.38 sec
      Start 36: py_SequenceReplay
36/36 Test #36: py_SequenceReplay ......................................................   Passed    3.30 sec

100% tests passed, 0 tests failed out of 36

Label Time Summary:
qSlicerBreachWarningModule                 =   3.53 sec*proc (2 tests)
qSlicerCollectPointsModule                 =   3.31 sec*proc (2 tests)
qSlicerCreateModelsModule                  =   3.38 sec*proc (2 tests)
qSlicerFiducialRegistrationWizardModule    =   4.90 sec*proc (2 tests)
qSlicerLandmarkDetectionModule             =   7.07 sec*proc (5 tests)
qSlicerPathExplorerModule                  =   5.14 sec*proc (2 tests)
qSlicerPivotCalibrationModule              =   3.84 sec*proc (3 tests)
qSlicerTransformProcessorModule            =   3.18 sec*proc (2 tests)
qSlicerUltrasoundSnapshotsModule           =   3.49 sec*proc (2 tests)
qSlicerWatchdogModule                      =   3.48 sec*proc (2 tests)

Total Test time (real) =  90.85 sec
ruffsl@box ~/w/s/S/inner-build> make test
Running tests...
Test project /home/ruffsl/ws/slicer/SlicerOpenIGTLink-Release/inner-build
    Start 1: vtkMRMLConnectorCommandSendAndReceiveTest
1/8 Test #1: vtkMRMLConnectorCommandSendAndReceiveTest .........***Failed   15.28 sec
    Start 2: vtkMRMLConnectorImageSendAndReceiveTest
2/8 Test #2: vtkMRMLConnectorImageSendAndReceiveTest ...........   Passed   10.36 sec
    Start 3: qSlicerOpenIGTLinkRemoteModuleGenericTest
3/8 Test #3: qSlicerOpenIGTLinkRemoteModuleGenericTest .........   Passed    2.09 sec
    Start 4: qSlicerOpenIGTLinkRemoteModuleWidgetGenericTest
4/8 Test #4: qSlicerOpenIGTLinkRemoteModuleWidgetGenericTest ...   Passed    2.32 sec
    Start 5: qSlicerOpenIGTLinkRemoteModuleGenericTest
5/8 Test #5: qSlicerOpenIGTLinkRemoteModuleGenericTest .........   Passed    2.02 sec
    Start 6: qSlicerOpenIGTLinkRemoteModuleWidgetGenericTest
6/8 Test #6: qSlicerOpenIGTLinkRemoteModuleWidgetGenericTest ...   Passed    2.35 sec
    Start 7: qSlicerPlusRemoteModuleGenericTest
7/8 Test #7: qSlicerPlusRemoteModuleGenericTest ................   Passed    2.12 sec
    Start 8: qSlicerPlusRemoteModuleWidgetGenericTest
8/8 Test #8: qSlicerPlusRemoteModuleWidgetGenericTest ..........   Passed    2.32 sec

88% tests passed, 1 tests failed out of 8

Label Time Summary:
SlicerOpenIGTLink                 =  25.64 sec*proc (2 tests)
qSlicerOpenIGTLinkRemoteModule    =   8.77 sec*proc (4 tests)
qSlicerPlusRemoteModule           =   4.44 sec*proc (2 tests)

Total Test time (real) =  38.86 sec

The following tests FAILED:
          1 - vtkMRMLConnectorCommandSendAndReceiveTest (Failed)
Errors while running CTest
Output from these tests are in: /home/ruffsl/ws/slicer/SlicerOpenIGTLink-Release/inner-build/Testing/Temporary/LastTest.log
Use "--rerun-failed --output-on-failure" to re-run the failed cases verbosely.
make: *** [Makefile:91: test] Error 8
ruffsl@box ~/w/s/S/inner-build [2]> make test ARGS="--rerun-failed --output-on-failure"
Running tests...
Test project /home/ruffsl/ws/slicer/SlicerOpenIGTLink-Release/inner-build
    Start 1: vtkMRMLConnectorCommandSendAndReceiveTest
1/1 Test #1: vtkMRMLConnectorCommandSendAndReceiveTest ...***Failed    0.42 sec
SUCCESS: connected to server
error: [/home/ruffsl/ws/slicer/SlicerOpenIGTLink-Release/inner-build/bin/SlicerOpenIGTLinkCxxTests] exit abnormally - Report the problem.


0% tests passed, 1 tests failed out of 1

Label Time Summary:
SlicerOpenIGTLink    =   0.42 sec*proc (1 test)

Total Test time (real) =   0.42 sec

The following tests FAILED:
          1 - vtkMRMLConnectorCommandSendAndReceiveTest (Failed)
Errors while running CTest
make: *** [Makefile:91: test] Error 8

Following the docs, I’ve gone ahead and compiled 3D Slicer from source using Ubuntu 24.04, including the IGT extensions from the HEADs of their respective default branches, as linked above. All seems to build and run fine as show (unsure if SlicerIGSIO is tested here):

Example scene attached, sans the CTChest.nrrd from downloaded sample data:

And synthetic transform publisher for animating the example demo:

"""
============================
Position sending server
============================

Simple application that starts a server that provides a stream of random positions.

from slicer.util import pip_install
pip_install("pyigtl")

Adapted from:
https://github.com/lassoan/pyigtl/blob/d28132d8e9e1cef4ac531d795f5284c8aa739408/examples/example_position_server.py
https://github.com/lassoan/pyigtl/blob/d28132d8e9e1cef4ac531d795f5284c8aa739408/pyigtl/tests/test_basic_comm.py#L87-L93
"""

import pyigtl  # pylint: disable=import-error

from time import sleep
import numpy as np
from scipy.spatial.transform import Rotation as R

server = pyigtl.OpenIGTLinkServer(port=18944)

transverse180 = np.array([
    [-1.0,  0.0,  0.0,  0.0],
    [ 0.0,  1.0,  0.0,  0.0],
    [ 0.0,  0.0, -1.0,  0.0],
    [ 0.0,  0.0,  0.0,  1.0]
])

timestep = 0
while True:
    if not server.is_connected():
        # Wait for client to connect
        sleep(0.1)
        continue

    # Generate periodic trajectory: Lissajous curve on sphere
    timestep += 1
    radius = 50.0
    center = np.array([0.0, 0.0, -100.0])
    # Use two periodic angles for smooth looping
    phi = (timestep * 0.001) % (2 * np.pi)  # azimuthal
    theta = (timestep * 0.002) % (2 * np.pi) # polar
    x = center[0] + radius * np.sin(theta) * np.cos(phi)
    y = center[1] + radius * np.sin(theta) * np.sin(phi)
    z = center[2] + radius * np.cos(theta)
    position = np.array([x, y, z])

    # Orientation: always point toward center
    forward = center - position
    forward = forward / np.linalg.norm(forward)
    up = np.array([0.0, 1.0, 0.0])
    if np.abs(np.dot(forward, up)) > 0.99:
        up = np.array([1.0, 0.0, 0.0])
    rot_obj, _ = R.align_vectors([forward, up], [[0, 0, 1], [0, 1, 0]])
    rot_matrix = rot_obj.as_matrix()
    # Build 4x4 transform
    transform = np.eye(4)
    transform[:3, :3] = rot_matrix
    transform[:3, 3] = position

    transform_message = pyigtl.TransformMessage(transform, device_name='ToolToRAS')
    server.send_message(transform_message, wait=True)
    transform_message = pyigtl.TransformMessage(transverse180, device_name='TipToTool')
    server.send_message(transform_message, wait=True)
    # Since we wait until the message is actually sent, the message queue will not be flooded

@ruffsl the infrastructure for building extensions on GNU/Linux has been updated recently. Some extensions seem to have been affected by this update ( Slicer Build Environment Upgraded to `qt5-almalinux8-gcc14` - #6 by fedorov ). Our colleagues from Kitware are aware of this issue and will check on it soon.

While extensions such as SlicerSOFA and DCMQI seem to fail only in the GNU/Linux build system, some other extension may fail legitimately because they need an update to adapt to the new build system. To test in which case the IGT extensions fall into, it is not enough to build them in your own system. A good test to discriminate whether the extension needs an update or the build system needs and adjustment, you would need to build Slicer and the extensions using Slicer building environment. @ruffsl, would you have the availability to give the extensions a try with GitHub - Slicer/SlicerBuildEnvironment: A repository of scripts to set up a Slicer build environment. using the qt5-almalinux8-gcc14 environment? This would help speeding up the diagnostic and eventual resolution of the problem.

@jcfr, @Sam_Horvath, @pieper, @lassoan

1 Like

I gave it a go using the reference in the readme, see my exact script included below:

Build Script
#!/usr/bin/env bash

################################################################################
# MARK: Build Slicer
################################################################################

SLICER_BUILD_ENV_NAME=qt5-almalinux8-gcc14 
SLICER_BUILD_ENV_VERSION=5.9
SLICER_BRANCH=main

ROOT_DIR=/tmp/Slicer-$SLICER_BUILD_ENV_VERSION
mkdir -p $ROOT_DIR

cd ${ROOT_DIR}

slicer_build_env_script=/tmp/bin/slicer-buildenv-$SLICER_BUILD_ENV_NAME-$SLICER_BUILD_ENV_VERSION
mkdir -p $(dirname $slicer_build_env_script)

# Download sources
git clone https://github.com/Slicer/Slicer -b $SLICER_BRANCH

# Download corresponding build environment and generate convenience script
docker run --rm slicer/buildenv-qt5-almalinux8-gcc14 > $slicer_build_env_script
chmod u+x $slicer_build_env_script

# Configure Slicer
$slicer_build_env_script cmake \
  -BSlicer-build \
  -SSlicer \
  -GNinja \
  -DCMAKE_BUILD_TYPE:STRING=Release

# Build Slicer
$slicer_build_env_script cmake --build Slicer-build

# Package Slicer
$slicer_build_env_script cmake --build Slicer-build/Slicer-build --target package

################################################################################
# MARK: Build Extension
################################################################################

EXTENSION_NAME=SlicerOpenIGTLink

# Download extension source
git clone https://github.com/openigtlink/SlicerOpenIGTLink.git ${EXTENSION_NAME}

# Configure the extension
$slicer_build_env_script cmake \
  -B${EXTENSION_NAME}-build \
  -S${EXTENSION_NAME} \
  -GNinja \
  -DCMAKE_BUILD_TYPE:STRING=Release \
  -DSlicer_DIR:PATH=/work/Slicer-build/Slicer-build

# Build the extension
$slicer_build_env_script cmake --build ${EXTENSION_NAME}-build

# Package the extension
$slicer_build_env_script cmake --build ${EXTENSION_NAME}-build --target package

However, the build for the extension failed:

[24/26] No install step for 'inner'
[26/26] Completed 'inner'
ninja: error: unknown target 'package'

I will note that one thing that tripped my up from the docs while packaging the exetentions from my local source builds on my Ubuntu host was that make package would not work as expected from the toplevel build folder for for either SlicerIGSIO and SlicerOpenIGTLink,

Instead I had to cd into SlicerOpenIGTLink-Release/inner-build and SlicerIGSIO-Release/inner-build to find the Makefile with the expected package function call.

This isn’t something I encountered when building SlicerIGT from source.


Also, it looks like I can’t run the finished Slicer build from outside the docker image on my host:

ruffsl@box /t/S/S/Slicer-build> ./Slicer --version
/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./SlicerApp-real: error while loading shared libraries: libCTKQtTesting.so.0.1: cannot open shared object file: No such file or directory

Although I suspect that’s as expected without these new different QT 5 libs installed locally?