summaryrefslogtreecommitdiffstats
path: root/Modules/CMakeDetermineCUDACompiler.cmake
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-12-09 20:56:41 (GMT)
committerBrad King <brad.king@kitware.com>2016-12-13 16:01:40 (GMT)
commite3f404fe29d85c068641309c1bfbfab1e34cc6e3 (patch)
tree9e01bdbc8b381407070a42561eb0817c50a5c614 /Modules/CMakeDetermineCUDACompiler.cmake
parent3d3d3f94703e23d3d2cbff67537057474e3e0ff1 (diff)
downloadCMake-e3f404fe29d85c068641309c1bfbfab1e34cc6e3.zip
CMake-e3f404fe29d85c068641309c1bfbfab1e34cc6e3.tar.gz
CMake-e3f404fe29d85c068641309c1bfbfab1e34cc6e3.tar.bz2
CUDA: Implement nvcc implicit link line extraction more robustly
Do not assume that the implicit link line is the last line of the output from `nvcc -v`. Instead first find the `LIBRARIES=` line, and then look for that content on a later line. It appears twice. First on a call to `nvlink`, which we ignore. Later it appears on the implicit link line. Extract the latter line. On failure, abort with a `FATAL_ERROR` so that the user does not try to build without proper link information. Once we have the line, parse it with `separate_arguments` using the `UNIX_COMMAND` option just like `CMakeParseImplicitLinkInfo` already does. This robustly parses the command line and removes quoting. Then extract the first argument as the host link launcher.
Diffstat (limited to 'Modules/CMakeDetermineCUDACompiler.cmake')
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake77
1 files changed, 54 insertions, 23 deletions
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 419f3a5..e03de7e 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -79,29 +79,60 @@ include(CMakeFindBinUtils)
#We also need to find the implicit link lines. Which can be done by replacing
#the compiler with cuda-fake-ld and pass too CMAKE_PARSE_IMPLICIT_LINK_INFO
if(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
- #grab the last line of the output which holds the link line
- string(REPLACE "#\$ " ";" nvcc_output "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
- list(GET nvcc_output -1 nvcc_output)
-
- #extract the compiler that is being used for linking
- string(REPLACE " " ";" nvcc_output_to_find_launcher "${nvcc_output}")
- list(GET nvcc_output_to_find_launcher 0 CMAKE_CUDA_HOST_LINK_LAUNCHER)
- #we need to remove the quotes that nvcc adds around the directory section
- #of the path
- string(REPLACE "\"" "" CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_CUDA_HOST_LINK_LAUNCHER}")
-
- #prefix the line with cuda-fake-ld so that implicit link info believes it is
- #a link line
- set(nvcc_output "cuda-fake-ld ${nvcc_output}")
- CMAKE_PARSE_IMPLICIT_LINK_INFO("${nvcc_output}"
- CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES
- CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES
- CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
- log
- "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}")
-
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Parsed CUDA nvcc implicit link information from above output:\n${log}\n\n")
+ set(_nvcc_log "")
+ string(REPLACE "\r" "" _nvcc_output "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+ if(_nvcc_output MATCHES "#\\\$ +LIBRARIES= *([^\n]*)\n")
+ set(_nvcc_libraries "${CMAKE_MATCH_1}")
+ string(APPEND _nvcc_log " found 'LIBRARIES=' string: [${_nvcc_libraries}]\n")
+ else()
+ set(_nvcc_libraries "")
+ string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output}")
+ string(APPEND _nvcc_log " no 'LIBRARIES=' string found in nvcc output:${_nvcc_output_log}\n")
+ endif()
+
+ set(_nvcc_link_line "")
+ if(_nvcc_libraries)
+ # Remove variable assignments.
+ string(REGEX REPLACE "#\\\$ *[^= ]+=[^\n]*\n" "" _nvcc_output "${_nvcc_output}")
+ # Split lines.
+ string(REGEX REPLACE "\n+(#\\\$ )?" ";" _nvcc_output "${_nvcc_output}")
+ foreach(line IN LISTS _nvcc_output)
+ set(_nvcc_output_line "${line}")
+ string(APPEND _nvcc_log " considering line: [${_nvcc_output_line}]\n")
+ if("${_nvcc_output_line}" MATCHES "^ *nvlink")
+ string(APPEND _nvcc_log " ignoring nvlink line\n")
+ elseif(_nvcc_libraries)
+ string(FIND "${_nvcc_output_line}" "${_nvcc_libraries}" _nvcc_libraries_pos)
+ if(NOT _nvcc_libraries_pos EQUAL -1)
+ set(_nvcc_link_line "${_nvcc_output_line}")
+ string(APPEND _nvcc_log " extracted link line: [${_nvcc_link_line}]\n")
+ endif()
+ endif()
+ endforeach()
+ endif()
+
+ if(_nvcc_link_line)
+ #extract the compiler that is being used for linking
+ separate_arguments(_nvcc_link_line_args UNIX_COMMAND "${_nvcc_link_line}")
+ list(GET _nvcc_link_line_args 0 CMAKE_CUDA_HOST_LINK_LAUNCHER)
+
+ #prefix the line with cuda-fake-ld so that implicit link info believes it is
+ #a link line
+ set(_nvcc_link_line "cuda-fake-ld ${_nvcc_link_line}")
+ CMAKE_PARSE_IMPLICIT_LINK_INFO("${_nvcc_link_line}"
+ CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES
+ CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES
+ CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+ log
+ "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}")
+
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Parsed CUDA nvcc implicit link information from above output:\n${_nvcc_log}\n${log}\n\n")
+ else()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Failed to parsed CUDA nvcc implicit link information:\n${_nvcc_log}\n\n")
+ message(FATAL_ERROR "Failed to extract nvcc implicit link line.")
+ endif()
endif()