From 13eba3d8429f641b086376a6998a3df3e5245637 Mon Sep 17 00:00:00 2001 From: WalkingDevFlag Date: Mon, 19 Jan 2026 15:28:15 +0530 Subject: [PATCH] cmake: relax CUDA version check to major.minor in OpenCVConfig (#26965) The first-class-language OpenCV CMake config (OpenCVConfig-CUDALanguage.cmake.in) pinned the consumer's CUDA Toolkit to the exact patch version OpenCV was built with (e.g. 12.3.107), via find_package(CUDAToolkit ... EXACT) and a full VERSION_EQUAL check. Patch versions change frequently while the CUDA runtime API is stable within a minor release, so this forced needless rebuilds and could FATAL_ERROR even for a matching toolkit. Per the core team's direction on #26966, the change lives in the installed config template rather than the build scripts, and is controlled by a consumer-set variable: - Default: match major.minor only (fixes the reported patch-pinning bug). - OPENCV_STRONG_CUDA_VERSION_CHECK: restore the exact full-version match. The build-time detection (OpenCVDetectCUDALanguage.cmake) is left untouched, so OpenCV_CUDA_VERSION still records the full version for diagnostics. Fixes #26965 --- .../OpenCVConfig-CUDALanguage.cmake.in | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/cmake/templates/OpenCVConfig-CUDALanguage.cmake.in b/cmake/templates/OpenCVConfig-CUDALanguage.cmake.in index 259141006a..44d8de8225 100644 --- a/cmake/templates/OpenCVConfig-CUDALanguage.cmake.in +++ b/cmake/templates/OpenCVConfig-CUDALanguage.cmake.in @@ -10,6 +10,14 @@ set(OpenCV_CUDNN_VERSION "@CUDNN_VERSION@") set(OpenCV_USE_CUDNN "@HAVE_CUDNN@") set(ENABLE_CUDA_FIRST_CLASS_LANGUAGE ON) +# By default OpenCV only requires the consumer's CUDA Toolkit to match the +# major.minor version it was built with. The CUDA runtime API is stable within +# a minor release and patch versions change frequently, so pinning the patch +# component forces needless rebuilds (issue #26965). Set +# OPENCV_STRONG_CUDA_VERSION_CHECK before find_package(OpenCV) to require an +# exact match including the patch component. +string(REGEX MATCH "^[0-9]+\\.[0-9]+" OpenCV_CUDA_VERSION_MAJOR_MINOR "${OpenCV_CUDA_VERSION}") + if(NOT CUDAToolkit_FOUND) if(NOT CMAKE_VERSION VERSION_LESS 3.18) if(UNIX AND NOT CMAKE_CUDA_COMPILER AND NOT CUDAToolkit_ROOT) @@ -17,15 +25,28 @@ if(NOT CUDAToolkit_FOUND) set(CUDA_PATH "/usr/local/cuda" CACHE INTERNAL "") set(ENV{CUDA_PATH} ${CUDA_PATH}) endif() - find_package(CUDAToolkit ${OpenCV_CUDA_VERSION} EXACT REQUIRED) + if(OPENCV_STRONG_CUDA_VERSION_CHECK) + find_package(CUDAToolkit ${OpenCV_CUDA_VERSION} EXACT REQUIRED) + else() + find_package(CUDAToolkit ${OpenCV_CUDA_VERSION_MAJOR_MINOR} REQUIRED) + endif() else() message(FATAL_ERROR "Using OpenCV compiled with CUDA as first class language requires CMake \>= 3.18.") endif() -else() - if(CUDAToolkit_FOUND) - set(CUDA_VERSION_STRING ${CUDAToolkit_VERSION}) - endif() - if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION) - message(FATAL_ERROR "OpenCV library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}") - endif() +endif() + +if(CUDAToolkit_FOUND) + set(CUDA_VERSION_STRING ${CUDAToolkit_VERSION}) +endif() + +string(REGEX MATCH "^[0-9]+\\.[0-9]+" CUDA_VERSION_STRING_MAJOR_MINOR "${CUDA_VERSION_STRING}") +if(OPENCV_STRONG_CUDA_VERSION_CHECK) + set(__ocv_cuda_found "${CUDA_VERSION_STRING}") + set(__ocv_cuda_built "${OpenCV_CUDA_VERSION}") +else() + set(__ocv_cuda_found "${CUDA_VERSION_STRING_MAJOR_MINOR}") + set(__ocv_cuda_built "${OpenCV_CUDA_VERSION_MAJOR_MINOR}") +endif() +if(NOT __ocv_cuda_found VERSION_EQUAL __ocv_cuda_built) + message(FATAL_ERROR "OpenCV library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}") endif()