From 7f15c998519d83d49b16887c4e035336378d854b Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 29 Nov 2019 11:16:21 -0500 Subject: CUDA: forward unknown flags to host compiler when possible. Starting with CUDA 10.2 the nvcc compiler has gained support to automatically forward unknown flags to the host compiler. This behavior is highly desired as projcts that mix CUDA, C, C++ run into situation where flags such as `-pthread` which aren't supported by nvcc, are being applied to all source files and therefore break CUDA compilation. --- Modules/CMakeCUDAInformation.cmake | 24 ++++++++---------------- Modules/Compiler/NVIDIA-CUDA.cmake | 16 ++++++++++++++++ Modules/Platform/Windows-NVIDIA-CUDA.cmake | 17 +++++------------ 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index b0d80d1..e140808 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -93,9 +93,7 @@ include(CMakeCommonLanguageInclude) # CMAKE_CUDA_LINK_EXECUTABLE if(CMAKE_CUDA_HOST_COMPILER) - set(CMAKE_CUDA_HOST_FLAGS "-ccbin=") -else() - set(CMAKE_CUDA_HOST_FLAGS "") + string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=") endif() set(__IMPLICT_LINKS ) @@ -135,24 +133,24 @@ endif() #Specify how to compile when ptx has been requested if(NOT CMAKE_CUDA_COMPILE_PTX_COMPILATION) set(CMAKE_CUDA_COMPILE_PTX_COMPILATION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -ptx -o ") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -ptx -o ") endif() #Specify how to compile when separable compilation has been requested if(NOT CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION) set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -dc -o ") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -dc -o ") endif() #Specify how to compile when whole compilation has been requested if(NOT CMAKE_CUDA_COMPILE_WHOLE_COMPILATION) set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -c -o ") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -c -o ") endif() if(CMAKE_GENERATOR STREQUAL "Ninja") set(CMAKE_CUDA_COMPILE_DEPENDENCY_DETECTION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -M -MT -o $DEP_FILE") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -M -MT -o $DEP_FILE") #The Ninja generator uses the make file dependency files to determine what #files need to be recompiled. Unfortunately, nvcc doesn't support building #a source file and generating the dependencies of said file in a single @@ -171,13 +169,6 @@ if(NOT CMAKE_CUDA_LINK_EXECUTABLE) " -o ${__IMPLICT_LINKS}") endif() -if( CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" AND - CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") -else() - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") -endif() - # Add implicit host link directories that contain device libraries # to the device link line. set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) @@ -192,14 +183,15 @@ foreach(dir ${__IMPLICT_DLINK_DIRS}) endforeach() unset(__IMPLICT_DLINK_DIRS) + #These are used when linking relocatable (dc) cuda code if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - " ${CMAKE_CUDA_HOST_FLAGS} ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o ${__IMPLICT_DLINK_FLAGS}") + " ${_CMAKE_CUDA_EXTRA_FLAGS} ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o ${__IMPLICT_DLINK_FLAGS}") endif() if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE) set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - " ${CMAKE_CUDA_HOST_FLAGS} ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o ${__IMPLICT_DLINK_FLAGS}") + " ${_CMAKE_CUDA_EXTRA_FLAGS} ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o ${__IMPLICT_DLINK_FLAGS}") endif() unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS) diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index b59deda..2400a9d 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -2,6 +2,22 @@ set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True) set(CMAKE_CUDA_VERBOSE_FLAG "-v") set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v") +if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 10.2) + # The -forward-unknown-to-host-compiler flag was only + # added to nvcc in 10.2 so before that we had no good + # way to invoke the CUDA compiler and propagate unknown + # flags such as -pthread to the host compiler + set(_CMAKE_CUDA_EXTRA_FLAGS "-forward-unknown-to-host-compiler") +else() + set(_CMAKE_CUDA_EXTRA_FLAGS "") +endif() + +if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") + set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") +else() + set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") +endif() + if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 94d77b9..30b5aa9 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -1,11 +1,11 @@ include(Platform/Windows-MSVC) set(CMAKE_CUDA_COMPILE_PTX_COMPILATION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -ptx -o -Xcompiler=-Fd,-FS") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -ptx -o -Xcompiler=-Fd,-FS") set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -dc -o -Xcompiler=-Fd,-FS") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -dc -o -Xcompiler=-Fd,-FS") set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION - " ${CMAKE_CUDA_HOST_FLAGS} -x cu -c -o -Xcompiler=-Fd,-FS") + " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -c -o -Xcompiler=-Fd,-FS") set(__IMPLICT_LINKS ) foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) @@ -30,11 +30,6 @@ set(CMAKE_CUDA_LINK_EXECUTABLE unset(_CMAKE_VS_LINK_EXE) unset(_CMAKE_VS_LINK_EXE) -if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") -else() - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") -endif() # Add implicit host link directories that contain device libraries # to the device link line. @@ -51,11 +46,9 @@ endforeach() unset(__IMPLICT_DLINK_DIRS) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - " ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o -Xcompiler=-Fd,-FS${__IMPLICT_DLINK_FLAGS}") + " ${_CMAKE_CUDA_EXTRA_FLAGS} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o -Xcompiler=-Fd,-FS${__IMPLICT_DLINK_FLAGS}") set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - " ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o -Xcompiler=-Fd,-FS${__IMPLICT_DLINK_FLAGS}") - -unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS) + " ${_CMAKE_CUDA_EXTRA_FLAGS} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink -o -Xcompiler=-Fd,-FS${__IMPLICT_DLINK_FLAGS}") unset(__IMPLICT_DLINK_FLAGS) string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}") -- cgit v0.12 From 5341f5e4a117c7b42f52250b9d66db2f6ca67724 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 29 Nov 2019 12:07:31 -0500 Subject: CUDA: get header deps from compiler invocation when possible Before CUDA 10.2 `nvcc` didn't support providing header dependency information while compiling. --- Modules/CMakeCUDAInformation.cmake | 4 ++-- Modules/Compiler/NVIDIA-CUDA.cmake | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index e140808..028fa13 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -148,11 +148,11 @@ if(NOT CMAKE_CUDA_COMPILE_WHOLE_COMPILATION) " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -c -o ") endif() -if(CMAKE_GENERATOR STREQUAL "Ninja") +if(CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_DEPFILE_FLAGS_CUDA ) set(CMAKE_CUDA_COMPILE_DEPENDENCY_DETECTION " ${_CMAKE_CUDA_EXTRA_FLAGS} -x cu -M -MT -o $DEP_FILE") #The Ninja generator uses the make file dependency files to determine what - #files need to be recompiled. Unfortunately, nvcc doesn't support building + #files need to be recompiled. Unfortunately, nvcc < 10.2 doesn't support building #a source file and generating the dependencies of said file in a single #invocation. Instead we have to state that you need to chain two commands. # diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 2400a9d..2b24fa5 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -18,6 +18,13 @@ else() set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") endif() +if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 10.2) + # The -MD flag was only added to nvcc in 10.2 so + # before that we had to invoke the compiler twice + # to get header dependency information + set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT -MF ") +endif() + if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) -- cgit v0.12