Skip to content
Snippets Groups Projects
Commit e3f404fe authored by Brad King's avatar Brad King
Browse files

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.
parent 3d3d3f94
No related branches found
No related tags found
No related merge requests found
......@@ -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()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment