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?

@ruffsl, thanks for having a look at it so quickly. And very good investigation job!

This is expected since the SlicerOpenIGTLink is a superbuild extension. Superbuild extensions build first an ecosystem of libraries to support the build of the extension, which as you found out happens in inner-build. The script should probably account for that and issue:

$slicer_build_env_script cmake --build ${EXTENSION_NAME}-build/inner-build --target package

Yes, that’s what I think. To fully verify you could try executing 3D Slicer inside the container, but I don’t think it is needed. You have successfully build the SlicerOpenIGTLink, with the Slicer environment, which does not happen in the Slicer infrastructure.

Let’s report all of this as an issue in 3D Slicer (if there’s not one yet) and continue the discussion from there. Send me a private with your github handle, if you want to be notified and participate there. I would be useful if you could give it a try to SlicerIGSIO and SlicerIGT too, as they seem to fail in different ways (in reality, SlicerIGT seems to fail due to SlicerIGSIO not being built).

Thank you for the great insight you have provided on the problem.

1 Like
-$slicer_build_env_script cmake --build ${EXTENSION_NAME}-build --target package
+$slicer_build_env_script cmake --build ${EXTENSION_NAME}-build/inner-build --target package

A case by case change, or something should slicer_build_env_script auto detect?

That worked for packaging SlicerOpenIGTLink via qt5-almalinux8-gcc14:

[24/26] No install step for 'inner'
[26/26] Completed 'inner'

real    0m36.421s
user    0m0.046s
sys     0m0.053s
[0/1] Run CPack packaging tool...
CPack: Create package using TGZ
CPack: Install projects
CPack: - Install project: SlicerOpenIGTLink []
CPack: - Install project: OpenIGTLink []
CPack: - Install project: OpenIGTLinkIO []
CPack: Create package
CPack: - package: /work/SlicerOpenIGTLink-build/inner-build/33872-linux-amd64-SlicerOpenIGTLink-gitf806007-2025-07-26.tar.gz generated.

Looks like they both build packages, but as before, can’t run this Slicer on host to test:

[31/34] No install step for 'inner'
[34/34] Completed 'inner'

real    1m11.141s
user    0m0.031s
sys     0m0.056s
[0/1] Run CPack packaging tool...
CPack: Create package using TGZ
CPack: Install projects
CPack: - Install project: SlicerIGSIO []
CPack: - Install project: IGSIO []
CPack: Create package
CPack: - package: /work/SlicerIGSIO-build/inner-build/33872-linux-amd64-SlicerIGSIO-git1a89776-2023-10-03.tar.gz generated.
EXTENSION_NAME=SlicerIGT

# Download extension source
git clone https://github.com/SlicerIGT/SlicerIGT.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 \
+  -DSlicerIGSIO_DIR:PATH=/work/SlicerIGSIO-build/inner-build

# Build the extension
time $slicer_build_env_script cmake --build ${EXTENSION_NAME}-build | tee extension_build.log

# Package the extension
$slicer_build_env_script cmake --build ${EXTENSION_NAME}-build --target package
real    0m30.716s
user    0m0.045s
sys     0m0.062s
[0/1] Run CPack packaging tool...
CPack: Create package using TGZ
CPack: Install projects
CPack: - Install project: SlicerIGT []
CPack: Create package
CPack: - package: /work/SlicerIGT-build/33872-linux-amd64-SlicerIGT-gitcc9678a-2025-08-19.tar.gz generated.

On which repo issue tracker in particular? Of these?

My user handle on GitHub is the same as here:

If you used the official Slicer build environment to build the package then you can install that package in the matching official Slicer Preview Release.

1 Like

The source checkout of Slicer I used with the build environment was the current HEAD of the main branch (b5a65a49a08171276f6a9624999450c0e8ec0116). How can discover what commit was used in the compilation for a given build jobs. E.g:

It looks like the Help -> About 3D Slicer menu does display a valid commit sha in the version string (but not in Slicer --launcher-version oddly enough):

5.9.0-2025-08-22 r33871 / c7e7ed1

But I can’t find the corresponding job for commit c7e7ed1, nor what commit a given job corresponds without downloading and inspecting each separate binary archive.

I’d just like to be sure I’m using the exact matching source trees for apples to apples.

That said, it looks to be installing & working, so I suppose the extensions built on top of b5a65a4 are close enough to c7e7ed1 in terms of API/ABI at the moment.


This all aside, it is concerning that the official Slicer build environment when used locally is not outputting an equivalent running binary as the remote buildfarm does.

The Slicer Preview across all platforms is built daily starting at 11pm ET, so the latest commit on main is what is used for the build. You can see at SlicerPreview the commit hash that was checked out for each platform. As of writing this c7e7ed1was the latest commit when it was triggered last night. The b5a65a4 was the next commit which came several hours later in the morning ET. Slicer Previews are built once daily by the factory machines and are not built and packaged for each commit to main.

Now understood; not every commit may be scheduled for daily build.

Thanks for pointing out the Revision column in the Nightly-Packages table includes the Git commit sha. I was fruitlessly looking for the sha under the job’s own page. From the dashboard URLs, I see the build stores this revision info under the slug /update.

-https://slicer.cdash.org/builds/3906947
+https://slicer.cdash.org/builds/3906947/update

However, where is this revision info for extensions jobs under Extensions-Nightly?

In searching for resources on the missing libCTKQtTesting.so library, in found:

An sure enough, libCTKQtTesting.so was merely just the first shared lib not found:

~/t/S/S/Slicer-build> ./Slicer --launch ldd ./bin/SlicerApp-real | head
        linux-vdso.so.1 (0x0000773d3e11d000)
        libqSlicerApp.so => /home/ruffsl/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./libqSlicerApp.so (0x0000773d3e073000)
        libqSlicerBaseQTApp.so => /home/ruffsl/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./libqSlicerBaseQTApp.so (0x0000773d3e01f000)
        libqSlicerModulesCore.so => /home/ruffsl/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./libqSlicerModulesCore.so (0x0000773d3dfff000)
        libqSlicerBaseQTCLI.so => /home/ruffsl/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./libqSlicerBaseQTCLI.so (0x0000773d3df9d000)
        libqSlicerBaseQTGUI.so => /home/ruffsl/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./libqSlicerBaseQTGUI.so (0x0000773d3dc00000)
        libqMRMLWidgets.so => /home/ruffsl/tmp/Slicer-5.9/Slicer-build/Slicer-build/bin/./libqMRMLWidgets.so (0x0000773d3d800000)
        libCTKQtTesting.so.0.1 => not found
        libCTKVisualizationVTKWidgets.so.0.1 => not found
        libCTKScriptingPythonWidgets.so.0.1 => not found

After downloading and inspecting the buildfarm artifacts for the same commit, noticed the file tree was different compared to my local cmake build folder, and that I was attempting to run the Slicer binary directly, rather than from the extracted launcher binary from the generated .tar.gz archive nested inside the very same local build.

Sure enough, the packaged version is working as expected without any missing libs:

~/t/S/S/Slicer-build/Slicer-5.9.0-2025-08-25-linux-amd64$ ./Slicer \
    --launch ldd ./bin/SlicerApp-real | grep "not found"
~/t/S/S/Slicer-build/Slicer-5.9.0-2025-08-25-linux-amd64$

Is this the Cmake macro triggered by this corresponding command? Cpack is new to me.

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

33881-SlicerIGT-gitcc9678a-g+±64bits-Qt5.15-Release

^This was building commit cc9678a of SlicerIGT repo using the SlicerPreview build of Slicer core that was built.

How is that association traced? Or just fuzzy search via timestamps? Git only timestamps commits creation, not when the commit was push to a remote branch.

SlicerIGT’s extension index entry specifies to use the latest of the master branch as stated here. So at build time it will pull the latest which in that specific case was cc9678a. Git has both authored date and commit date, and in this situation was pulling the latest of the master branch at build time.

@RafaelPalomar , was a ticket created, our should I add it?