diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 373f011..9d3507a 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -170,6 +170,10 @@ 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 }}" \ "${{ steps.image-name-base.outputs.name }}:${{ steps.docker-metadata.outputs.version }}" \ bash -c ' @@ -180,11 +184,13 @@ 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}"} - 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1007353..fee6d32 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,8 +76,24 @@ compose_forwarded_cache_args( CMAKE_INSTALL_RPATH CMAKE_INSTALL_RPATH_USE_LINK_PATH CMAKE_POLICY_VERSION_MINIMUM + 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 diff --git a/externalProjects/CudssExternalProject.cmake b/externalProjects/CudssExternalProject.cmake index cb12e4f..4344f39 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 diff --git a/externalProjects/OpenCVExternalProject.cmake b/externalProjects/OpenCVExternalProject.cmake index 83dab8a..8309019 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) @@ -248,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 diff --git a/systemDependencies.json b/systemDependencies.json index dae101b..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" }, { @@ -158,9 +158,9 @@ }, { "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: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" }, {