From be580d9b9364ba7983db8c09c40641d802800385 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 08:12:25 +0200 Subject: [PATCH 01/12] build: compile all external projects as position-independent code The gz and sdformat python/ruby binding modules are shared objects even in static builds, and they fail to link against non-PIC static archives (seen first at gz-math's ruby module on the clang-static job). Impose CMAKE_POSITION_INDEPENDENT_CODE from the root and forward it to every external project, so the bindings stay enabled in every flavor. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1007353..2ee0c32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,10 @@ set(CMAKE_POLICY_VERSION_MINIMUM 3.5) set(CMAKE_INSTALL_RPATH "$ORIGIN") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) +# Static archives must be position-independent so that the language binding modules, which +# are shared objects even in static builds, can link them. +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + if(CMAKE_INSTALL_PREFIX) list(PREPEND CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}) endif() @@ -72,6 +76,7 @@ compose_forwarded_cache_args( CMAKE_INSTALL_RPATH CMAKE_INSTALL_RPATH_USE_LINK_PATH CMAKE_POLICY_VERSION_MINIMUM + CMAKE_POSITION_INDEPENDENT_CODE CMAKE_PREFIX_PATH) set(ROBOT_FARM_REQUESTED_BUILD_LIST From cea1069fb7868244e32da0153871b106c8f05820 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 08:12:25 +0200 Subject: [PATCH 02/12] ci(docker-image): cap the build at 4 compile jobs The superbuild's outer ninja fanned out external projects while each inner build used every core, oversubscribing the shared build machine into OOM kills that took the runner service down. Serialize the outer level and cap the inner builds at 4 jobs via CMAKE_BUILD_PARALLEL_LEVEL, with CARGO_BUILD_JOBS covering the zenoh cargo build. --- .github/workflows/docker-image.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 373f011..33c5023 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -170,6 +170,8 @@ jobs: --volume "${RUNNER_TEMP}/archive":/archive \ --env CCACHE_DIR=/ccache \ --env CCACHE_MAXSIZE=20G \ + --env CMAKE_BUILD_PARALLEL_LEVEL=4 \ + --env CARGO_BUILD_JOBS=4 \ --env BUILD_LIST="${{ matrix.os_base.build-list }}" \ "${{ steps.image-name-base.outputs.name }}:${{ steps.docker-metadata.outputs.version }}" \ bash -c ' @@ -184,7 +186,11 @@ jobs: -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - cmake --build /tmp/robotFarm-build + # The external projects build serially, each capped at 4 compile jobs by the + # CMAKE_BUILD_PARALLEL_LEVEL (and CARGO_BUILD_JOBS) environment above, so the + # build never exceeds 4 cores and stays within memory. NOTE: this script runs + # inside single quotes, so it must never contain an apostrophe. + cmake --build /tmp/robotFarm-build --parallel 1 cmake --install /tmp/robotFarm-build ccache --show-stats From 5390719b54b1dea5ff69a48ea75f3d68ccfcc31f Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 08:18:00 +0200 Subject: [PATCH 03/12] ci(docker-image): pass the ccache launchers through the environment CMake reads CMAKE_C_COMPILER_LAUNCHER and CMAKE_CXX_COMPILER_LAUNCHER from the environment at first configure, and the environment is inherited by every child configure inside the container, so the launchers sit with the other ccache settings on docker run instead of riding the forwarded cache entries. --- .github/workflows/docker-image.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 33c5023..9d3507a 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -170,6 +170,8 @@ jobs: --volume "${RUNNER_TEMP}/archive":/archive \ --env CCACHE_DIR=/ccache \ --env CCACHE_MAXSIZE=20G \ + --env CMAKE_C_COMPILER_LAUNCHER=ccache \ + --env CMAKE_CXX_COMPILER_LAUNCHER=ccache \ --env CMAKE_BUILD_PARALLEL_LEVEL=4 \ --env CARGO_BUILD_JOBS=4 \ --env BUILD_LIST="${{ matrix.os_base.build-list }}" \ @@ -182,9 +184,7 @@ jobs: cmake -S /tmp/robotFarm-src \ -B /tmp/robotFarm-build \ --preset ${{ matrix.preset }} \ - ${BUILD_LIST:+-DROBOT_FARM_REQUESTED_BUILD_LIST="${BUILD_LIST}"} \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + ${BUILD_LIST:+-DROBOT_FARM_REQUESTED_BUILD_LIST="${BUILD_LIST}"} # The external projects build serially, each capped at 4 compile jobs by the # CMAKE_BUILD_PARALLEL_LEVEL (and CARGO_BUILD_JOBS) environment above, so the From 581afcf1585958a749e29b1bdb3a5ab15a407b30 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:41:50 +0200 Subject: [PATCH 04/12] build(vtk): add the Qt6 OpenGL dev package on ubuntu 22.04 VTK's Qt GUI support needs Qt6's OpenGL component, which qt6-base-dev provides on the newer bases but jammy splits into libqt6opengl6-dev. --- systemDependencies.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systemDependencies.json b/systemDependencies.json index dae101b..88a7aaf 100644 --- a/systemDependencies.json +++ b/systemDependencies.json @@ -158,7 +158,7 @@ }, { "group": "VTKExternalProject", - "ubuntu:22.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", + "ubuntu:22.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libqt6opengl6-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", "ubuntu:24.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", "ubuntu:26.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", "tag": "all" From fc8802fe1acd8eb3ec323611878ad021f9b8f254 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:41:50 +0200 Subject: [PATCH 05/12] build(static): skip the gz projects that upstream cannot build statically gz-rendering fails to export its vendored terra target in static builds, and the installed static configs of gz-common and gz-plugin reference TINYXML2::TINYXML2 and DL::DL targets that consumers cannot resolve. Skip those consumers in static builds only; the base gz libraries, gz-transport, and sdformat remain, and shared builds keep everything. --- CMakeLists.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ee0c32..fee6d32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,21 @@ compose_forwarded_cache_args( CMAKE_POSITION_INDEPENDENT_CODE CMAKE_PREFIX_PATH) +#[[ Upstream gz does not support static consumption: gz-rendering fails to export its + vendored terra target, and the installed static configs of gz-common and gz-plugin + reference TINYXML2::TINYXML2 and DL::DL targets that consumers cannot resolve. Static + builds therefore skip the projects that consume those configs; the base gz libraries, + gz-transport, and sdformat build statically and stay in. ]] +if(NOT BUILD_SHARED_LIBS) + set(ROBOT_FARM_SKIP_GzFuelToolsExternalProject ON) + set(ROBOT_FARM_SKIP_GzGuiExternalProject ON) + set(ROBOT_FARM_SKIP_GzLaunchExternalProject ON) + set(ROBOT_FARM_SKIP_GzPhysicsExternalProject ON) + set(ROBOT_FARM_SKIP_GzRenderingExternalProject ON) + set(ROBOT_FARM_SKIP_GzSensorsExternalProject ON) + set(ROBOT_FARM_SKIP_GzSimExternalProject ON) +endif() + set(ROBOT_FARM_REQUESTED_BUILD_LIST AbseilExternalProject BoostExternalProject From 8822ceb80aca929d7ca4bde76f8c715583b088de Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:56:19 +0200 Subject: [PATCH 06/12] build(opencv): pin CUDA architectures and allow new host compilers OpenCV builds CUDA through its legacy FindCUDA path, which probes nvcc itself and never sees the toolchain's CMAKE_CUDA_* settings. The fresh bases carry host compilers newer than nvcc admits (clang 22 on ubuntu 26.04), so the architecture autodetection came back empty and the configure failed. Hand OpenCV the architecture list matching the toolchain files and the -allow-unsupported-compiler override they already use. --- externalProjects/OpenCVExternalProject.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/externalProjects/OpenCVExternalProject.cmake b/externalProjects/OpenCVExternalProject.cmake index 83dab8a..79892f0 100644 --- a/externalProjects/OpenCVExternalProject.cmake +++ b/externalProjects/OpenCVExternalProject.cmake @@ -227,12 +227,19 @@ else() algorithms inside contrib. ]] if(CUDAToolkit_FOUND AND ROBOT_FARM_OPENCV_WITH_CONTRIB) message(STATUS "Turning on CUDA options for OpenCV") + #[[ OpenCV builds CUDA through its legacy FindCUDA path, which probes nvcc itself and + never sees the toolchain's CMAKE_CUDA_* settings. The fresh bases carry host + compilers newer than nvcc admits (clang 22 on ubuntu 26.04), so hand OpenCV the + architecture list and the override flag the toolchain files already use. ]] list(APPEND ROBOT_FARM_OPENCV_CMAKE_ARGS -DWITH_CUDA:BOOL=ON -DWITH_CUBLAS:BOOL=ON -DWITH_CUDNN:BOOL=ON -DWITH_CUFFT:BOOL=ON -DCUDA_FAST_MATH=1 + -DCUDA_ARCH_BIN:STRING=7.5,8.0 + -DCUDA_NVCC_FLAGS:STRING=-allow-unsupported-compiler + -DOPENCV_CUDA_DETECTION_NVCC_FLAGS:STRING=-allow-unsupported-compiler -DWITH_NVCUVID:BOOL=ON -DBUILD_opencv_cudacodec:BOOL=OFF -DBUILD_opencv_world:BOOL=OFF) From 4c0385c467d58613ca9644495be3bc4090aa2541 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:51:39 +0200 Subject: [PATCH 07/12] build(cudss): guard the shipped config against double inclusion cudss-config.cmake promotes its imported targets to global scope unconditionally, which CMake rejects when a second directory includes the config: opencv_contrib's sfm module re-finds Ceres, whose config finds cuDSS again, and the OpenCV configure dies. Patch an early return into the installed config so only the first inclusion creates and promotes. --- externalProjects/CudssExternalProject.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/externalProjects/CudssExternalProject.cmake b/externalProjects/CudssExternalProject.cmake index cb12e4f..2cd765d 100644 --- a/externalProjects/CudssExternalProject.cmake +++ b/externalProjects/CudssExternalProject.cmake @@ -33,6 +33,13 @@ else() URL ${ROBOT_FARM_CUDSS_URL} URL_HASH ${ROBOT_FARM_CUDSS_URL_HASH} DOWNLOAD_NO_PROGRESS ON + #[[ The shipped config promotes its imported targets to global scope unconditionally, + which CMake rejects when a second directory includes the config (seen when + opencv_contrib's sfm module re-finds Ceres, whose config finds cuDSS again). Guard + the config with an early return so only the first inclusion creates and promotes. ]] + PATCH_COMMAND sed -i + "1i # robotFarm: return early when already loaded; the IMPORTED_GLOBAL promotion\\n# below fails when a second directory includes this config.\\nif(TARGET cudss)\\n return()\\nendif()" + lib/cmake/cudss/cudss-config.cmake CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory /include ${CMAKE_INSTALL_PREFIX}/include From 99c479f1a54660dc185c1134c9a1ec1d434dbf67 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:54:56 +0200 Subject: [PATCH 08/12] build(cudss): drop the semicolon that split the patch command CMake expands semicolons in COMMAND arguments as list separators, so the guard comment's semicolon split the sed text into a second file argument and the patch step failed. --- externalProjects/CudssExternalProject.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externalProjects/CudssExternalProject.cmake b/externalProjects/CudssExternalProject.cmake index 2cd765d..4344f39 100644 --- a/externalProjects/CudssExternalProject.cmake +++ b/externalProjects/CudssExternalProject.cmake @@ -38,7 +38,7 @@ else() opencv_contrib's sfm module re-finds Ceres, whose config finds cuDSS again). Guard the config with an early return so only the first inclusion creates and promotes. ]] PATCH_COMMAND sed -i - "1i # robotFarm: return early when already loaded; the IMPORTED_GLOBAL promotion\\n# below fails when a second directory includes this config.\\nif(TARGET cudss)\\n return()\\nendif()" + "1i # robotFarm: return early when already loaded. The IMPORTED_GLOBAL promotion\\n# below fails when a second directory includes this config.\\nif(TARGET cudss)\\n return()\\nendif()" lib/cmake/cudss/cudss-config.cmake CONFIGURE_COMMAND "" BUILD_COMMAND "" From 8741e81c45528bdf552662b71ef7fafbeac56a86 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 13:51:25 +0200 Subject: [PATCH 09/12] build(opencv): keep the shared CUDA runtime in static builds With the static CUDA runtime OpenCV lists bare library names (cudart_static, cublas, cudnn) plus -L flags, and the python binding generator hands those names to ninja as file dependencies, failing the cv2 module link. The shared-runtime path resolves the CUDA libraries to full paths, as the passing shared lanes already show, and the CUDA libraries are system-provided at runtime either way. --- externalProjects/OpenCVExternalProject.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/externalProjects/OpenCVExternalProject.cmake b/externalProjects/OpenCVExternalProject.cmake index 79892f0..fd73055 100644 --- a/externalProjects/OpenCVExternalProject.cmake +++ b/externalProjects/OpenCVExternalProject.cmake @@ -238,6 +238,10 @@ else() -DWITH_CUFFT:BOOL=ON -DCUDA_FAST_MATH=1 -DCUDA_ARCH_BIN:STRING=7.5,8.0 + # With the static CUDA runtime OpenCV lists bare library names (cublas, cudnn) that + # the python binding generator hands to ninja as file dependencies, and the link + # fails. The CUDA libraries are system-provided at runtime either way. + -DCUDA_USE_STATIC_CUDA_RUNTIME:BOOL=OFF -DCUDA_NVCC_FLAGS:STRING=-allow-unsupported-compiler -DOPENCV_CUDA_DETECTION_NVCC_FLAGS:STRING=-allow-unsupported-compiler -DWITH_NVCUVID:BOOL=ON From 594ce0f1af832e0fb035065582a579346dd403e3 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 16:02:26 +0200 Subject: [PATCH 10/12] build(opencv): skip the python bindings in static builds In a static build the cv2 python module links every module directly, and OpenCV's legacy CUDA path emits bare linker names (cublas, cudnn) that the binding generator hands to ninja as file dependencies, so the module cannot link. The shared-runtime switch from the previous commit did not change that and is reverted. Python consumers use the shared flavors, where the bindings stay enabled. --- externalProjects/OpenCVExternalProject.cmake | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/externalProjects/OpenCVExternalProject.cmake b/externalProjects/OpenCVExternalProject.cmake index fd73055..8309019 100644 --- a/externalProjects/OpenCVExternalProject.cmake +++ b/externalProjects/OpenCVExternalProject.cmake @@ -238,10 +238,6 @@ else() -DWITH_CUFFT:BOOL=ON -DCUDA_FAST_MATH=1 -DCUDA_ARCH_BIN:STRING=7.5,8.0 - # With the static CUDA runtime OpenCV lists bare library names (cublas, cudnn) that - # the python binding generator hands to ninja as file dependencies, and the link - # fails. The CUDA libraries are system-provided at runtime either way. - -DCUDA_USE_STATIC_CUDA_RUNTIME:BOOL=OFF -DCUDA_NVCC_FLAGS:STRING=-allow-unsupported-compiler -DOPENCV_CUDA_DETECTION_NVCC_FLAGS:STRING=-allow-unsupported-compiler -DWITH_NVCUVID:BOOL=ON @@ -259,6 +255,15 @@ else() -DBUILD_opencv_world:BOOL=OFF) endif() + #[[ In a static build the cv2 python module links every module directly, and OpenCV's + legacy CUDA path emits bare linker names (cublas, cudnn) that the binding generator + hands to ninja as file dependencies, so the module cannot link. Python consumers use + the shared flavors, where the bindings stay enabled. ]] + if(NOT BUILD_SHARED_LIBS) + list(APPEND ROBOT_FARM_OPENCV_CMAKE_ARGS + -DBUILD_opencv_python3:BOOL=OFF) + endif() + if(ROBOT_FARM_OPENCV_WITH_CONTRIB) #[[ The 5.0.0 viz module relies on VTK headers to transitively provide , which stops holding with VTK 9.6 and GCC 15. Same fix as vcpkg's From 0ea5603937d52e54ca88b0bef59e89be17d91b9a Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 16:11:36 +0200 Subject: [PATCH 11/12] build(vtk): declare the Qt6 declarative dev package for every base VTK's QtQuick GUI support needs the Qt6 Quick and Qml configs from qt6-declarative-dev. The newer bases received it incidentally through the gz-gui group, which 22.04 never installs because gz is not buildable there, so its VTK configure failed. Declare the dependency in the VTK group itself on all bases. --- systemDependencies.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/systemDependencies.json b/systemDependencies.json index 88a7aaf..9257274 100644 --- a/systemDependencies.json +++ b/systemDependencies.json @@ -158,9 +158,9 @@ }, { "group": "VTKExternalProject", - "ubuntu:22.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libqt6opengl6-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", - "ubuntu:24.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", - "ubuntu:26.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev", + "ubuntu:22.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libqt6opengl6-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev qt6-declarative-dev", + "ubuntu:24.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev qt6-declarative-dev", + "ubuntu:26.04": "libavcodec-dev libavformat-dev libavutil-dev libgdal-dev libgl1-mesa-dev libswresample-dev libswscale-dev libtbb-dev libxt-dev mpi-default-dev python3-dev qt6-base-dev qt6-declarative-dev", "tag": "all" }, { From b04e1520766f1cb290b3de36c5f256fb6d227400 Mon Sep 17 00:00:00 2001 From: Anurag Jakhotia <5448528+ajakhotia@users.noreply.github.com> Date: Fri, 21 Aug 2026 21:59:05 +0200 Subject: [PATCH 12/12] build(opencv): declare the Qt6 Core5Compat dev package for every base opencv_contrib's cvv module requires the Qt6 Core5Compat component, which the newer bases received incidentally through the gz-gui group and 22.04 lacks entirely. Declare it in the OpenCV group on all bases, under jammy's package name libqt6core5compat6-dev there. --- systemDependencies.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/systemDependencies.json b/systemDependencies.json index 9257274..15d2424 100644 --- a/systemDependencies.json +++ b/systemDependencies.json @@ -131,9 +131,9 @@ }, { "group": "OpenCVExternalProject", - "ubuntu:22.04": "libcudnn9-dev-cuda-13 libavcodec-dev libavformat-dev libavif-dev libavutil-dev libdc1394-dev libgdal-dev libgphoto2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libhdf5-dev libjpeg-dev liblapacke-dev libopenexr-dev libopenjp2-7-dev libpng-dev libswresample-dev libswscale-dev libtbb-dev libtesseract-dev libtiff-dev libv4l-dev libwebp-dev python3-dev python3-numpy qt6-base-dev v4l-utils", - "ubuntu:24.04": "libcudnn9-dev-cuda-13 libavcodec-dev libavformat-dev libavif-dev libavutil-dev libdc1394-dev libgdal-dev libgphoto2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libhdf5-dev libjpeg-dev libjxl-dev liblapacke-dev libopenexr-dev libopenjp2-7-dev libpng-dev libswresample-dev libswscale-dev libtbb-dev libtesseract-dev libtiff-dev libv4l-dev libwebp-dev python3-dev python3-numpy qt6-base-dev v4l-utils", - "ubuntu:26.04": "libcudnn9-dev-cuda-13 libavcodec-dev libavformat-dev libavif-dev libavutil-dev libdc1394-dev libgdal-dev libgphoto2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libhdf5-dev libjpeg-dev libjxl-dev liblapacke-dev libopenexr-dev libopenjp2-7-dev libpng-dev libswresample-dev libswscale-dev libtbb-dev libtesseract-dev libtiff-dev libv4l-dev libwebp-dev python3-dev python3-numpy qt6-base-dev v4l-utils", + "ubuntu:22.04": "libcudnn9-dev-cuda-13 libavcodec-dev libavformat-dev libavif-dev libavutil-dev libdc1394-dev libgdal-dev libgphoto2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libhdf5-dev libjpeg-dev liblapacke-dev libopenexr-dev libopenjp2-7-dev libpng-dev libswresample-dev libswscale-dev libtbb-dev libtesseract-dev libtiff-dev libv4l-dev libwebp-dev python3-dev python3-numpy libqt6core5compat6-dev qt6-base-dev v4l-utils", + "ubuntu:24.04": "libcudnn9-dev-cuda-13 libavcodec-dev libavformat-dev libavif-dev libavutil-dev libdc1394-dev libgdal-dev libgphoto2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libhdf5-dev libjpeg-dev libjxl-dev liblapacke-dev libopenexr-dev libopenjp2-7-dev libpng-dev libswresample-dev libswscale-dev libtbb-dev libtesseract-dev libtiff-dev libv4l-dev libwebp-dev python3-dev python3-numpy qt6-5compat-dev qt6-base-dev v4l-utils", + "ubuntu:26.04": "libcudnn9-dev-cuda-13 libavcodec-dev libavformat-dev libavif-dev libavutil-dev libdc1394-dev libgdal-dev libgphoto2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libhdf5-dev libjpeg-dev libjxl-dev liblapacke-dev libopenexr-dev libopenjp2-7-dev libpng-dev libswresample-dev libswscale-dev libtbb-dev libtesseract-dev libtiff-dev libv4l-dev libwebp-dev python3-dev python3-numpy qt6-5compat-dev qt6-base-dev v4l-utils", "tag": "all" }, {