diff options
author | Brad King <brad.king@kitware.com> | 2016-12-09 20:56:41 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-12-13 16:01:40 (GMT) |
commit | e3f404fe29d85c068641309c1bfbfab1e34cc6e3 (patch) | |
tree | 9e01bdbc8b381407070a42561eb0817c50a5c614 /Modules/CMakeDetermineCUDACompiler.cmake | |
parent | 3d3d3f94703e23d3d2cbff67537057474e3e0ff1 (diff) | |
download | CMake-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.cmake | 77 |
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() |