Skip to content

Commit

Permalink
build: first class cuda support
Browse files Browse the repository at this point in the history
  • Loading branch information
cudawarped committed Aug 26, 2023
1 parent 588ddf1 commit aff1fb0
Show file tree
Hide file tree
Showing 11 changed files with 708 additions and 28 deletions.
31 changes: 31 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW) # CMake 3.13+: option() honors normal variables.
endif()

if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW) # CMake 3.15+: leave MSVC runtime selection out of default CMAKE_<LANG>_FLAGS_<CONFIG> flags
endif()

if(POLICY CMP0146)
cmake_policy(SET CMP0146 OLD) # CMake 3.27+: use CMake FindCUDA if available.
endif()
Expand Down Expand Up @@ -546,6 +550,9 @@ OCV_OPTION(OPENCV_ENABLE_MEMALIGN "Enable posix_memalign or memalign usage"
OCV_OPTION(OPENCV_DISABLE_FILESYSTEM_SUPPORT "Disable filesystem support" OFF)
OCV_OPTION(OPENCV_DISABLE_THREAD_SUPPORT "Build the library without multi-threaded code." OFF)
OCV_OPTION(OPENCV_SEMIHOSTING "Build the library for semihosting target (Arm). See https://developer.arm.com/documentation/100863/latest." OFF)
OCV_OPTION(ENABLE_CUDA_FIRST_CLASS_LANGUAGE "Enable CUDA as a first class language, if enabled dependant projects will need to use CMake >= 3.18" (WITH_CUDA AND NOT CMAKE_VERSION VERSION_LESS 3.18)
VISIBLE_IF (WITH_CUDA AND NOT CMAKE_VERSION VERSION_LESS 3.18)
VERIFY HAVE_CUDA)

OCV_OPTION(ENABLE_PYLINT "Add target with Pylint checks" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
OCV_OPTION(ENABLE_FLAKE8 "Add target with Python flake8 checker" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
Expand Down Expand Up @@ -654,6 +661,30 @@ include(cmake/OpenCVCompilerOptions.cmake)

ocv_cmake_hook(POST_COMPILER_OPTIONS)

# --- CUDA Support ---
if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE)
if(CMAKE_VERSION VERSION_LESS 3.18)
message(WARNING "CUDA first class language only supported for CMake versions >= 3.18, falling back to FindCUDA!")
set(ENABLE_CUDA_FIRST_CLASS_LANGUAGE OFF CACHE BOOL "Enable CUDA as a first class language, if enabled dependant projects will need to use CMake >= 3.18" FORCE)
else()
if(UNIX AND CUDA_PATH AND NOT $ENV{CUDA_PATH})
set(ENV{CUDA_PATH} ${CUDA_PATH})
elseif(WIN32 AND CUDA_PATH)
set(ENV{PATH} "${CUDA_PATH}\\bin\;$ENV{PATH}")
endif()
include(CheckLanguage)
check_language(CUDA)
# Checking windows default search location isn't possible because the CUDA Toolkit is installed to C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/vXX.X
if(UNIX AND NOT CMAKE_CUDA_COMPILER)
message(STATUS "Checking for CUDA compiler in default location (/usr/local/cuda)")
set(CUDA_PATH "/usr/local/cuda" CACHE INTERNAL "")
set(ENV{CUDA_PATH} ${CUDA_PATH})
endif()
cmake_policy(SET CMP0092 NEW) # CMake 3.15+: leave warning flags out of default CMAKE_<LANG>_FLAGS flags.
enable_language(CUDA)
endif()
endif()

# ----------------------------------------------------------------------------
# CHECK FOR SYSTEM LIBRARIES, OPTIONS, ETC..
# ----------------------------------------------------------------------------
Expand Down
58 changes: 34 additions & 24 deletions cmake/OpenCVCRTLinkage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,44 @@ endif()
# Ignore warning: This object file does not define any previously undefined public symbols, ...
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")

if(POLICY CMP0091)
cmake_policy(GET CMP0091 MSVC_RUNTIME_SET_BY_ABSTRACTION)
endif()

if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif()
if(${flag_var} MATCHES "/MDd")
string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
if(MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
else()
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif()
if(${flag_var} MATCHES "/MDd")
string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
endif()

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:atlthunk.lib")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:msvcrt.lib")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:msvcrtd.lib")
else()
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
endif()
if(${flag_var} MATCHES "/MTd")
string(REGEX REPLACE "/MTd" "/MDd" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
if(NOT MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
endif()
if(${flag_var} MATCHES "/MTd")
string(REGEX REPLACE "/MTd" "/MDd" ${flag_var} "${${flag_var}}")
endif()
endforeach(flag_var)
endif()
endif()
17 changes: 17 additions & 0 deletions cmake/OpenCVDetectCUDA.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,25 @@ if(CUDA_FOUND)
endforeach()
endmacro()

macro(ocv_check_windows_crt_linkage)
# The new MSVC runtime abstraction is only useable if CUDA is a first class language
if(WIN32 AND POLICY CMP0091)
cmake_policy(GET CMP0091 MSVC_RUNTIME_SET_BY_ABSTRACTION)
if(MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
if(BUILD_SHARED_LIBS)
set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} " /MD")
set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} " /MDd")
else()
set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} " /MT")
set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} " /MTd")
endif()
endif()
endif()
endmacro()

macro(ocv_cuda_compile VAR)
ocv_cuda_filter_options()
ocv_check_windows_crt_linkage()

if(BUILD_SHARED_LIBS)
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -DCVAPI_EXPORTS)
Expand Down

0 comments on commit aff1fb0

Please sign in to comment.