From 489c52ce680df6439f9c1e553cd2925ca8944cb1 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 19 Sep 2016 13:14:47 -0400 Subject: CUDA: Use the host compiler for linking CUDA executables and shared libs. --- Modules/CMakeCUDACompiler.cmake.in | 6 +++++ Modules/CMakeCUDAInformation.cmake | 18 +++++++++++--- Modules/CMakeDetermineCUDACompiler.cmake | 42 ++++++++++++++++++++++++++++---- Modules/CMakeDetermineCompilerId.cmake | 6 ++++- Modules/Compiler/NVIDIA-CUDA.cmake | 6 +++-- Source/cmCoreTryCompile.cxx | 3 --- Source/cmLocalGenerator.cxx | 2 ++ 7 files changed, 69 insertions(+), 14 deletions(-) diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index 897fc52..7148275 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -1,4 +1,6 @@ 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@") diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index 858fee7..19bce6f 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -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=") 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_HOST_FLAGS} -o ") + " -o ${__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_HOST_FLAGS} -o ") + " -o ${__IMPLICT_LINKS}") endif() diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index d5dc9f4..9ad4fc6 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -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 diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 59d8ab6..c5a2bcb 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.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() #----------------------------------------------------------------------------- diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 6f12ff2..6b1ac74 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -1,9 +1,11 @@ -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=) diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index b1d3775..3b46fc0 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -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 const& argv, bool isTryRun) @@ -455,7 +453,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector 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)) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 1ccd489..8d81d61 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -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" }; -- cgit v0.12