OpenCVDetectCUDAUtils.cmake 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. macro(ocv_check_for_nvidia_video_codec_sdk cuda_toolkit_dirs)
  2. macro(ocv_cuda_SEARCH_NVCUVID_HEADER _filename _result)
  3. # place header file under CUDAToolkit_LIBRARY_ROOT
  4. find_path(_header_result
  5. ${_filename}
  6. PATHS ${cuda_toolkit_dirs}
  7. PATH_SUFFIXES include
  8. NO_DEFAULT_PATH
  9. )
  10. if("x${_header_result}" STREQUAL "x_header_result-NOTFOUND")
  11. set(${_result} 0)
  12. else()
  13. set(${_result} 1)
  14. endif()
  15. unset(_header_result CACHE)
  16. endmacro()
  17. if(WITH_NVCUVID)
  18. ocv_cuda_SEARCH_NVCUVID_HEADER("nvcuvid.h" HAVE_NVCUVID_HEADER)
  19. # make sure to have both header and library before enabling
  20. if(${HAVE_NVCUVID_HEADER})
  21. find_cuda_helper_libs(nvcuvid)
  22. if(CUDA_nvcuvid_LIBRARY)
  23. set(HAVE_NVCUVID 1)
  24. message(STATUS "Found NVCUVID: ${CUDA_nvcuvid_LIBRARY}")
  25. else()
  26. if(WIN32)
  27. message(STATUS "NVCUVID: Library not found, WITH_NVCUVID requires Nvidia decoding library nvcuvid.lib to either be inside ${cuda_toolkit_dirs}/lib or its location manually set with CUDA_nvcuvid_LIBRARY, i.e. CUDA_nvcuvid_LIBRARY=${cuda_toolkit_dirs}/lib/nvcuvid.lib")
  28. else()
  29. message(STATUS "NVCUVID: Library not found, WITH_NVCUVID requires the Nvidia decoding shared library nvcuvid.so from the driver installation or the location of the stub library to be manually set with CUDA_nvcuvid_LIBRARY i.e. CUDA_nvcuvid_LIBRARY=/home/user/Video_Codec_SDK_X.X.X/Lib/linux/stubs/x86_64/nvcuvid.so")
  30. endif()
  31. endif()
  32. else()
  33. message(STATUS "NVCUVID: Header not found, WITH_NVCUVID requires Nvidia decoding library header ${cuda_toolkit_dirs}/include/nvcuvid.h")
  34. endif()
  35. endif()
  36. if(WITH_NVCUVENC)
  37. ocv_cuda_SEARCH_NVCUVID_HEADER("nvEncodeAPI.h" HAVE_NVCUVENC_HEADER)
  38. if(${HAVE_NVCUVENC_HEADER})
  39. if(WIN32)
  40. find_cuda_helper_libs(nvencodeapi)
  41. else()
  42. find_cuda_helper_libs(nvidia-encode)
  43. endif()
  44. if(CUDA_nvencodeapi_LIBRARY OR CUDA_nvidia-encode_LIBRARY)
  45. set(HAVE_NVCUVENC 1)
  46. message(STATUS "Found NVCUVENC: ${CUDA_nvencodeapi_LIBRARY} ${CUDA_nvidia-encode_LIBRARY}")
  47. else()
  48. if(WIN32)
  49. message(STATUS "NVCUVENC: Library not found, WITH_NVCUVENC requires Nvidia encoding library nvencodeapi.lib to either be inside ${cuda_toolkit_dirs}/lib or its location manually set with CUDA_nvencodeapi_LIBRARY, i.e. CUDA_nvencodeapi_LIBRARY=${cuda_toolkit_dirs}/lib/nvencodeapi.lib")
  50. else()
  51. message(STATUS "NVCUVENC: Library not found, WITH_NVCUVENC requires the Nvidia encoding shared library libnvidia-encode.so from the driver installation or the location of the stub library to be manually set with CUDA_nvidia-encode_LIBRARY i.e. CUDA_nvidia-encode_LIBRARY=/home/user/Video_Codec_SDK_X.X.X/Lib/linux/stubs/x86_64/libnvidia-encode.so")
  52. endif()
  53. endif()
  54. else()
  55. message(STATUS "NVCUVENC: Header not found, WITH_NVCUVENC requires Nvidia encoding library header ${cuda_toolkit_dirs}/include/nvEncodeAPI.h")
  56. endif()
  57. endif()
  58. endmacro()
  59. # Use CMAKE_CUDA_ARCHITECTURES if provided: order of preference CMAKE_CUDA_ARCHITECTURES > CUDA_GENERATION > CUDA_ARCH_BIN and/or CUDA_ARCH_PTX
  60. function(ocv_check_for_cmake_cuda_architectures)
  61. if(NOT CMAKE_CUDA_ARCHITECTURES)
  62. return()
  63. endif()
  64. if(CMAKE_CUDA_ARCHITECTURES STREQUAL "all" OR CMAKE_CUDA_ARCHITECTURES STREQUAL "all-major" OR CMAKE_CUDA_ARCHITECTURES STREQUAL "native")
  65. message(WARNING "CUDA: CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}, special values all, all-major and native are not supported by OpenCV, specify only CUDA real and/or virtual architectures or use combinations of CUDA_ARCH_BIN and CUDA_ARCH_PTX or specify the CUDA_GENERATION where -DCUDA_GENERATION=Auto is equivalent to native!")
  66. return()
  67. endif()
  68. set(internal_ptx "")
  69. set(internal_bin "")
  70. foreach(ARCH IN LISTS CMAKE_CUDA_ARCHITECTURES)
  71. if(ARCH MATCHES "([0-9]+)\-real")
  72. set(internal_bin ${internal_bin} ${CMAKE_MATCH_1};)
  73. elseif(ARCH MATCHES "([0-9]+)\-virtual")
  74. set(internal_ptx ${internal_ptx} ${CMAKE_MATCH_1};)
  75. elseif(ARCH MATCHES "([0-9]+)")
  76. set(internal_bin ${internal_bin} ${CMAKE_MATCH_1};)
  77. set(internal_ptx ${internal_ptx} ${CMAKE_MATCH_1};)
  78. endif()
  79. endforeach()
  80. if(internal_bin OR internal_ptx)
  81. unset(CUDA_ARCH_BIN CACHE)
  82. unset(CUDA_ARCH_PTX CACHE)
  83. endif()
  84. if(internal_ptx)
  85. set(CUDA_ARCH_PTX ${internal_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for (see https://docs.opencv.org/4.x/d2/dbc/cuda_intro.html)")
  86. endif()
  87. if(internal_bin)
  88. set(CUDA_ARCH_BIN ${internal_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported (see https://docs.opencv.org/4.x/d2/dbc/cuda_intro.html)")
  89. endif()
  90. set(CMAKE_CUDA_ARCHITECTURES "" PARENT)
  91. unset(CUDA_GENERATION CACHE)
  92. endfunction()
  93. macro(ocv_initialize_nvidia_device_generations)
  94. OCV_OPTION(CUDA_ENABLE_DEPRECATED_GENERATION "Enable deprecated generations in the list" OFF)
  95. set(_generations "Maxwell" "Pascal" "Volta" "Turing" "Ampere" "Lovelace" "Hopper" "Blackwell")
  96. if(CUDA_ENABLE_DEPRECATED_GENERATION)
  97. set(_generations "Fermi" "${_generations}")
  98. set(_generations "Kepler" "${_generations}")
  99. endif()
  100. set(_arch_fermi "2.0")
  101. set(_arch_kepler "3.0;3.5;3.7")
  102. set(_arch_maxwell "5.0;5.2")
  103. set(_arch_pascal "6.0;6.1")
  104. set(_arch_volta "7.0")
  105. set(_arch_turing "7.5")
  106. set(_arch_ampere "8.0;8.6")
  107. set(_arch_lovelace "8.9")
  108. set(_arch_hopper "9.0")
  109. set(_arch_blackwell "10.0;10.3;11.0;12.0;12.1")
  110. if(NOT CMAKE_CROSSCOMPILING)
  111. list(APPEND _generations "Auto")
  112. endif()
  113. set(CUDA_GENERATION "" CACHE STRING "Build CUDA device code only for specific GPU architecture. Leave empty to build for all architectures (see https://docs.opencv.org/4.x/d2/dbc/cuda_intro.html).")
  114. if( CMAKE_VERSION VERSION_GREATER "2.8" )
  115. set_property( CACHE CUDA_GENERATION PROPERTY STRINGS "" ${_generations} )
  116. endif()
  117. if(CUDA_GENERATION)
  118. if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};")
  119. string(REPLACE ";" ", " _generations "${_generations}")
  120. message(FATAL_ERROR "ERROR: ${_generations} Generations are supported.")
  121. endif()
  122. unset(CUDA_ARCH_BIN CACHE)
  123. unset(CUDA_ARCH_PTX CACHE)
  124. endif()
  125. endmacro()
  126. macro(ocv_set_cuda_detection_nvcc_flags cuda_host_compiler_var)
  127. if(OPENCV_CUDA_DETECTION_NVCC_FLAGS MATCHES "-ccbin")
  128. # already specified by user
  129. elseif(${cuda_host_compiler_var} AND EXISTS "${${cuda_host_compiler_var}}")
  130. get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
  131. # C compiler doesn't work with --run option, forcing C++ compiler instead
  132. if(${cuda_host_compiler_var} STREQUAL c_compiler_realpath OR ${cuda_host_compiler_var} STREQUAL CMAKE_C_COMPILER)
  133. if(DEFINED CMAKE_CXX_COMPILER)
  134. get_filename_component(cxx_compiler_realpath "${CMAKE_CXX_COMPILER}" REALPATH)
  135. LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${cxx_compiler_realpath}")
  136. else()
  137. message(STATUS "CUDA: CMAKE_CXX_COMPILER is not available. You may need to specify ${cuda_host_compiler_var}.")
  138. endif()
  139. else()
  140. LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${${cuda_host_compiler_var}}")
  141. endif()
  142. elseif(WIN32 AND CMAKE_LINKER) # Workaround for VS cl.exe not being in the env. path
  143. get_filename_component(host_compiler_bindir ${CMAKE_LINKER} DIRECTORY)
  144. LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${host_compiler_bindir}")
  145. else()
  146. if(${cuda_host_compiler_var})
  147. message(STATUS "CUDA: ${cuda_host_compiler_var}='${cuda_host_compiler}' is not valid, autodetection may not work. Specify OPENCV_CUDA_DETECTION_NVCC_FLAGS with -ccbin option for fix that")
  148. endif()
  149. endif()
  150. endmacro()
  151. macro(ocv_filter_available_architecture nvcc_executable result_list)
  152. set(__cache_key_check "${ARGN} : ${nvcc_executable} ${OPENCV_CUDA_DETECTION_NVCC_FLAGS}")
  153. if(DEFINED OPENCV_CACHE_CUDA_SUPPORTED_CC AND OPENCV_CACHE_CUDA_SUPPORTED_CC_check STREQUAL __cache_key_check)
  154. set(${result_list} "${OPENCV_CACHE_CUDA_SUPPORTED_CC}")
  155. else()
  156. set(CC_LIST ${ARGN})
  157. foreach(target_arch ${CC_LIST})
  158. string(REPLACE "." "" target_arch_short "${target_arch}")
  159. set(NVCC_OPTION "-gencode;arch=compute_${target_arch_short},code=sm_${target_arch_short}")
  160. set(_cmd "${nvcc_executable}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" --compile)
  161. execute_process(
  162. COMMAND ${_cmd}
  163. WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
  164. RESULT_VARIABLE _nvcc_res
  165. OUTPUT_VARIABLE _nvcc_out
  166. ERROR_VARIABLE _nvcc_err
  167. #ERROR_QUIET
  168. OUTPUT_STRIP_TRAILING_WHITESPACE
  169. )
  170. if(OPENCV_CMAKE_CUDA_DEBUG)
  171. message(WARNING "COMMAND: ${_cmd}")
  172. message(STATUS "Result: ${_nvcc_res}")
  173. message(STATUS "Out: ${_nvcc_out}")
  174. message(STATUS "Err: ${_nvcc_err}")
  175. endif()
  176. if(_nvcc_res EQUAL 0)
  177. LIST(APPEND ${result_list} "${target_arch}")
  178. endif()
  179. endforeach()
  180. string(STRIP "${${result_list}}" ${result_list})
  181. if(" ${${result_list}}" STREQUAL " ")
  182. message(WARNING "CUDA: Autodetection arch list is empty. Please enable OPENCV_CMAKE_CUDA_DEBUG=1 and check/specify OPENCV_CUDA_DETECTION_NVCC_FLAGS variable")
  183. endif()
  184. # cache detected values
  185. set(OPENCV_CACHE_CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "")
  186. set(OPENCV_CACHE_CUDA_SUPPORTED_CC_check "${__cache_key_check}" CACHE INTERNAL "")
  187. endif()
  188. endmacro()
  189. macro(ocv_detect_native_cuda_arch nvcc_executable status output)
  190. set(OPENCV_CUDA_DETECT_ARCHS_COMMAND "${nvcc_executable}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run")
  191. set(__cache_key_check "${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
  192. if(DEFINED OPENCV_CACHE_CUDA_ACTIVE_CC AND OPENCV_CACHE_CUDA_ACTIVE_CC_check STREQUAL __cache_key_check)
  193. set(${output} "${OPENCV_CACHE_CUDA_ACTIVE_CC}")
  194. set(${status} 0)
  195. else()
  196. execute_process(
  197. COMMAND ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}
  198. WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
  199. RESULT_VARIABLE ${status}
  200. OUTPUT_VARIABLE _nvcc_out
  201. ERROR_VARIABLE _nvcc_err
  202. ERROR_QUIET
  203. OUTPUT_STRIP_TRAILING_WHITESPACE
  204. )
  205. if(OPENCV_CMAKE_CUDA_DEBUG)
  206. message(WARNING "COMMAND: ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
  207. message(STATUS "Result: ${${status}}")
  208. message(STATUS "Out: ${_nvcc_out}")
  209. message(STATUS "Err: ${_nvcc_err}")
  210. endif()
  211. string(REGEX REPLACE ".*\n" "" ${output} "${_nvcc_out}") #Strip leading warning messages, if any
  212. if(${status} EQUAL 0)
  213. # cache detected values
  214. set(OPENCV_CACHE_CUDA_ACTIVE_CC ${${output}} CACHE INTERNAL "")
  215. set(OPENCV_CACHE_CUDA_ACTIVE_CC_check "${__cache_key_check}" CACHE INTERNAL "")
  216. endif()
  217. endif()
  218. endmacro()
  219. macro(ocv_set_cuda_arch_bin_and_ptx nvcc_executable)
  220. ocv_initialize_nvidia_device_generations()
  221. set(__cuda_arch_ptx ${CUDA_ARCH_PTX})
  222. if(CUDA_GENERATION STREQUAL "Fermi")
  223. set(__cuda_arch_bin ${_arch_fermi})
  224. elseif(CUDA_GENERATION STREQUAL "Kepler")
  225. set(__cuda_arch_bin ${_arch_kepler})
  226. elseif(CUDA_GENERATION STREQUAL "Maxwell")
  227. set(__cuda_arch_bin ${_arch_maxwell})
  228. elseif(CUDA_GENERATION STREQUAL "Pascal")
  229. set(__cuda_arch_bin ${_arch_pascal})
  230. elseif(CUDA_GENERATION STREQUAL "Volta")
  231. set(__cuda_arch_bin ${_arch_volta})
  232. elseif(CUDA_GENERATION STREQUAL "Turing")
  233. set(__cuda_arch_bin ${_arch_turing})
  234. elseif(CUDA_GENERATION STREQUAL "Ampere")
  235. set(__cuda_arch_bin ${_arch_ampere})
  236. elseif(CUDA_GENERATION STREQUAL "Lovelace")
  237. set(__cuda_arch_bin ${_arch_lovelace})
  238. elseif(CUDA_GENERATION STREQUAL "Hopper")
  239. set(__cuda_arch_bin ${_arch_hopper})
  240. elseif(CUDA_GENERATION STREQUAL "Blackwell")
  241. set(__cuda_arch_bin ${_arch_blackwell})
  242. elseif(CUDA_GENERATION STREQUAL "Auto")
  243. ocv_detect_native_cuda_arch(${nvcc_executable} _nvcc_res _nvcc_out)
  244. if(NOT _nvcc_res EQUAL 0)
  245. message(STATUS "CUDA: Automatic detection of CUDA generation failed. Going to build for all known architectures")
  246. else()
  247. string(REGEX MATCHALL "[0-9]+\\.[0-9]" __cuda_arch_bin "${_nvcc_out}")
  248. endif()
  249. elseif(CUDA_ARCH_BIN)
  250. message(STATUS "CUDA: Using CUDA_ARCH_BIN=${CUDA_ARCH_BIN}")
  251. set(__cuda_arch_bin ${CUDA_ARCH_BIN})
  252. endif()
  253. if(NOT DEFINED __cuda_arch_bin AND NOT DEFINED __cuda_arch_ptx)
  254. if(ARM)
  255. set(__cuda_arch_bin "3.2")
  256. set(__cuda_arch_ptx "")
  257. elseif(AARCH64)
  258. if(NOT CMAKE_CROSSCOMPILING)
  259. ocv_detect_native_cuda_arch(${nvcc_executable} _nvcc_res _nvcc_out)
  260. else()
  261. set(_nvcc_res -1) # emulate error, see below
  262. endif()
  263. if(NOT _nvcc_res EQUAL 0)
  264. message(STATUS "CUDA: Automatic detection of CUDA generation failed. Going to build for all known architectures")
  265. # TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0) Orin (8.7) Thor (11.0) Spark (12.1)
  266. ocv_filter_available_architecture(${nvcc_executable} __cuda_arch_bin
  267. 5.3
  268. 6.2
  269. 7.2
  270. 7.0
  271. 8.7
  272. 11.0
  273. 12.1
  274. )
  275. else()
  276. set(__cuda_arch_bin "${_nvcc_out}")
  277. endif()
  278. set(__cuda_arch_ptx "")
  279. else()
  280. ocv_filter_available_architecture(${nvcc_executable} __cuda_arch_bin
  281. ${_arch_fermi}
  282. ${_arch_kepler}
  283. ${_arch_maxwell}
  284. ${_arch_pascal}
  285. ${_arch_volta}
  286. ${_arch_turing}
  287. ${_arch_ampere}
  288. ${_arch_lovelace}
  289. ${_arch_hopper}
  290. ${_arch_blackwell}
  291. )
  292. list(GET __cuda_arch_bin -1 __cuda_arch_ptx)
  293. endif()
  294. endif()
  295. set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported (see https://docs.opencv.org/4.x/d2/dbc/cuda_intro.html)")
  296. set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for (see https://docs.opencv.org/4.x/d2/dbc/cuda_intro.html)")
  297. string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
  298. string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
  299. # Check if user specified 1.0/2.1 compute capability: we don't support it
  300. macro(ocv_wipeout_deprecated_cc target_cc)
  301. if(${target_cc} IN_LIST ARCH_BIN_NO_POINTS OR ${target_cc} IN_LIST ARCH_PTX_NO_POINTS)
  302. message(SEND_ERROR "CUDA: ${target_cc} compute capability is not supported - exclude it from ARCH/PTX list and re-run CMake")
  303. endif()
  304. endmacro()
  305. ocv_wipeout_deprecated_cc("10")
  306. ocv_wipeout_deprecated_cc("21")
  307. endmacro()
  308. macro(ocv_set_nvcc_threads_for_vs)
  309. # Tell NVCC the maximum number of threads to be used to execute the compilation steps in parallel
  310. # (option --threads was introduced in version 11.2)
  311. if(NOT CUDA_VERSION VERSION_LESS "11.2")
  312. if(CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT $ENV{CMAKE_BUILD_PARALLEL_LEVEL} STREQUAL "")
  313. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--threads=$ENV{CMAKE_BUILD_PARALLEL_LEVEL}")
  314. endif()
  315. endif()
  316. endmacro()
  317. macro(ocv_cuda_filter_options)
  318. foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
  319. set(${var}_backup_in_cuda_compile_ "${${var}}")
  320. if (CV_CLANG)
  321. # we remove -Winconsistent-missing-override and -Qunused-arguments
  322. # just in case we are compiling CUDA with gcc but OpenCV with clang
  323. string(REPLACE "-Winconsistent-missing-override" "" ${var} "${${var}}")
  324. string(REPLACE "-Qunused-arguments" "" ${var} "${${var}}")
  325. endif()
  326. # we remove /EHa as it generates warnings under windows
  327. string(REPLACE "/EHa" "" ${var} "${${var}}")
  328. # we remove -ggdb3 flag as it leads to preprocessor errors when compiling CUDA files (CUDA 4.1)
  329. string(REPLACE "-ggdb3" "" ${var} "${${var}}")
  330. # we remove -Wsign-promo as it generates warnings under linux
  331. string(REPLACE "-Wsign-promo" "" ${var} "${${var}}")
  332. # we remove -Wno-sign-promo as it generates warnings under linux
  333. string(REPLACE "-Wno-sign-promo" "" ${var} "${${var}}")
  334. # we remove -Wno-delete-non-virtual-dtor because it's used for C++ compiler
  335. # but NVCC uses C compiler by default
  336. string(REPLACE "-Wno-delete-non-virtual-dtor" "" ${var} "${${var}}")
  337. # we remove -frtti because it's used for C++ compiler
  338. # but NVCC uses C compiler by default
  339. string(REPLACE "-frtti" "" ${var} "${${var}}")
  340. string(REPLACE "-fvisibility-inlines-hidden" "" ${var} "${${var}}")
  341. # cc1: warning: command line option '-Wsuggest-override' is valid for C++/ObjC++ but not for C
  342. string(REPLACE "-Wsuggest-override" "" ${var} "${${var}}")
  343. # issue: #11552 (from OpenCVCompilerOptions.cmake)
  344. string(REGEX REPLACE "-Wimplicit-fallthrough(=[0-9]+)? " "" ${var} "${${var}}")
  345. # removal of custom specified options
  346. if(OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS)
  347. foreach(__flag ${OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS})
  348. string(REPLACE "${__flag}" "" ${var} "${${var}}")
  349. endforeach()
  350. endif()
  351. endforeach()
  352. endmacro()
  353. macro(ocv_nvcc_flags)
  354. if(BUILD_SHARED_LIBS)
  355. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler=-DCVAPI_EXPORTS)
  356. endif()
  357. if(UNIX OR APPLE)
  358. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler=-fPIC)
  359. endif()
  360. if(APPLE)
  361. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler=-fno-finite-math-only)
  362. endif()
  363. if(WIN32)
  364. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler=/wd4505)
  365. if (NOT (CUDA_VERSION VERSION_LESS "11.2"))
  366. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcudafe --display_error_number --diag-suppress 1394,1388)
  367. endif()
  368. if(CUDA_VERSION GREATER "12.8")
  369. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler=/Zc:preprocessor)
  370. endif()
  371. endif()
  372. if(CMAKE_CROSSCOMPILING AND (ARM OR AARCH64))
  373. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xlinker --unresolved-symbols=ignore-in-shared-libs)
  374. endif()
  375. # disabled because of multiple warnings during building nvcc auto generated files
  376. if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.6.0")
  377. ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-but-set-variable)
  378. endif()
  379. endmacro()
  380. macro(ocv_apply_cuda_stub_workaround cuda_driver_library_path)
  381. # details: https://github.com/NVIDIA/nvidia-docker/issues/775
  382. if(" ${cuda_driver_library_path}" MATCHES "/stubs/libcuda.so" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND)
  383. set(CUDA_STUB_ENABLED_LINK_WORKAROUND 1)
  384. if(EXISTS "${cuda_driver_library_path}" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND_RPATH_LINK)
  385. set(CUDA_STUB_TARGET_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/")
  386. execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${cuda_driver_library_path}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
  387. RESULT_VARIABLE CUDA_STUB_SYMLINK_RESULT)
  388. if(NOT CUDA_STUB_SYMLINK_RESULT EQUAL 0)
  389. execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${cuda_driver_library_path}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
  390. RESULT_VARIABLE CUDA_STUB_COPY_RESULT)
  391. if(NOT CUDA_STUB_COPY_RESULT EQUAL 0)
  392. set(CUDA_STUB_ENABLED_LINK_WORKAROUND 0)
  393. endif()
  394. endif()
  395. if(CUDA_STUB_ENABLED_LINK_WORKAROUND)
  396. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,\"${CUDA_STUB_TARGET_PATH}\"")
  397. endif()
  398. else()
  399. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined")
  400. endif()
  401. if(NOT CUDA_STUB_ENABLED_LINK_WORKAROUND)
  402. message(WARNING "CUDA: Workaround for stubs/libcuda.so.1 is not applied")
  403. endif()
  404. endif()
  405. endmacro()
  406. macro(ocv_check_cuda_delayed_load cuda_toolkit_root_dir)
  407. if(MSVC AND CUDA_ENABLE_DELAYLOAD)
  408. set(DELAYFLAGS "delayimp.lib")
  409. file(GLOB CUDA_DLLS "${cuda_toolkit_root_dir}/bin/*.dll")
  410. foreach(d ${CUDA_DLLS})
  411. cmake_path(GET "d" FILENAME DLL_NAME)
  412. if(NOT ${DLL_NAME} MATCHES "cudart")
  413. set(DELAYFLAGS "${DELAYFLAGS} /DELAYLOAD:${DLL_NAME}")
  414. endif()
  415. endforeach()
  416. set(DELAYFLAGS "${DELAYFLAGS} /DELAYLOAD:nvcuda.dll /DELAYLOAD:nvml.dll /IGNORE:4199")
  417. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${DELAYFLAGS}")
  418. set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${DELAYFLAGS}")
  419. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${DELAYFLAGS}")
  420. endif()
  421. endmacro()