Commit 489c52ce authored by Robert Maynard's avatar Robert Maynard

CUDA: Use the host compiler for linking CUDA executables and shared libs.

parent bbaf2434
Pipeline #35178 passed with stage
set(CMAKE_CUDA_COMPILER "@CMAKE_CUDA_COMPILER@")
set(CMAKE_CUDA_HOST_COMPILER "@CMAKE_CUDA_HOST_COMPILER@")
set(CMAKE_CUDA_HOST_LINK_LAUNCHER "@CMAKE_CUDA_HOST_LINK_LAUNCHER@")
set(CMAKE_CUDA_COMPILER_ID "@CMAKE_CUDA_COMPILER_ID@")
set(CMAKE_CUDA_COMPILER_VERSION "@CMAKE_CUDA_COMPILER_VERSION@")
set(CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT "@CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT@")
......@@ -8,6 +10,10 @@ set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
set(CMAKE_CUDA_COMPILER_ID_RUN 1)
set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "@CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES@")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES@")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "@CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES@")
set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES@")
set(CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
......@@ -60,15 +60,27 @@ include(CMakeCommonLanguageInclude)
# CMAKE_CUDA_LINK_EXECUTABLE
if(CMAKE_CUDA_HOST_COMPILER)
set(CMAKE_CUDA_HOST_FLAGS "-ccbin \"${CMAKE_CUDA_HOST_COMPILER}\" ")
set(CMAKE_CUDA_HOST_FLAGS "-ccbin=<CMAKE_CUDA_HOST_COMPILER>")
else()
set(CMAKE_CUDA_HOST_FLAGS "")
endif()
set(__IMPLICT_LINKS )
foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
string(APPEND __IMPLICT_LINKS " -L\"${dir}\"")
endforeach()
foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES})
if(${lib} MATCHES "/")
string(APPEND __IMPLICT_LINKS " \"${lib}\"")
else()
string(APPEND __IMPLICT_LINKS " -l${lib}")
endif()
endforeach()
# create a shared library
if(NOT CMAKE_CUDA_CREATE_SHARED_LIBRARY)
set(CMAKE_CUDA_CREATE_SHARED_LIBRARY
"<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
"<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
endif()
# create a shared module copy the shared library rule by default
......@@ -110,7 +122,7 @@ endif()
# compile a cu file into an executable
if(NOT CMAKE_CUDA_LINK_EXECUTABLE)
set(CMAKE_CUDA_LINK_EXECUTABLE
"<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> <CMAKE_CUDA_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
"<CMAKE_CUDA_HOST_LINK_LAUNCHER> <CMAKE_CUDA_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
endif()
......
......@@ -2,6 +2,7 @@
# file Copyright.txt or https://cmake.org/licensing for details.
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake)
if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
("${CMAKE_GENERATOR}" MATCHES "Ninja") ) )
......@@ -43,12 +44,9 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCUDA/(\\./)?(CompilerIdCUDA.xctest/)?CompilerIdCUDA[ \t\n\\\"]")
set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v")
if(CMAKE_CUDA_HOST_COMPILER)
# Each entry in this list is a set of extra flags to try
# adding to the compile line to see if it helps produce
# a valid identification file. In our case this would just
# be the explicit host compiler
set(CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "-ccbin=${CMAKE_CUDA_HOST_COMPILER}")
list(APPEND CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-ccbin=${CMAKE_CUDA_HOST_COMPILER}")
endif()
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
......@@ -57,6 +55,40 @@ endif()
include(CMakeFindBinUtils)
#if this compiler vendor is matches NVIDIA we can determine
#what the host compiler is. This only needs to be done if the CMAKE_CUDA_HOST_COMPILER
#has NOT been explicitly set
#
#Find the line from compiler ID that contains a.out ( or last line )
#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")
endif()
# configure all variables set in this file
configure_file(${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeCUDACompiler.cmake
......
......@@ -101,6 +101,8 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
endfunction()
include(CMakeCompilerIdDetection)
......@@ -135,7 +137,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src)
set(COMPILER_DESCRIPTION
"Compiler: ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1}
Build flags: ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
Id flags: ${testflags}
Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
")
# Compile the compiler identification source.
......@@ -322,6 +324,7 @@ Id flags: ${testflags}
${CMAKE_${lang}_COMPILER_ID_ARG1}
${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
${testflags}
${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
"${src}"
WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
......@@ -400,6 +403,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
# Return the files produced by the compilation.
set(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
set(COMPILER_${lang}_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
......
set(CMAKE_CUDA_VERBOSE_FLAG "-v -Xcompiler=-v")
set(CMAKE_CUDA_VERBOSE_FLAG "-v")
set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE)
set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC)
set(CMAKE_SHARED_LIBRARY_CUDA_FLAGS -Xcompiler=-fPIC)
#CMAKE_SHARED_LIBRARY_CUDA_FLAGS is sent to the host linker so we don' need
#to forward it through nvcc
set(CMAKE_SHARED_LIBRARY_CUDA_FLAGS -fPIC)
set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
set(CMAKE_CUDA_COMPILE_OPTIONS_VISIBILITY -Xcompiler=-fvisibility=)
......
......@@ -44,8 +44,6 @@ static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
"CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
static std::string const kCMAKE_CUDA_HOST_COMPILER =
"CMAKE_CUDA_HOST_COMPILER";
int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
bool isTryRun)
......@@ -455,7 +453,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_OSX_SYSROOT);
vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE);
vars.insert(kCMAKE_SYSROOT);
vars.insert(kCMAKE_CUDA_HOST_COMPILER);
if (const char* varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
......
......@@ -63,6 +63,8 @@ static const char* ruleReplaceVars[] = {
"CMAKE_CURRENT_BINARY_DIR",
"CMAKE_RANLIB",
"CMAKE_LINKER",
"CMAKE_CUDA_HOST_COMPILER",
"CMAKE_CUDA_HOST_LINK_LAUNCHER",
"CMAKE_CL_SHOWINCLUDES_PREFIX"
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment