From 9f81aa0f6908785791b4a9c16331986b1dee7319 Mon Sep 17 00:00:00 2001 From: Raul Tambre Date: Sat, 22 Aug 2020 13:03:59 +0300 Subject: CUDA: Fail if compiler detection using the host compiler fails If an user specified a host compiler we should fail if we are unable to perform compiler detection with it. Previously we would try without and likely succeed and continue. Then we'd fail during ABI detection and compiler testing since we'd still try to use it. This is particularly problematic when crosscompiling since we extract the host linker from the compiler detection link line. This would result in the wrong host linker being used and a linking error due to architecture mismatch during ABI detection where other necessary flags may already be present to make the host compiler work. See #21076 for an example. Fix this by adding CMAKE__COMPILER_ID_REQUIRE_SUCCESS to CMakeDetermineCompilerId, which throws a fatal error if executing the compiler results in a non-zero exit code. Fixes #21120. --- Help/release/dev/cuda-fail-fast.rst | 5 +++++ Modules/CMakeDetermineCUDACompiler.cmake | 4 ++++ Modules/CMakeDetermineCompilerId.cmake | 9 ++++++--- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Help/release/dev/cuda-fail-fast.rst diff --git a/Help/release/dev/cuda-fail-fast.rst b/Help/release/dev/cuda-fail-fast.rst new file mode 100644 index 0000000..50bfce0 --- /dev/null +++ b/Help/release/dev/cuda-fail-fast.rst @@ -0,0 +1,5 @@ +cuda-fail-fast +-------------- + +* If ``CUDA`` compiler detection fails with user-specified + :variable:`CMAKE_CUDA_ARCHITECTURES` an error is raised. diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index daca382..85b6695 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -189,6 +189,10 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(nvcc_test_flags "--keep --keep-dir tmp") if(CMAKE_CUDA_HOST_COMPILER) string(APPEND nvcc_test_flags " -ccbin=\"${CMAKE_CUDA_HOST_COMPILER}\"") + + # If the user has specified a host compiler we should fail instead of trying without. + # Succeeding detection without may result in confusing errors later on, see #21076. + set(CMAKE_CUDA_COMPILER_ID_REQUIRE_SUCCESS ON) endif() elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") if(WIN32) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index d7a35e1..f024061 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -606,9 +606,12 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT} ") file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}") - #if(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL) - # message(FATAL_ERROR "${MSG}") - #endif() + + # Some languages may know the correct/desired set of flags and want to fail right away if they don't work. + # This is currently only used by CUDA. + if(CMAKE_${lang}_COMPILER_ID_REQUIRE_SUCCESS) + message(FATAL_ERROR "${MSG}") + endif() # No output files should be inspected. set(COMPILER_${lang}_PRODUCED_FILES) -- cgit v0.12 From 01428c5560f87122999a14fe4bf3e9b186b0127e Mon Sep 17 00:00:00 2001 From: Raul Tambre Date: Sat, 29 Aug 2020 12:44:08 +0300 Subject: CUDA: Fail fast if CMAKE_CUDA_ARCHITECTURES doesn't work during detection Also re-ordered the code to avoid testing flags for other compilers, since we know the vendor before full detection. --- Help/release/dev/cuda-fail-fast.rst | 3 ++- Modules/CMakeDetermineCUDACompiler.cmake | 37 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Help/release/dev/cuda-fail-fast.rst b/Help/release/dev/cuda-fail-fast.rst index 50bfce0..d857eb2 100644 --- a/Help/release/dev/cuda-fail-fast.rst +++ b/Help/release/dev/cuda-fail-fast.rst @@ -2,4 +2,5 @@ cuda-fail-fast -------------- * If ``CUDA`` compiler detection fails with user-specified - :variable:`CMAKE_CUDA_ARCHITECTURES` an error is raised. + :variable:`CMAKE_CUDA_ARCHITECTURES` or :variable:`CMAKE_CUDA_HOST_COMPILER` + an error is raised. diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 85b6695..6bdd06b 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -206,34 +206,35 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() endif() - # First try with the user-specified architectures. + # Append user-specified architectures. if(CMAKE_CUDA_ARCHITECTURES) - set(clang_archs "${clang_test_flags}") - set(nvcc_archs "${nvcc_test_flags}") - foreach(arch ${CMAKE_CUDA_ARCHITECTURES}) # Strip specifiers as PTX vs binary doesn't matter. string(REGEX MATCH "[0-9]+" arch_name "${arch}") - string(APPEND clang_archs " --cuda-gpu-arch=sm_${arch_name}") - string(APPEND nvcc_archs " -gencode=arch=compute_${arch_name},code=sm_${arch_name}") + string(APPEND clang_test_flags " --cuda-gpu-arch=sm_${arch_name}") + string(APPEND nvcc_test_flags " -gencode=arch=compute_${arch_name},code=sm_${arch_name}") list(APPEND tested_architectures "${arch_name}") endforeach() - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_archs}") - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${nvcc_archs}") + # If the user has specified architectures we'll want to fail during compiler detection if they don't work. + set(CMAKE_CUDA_COMPILER_ID_REQUIRE_SUCCESS ON) endif() - # Fallback default NVCC flags. - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST ${nvcc_test_flags}) - - # Clang doesn't automatically select an architecture supported by the SDK. - # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups). - foreach(arch "20" "30" "52") - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch}") - endforeach() + if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") + if(NOT CMAKE_CUDA_ARCHITECTURES) + # Clang doesn't automatically select an architecture supported by the SDK. + # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups). + foreach(arch "20" "30" "52") + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch}") + endforeach() + endif() - # Finally also try the default. - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}") + # If the user specified CMAKE_CUDA_ARCHITECTURES this will include all the architecture flags. + # Otherwise this won't include any architecture flags and we'll fallback to Clang's defaults. + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}") + elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${nvcc_test_flags}") + endif() # We perform compiler identification for a second time to extract implicit linking info and host compiler for NVCC. # We also use it to verify that CMAKE_CUDA_ARCHITECTURES and additionally on Clang that CUDA toolkit path works. -- cgit v0.12