blob: 86bfe31c730867008fc08c15ff9402a656b30608 [file]
# SPDX-FileCopyrightText: The Eigen Authors
# SPDX-License-Identifier: MPL-2.0
# ei_cuda_use_compiler_launcher() is the only way a compiler launcher reaches
# nvcc, because FindCUDA's cuda_add_executable() runs CUDA_NVCC_EXECUTABLE as a
# single quoted COMMAND. CMAKE_<LANG>_COMPILER_LAUNCHER is a list whose
# elements are argv entries, and an element may contain spaces, so the wrapper
# has to preserve argument boundaries rather than flatten the list into one
# line of shell source.
#
# No CUDA installation is involved: the launcher and nvcc are stand-ins that
# report the argv they were handed.
include("${EIGEN_SOURCE_DIR}/cmake/EigenTesting.cmake")
# A cmd.exe wrapper cannot be executed from a POSIX host, so its quoting rules
# are pinned on the rendering instead, on every host.
ei_quote_command_for_batch(rendered "C:/a dir/ccache.exe" "--opt=x y" "C:/cuda/nvcc.exe")
bs_assert_streq("${rendered}"
"\"C:/a dir/ccache.exe\" \"--opt=x y\" \"C:/cuda/nvcc.exe\""
"cmd.exe rendering of a launcher command")
if(CMAKE_HOST_WIN32)
return()
endif()
# Put the stand-ins under a directory whose name contains a space, so the paths
# the wrapper bakes in are quoted too, not only the launcher's own arguments.
set(bin_dir "${WORK_DIR}/fake bin")
file(MAKE_DIRECTORY "${bin_dir}")
set(fake_nvcc "${bin_dir}/fake nvcc")
file(WRITE "${fake_nvcc}" "#!/bin/sh\nfor a in \"$@\"; do echo \"nvcc-arg=[$a]\"; done\n")
execute_process(COMMAND chmod +x "${fake_nvcc}")
# Reports the one launcher argument it expects, then runs what follows it --
# which is how ccache is invoked, and what proves nvcc is still a separate argv
# entry rather than part of the launcher's.
set(fake_launcher "${bin_dir}/fake launcher")
file(WRITE "${fake_launcher}" "#!/bin/sh\necho \"launcher-arg=[$1]\"\nshift\nexec \"$@\"\n")
execute_process(COMMAND chmod +x "${fake_launcher}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${fake_launcher}" "--launcher opt")
set(CUDA_NVCC_EXECUTABLE "${fake_nvcc}")
set(CMAKE_CURRENT_BINARY_DIR "${WORK_DIR}")
ei_cuda_use_compiler_launcher()
if(CUDA_NVCC_EXECUTABLE STREQUAL "${fake_nvcc}")
bs_fail("ei_cuda_use_compiler_launcher() left CUDA_NVCC_EXECUTABLE unwrapped")
endif()
bs_run(WHAT "generated nvcc wrapper" OUTPUT_VARIABLE output
COMMAND "${CUDA_NVCC_EXECUTABLE}" "-Ia dir" "-DQ=\"a b\"" "plain")
foreach(expected "launcher-arg=[--launcher opt]"
"nvcc-arg=[-Ia dir]"
"nvcc-arg=[-DQ=\"a b\"]"
"nvcc-arg=[plain]")
string(FIND "${output}" "${expected}" position)
if(position LESS 0)
bs_fail("the wrapper did not pass through ${expected}\n----\n${output}\n----")
endif()
endforeach()