From 4468acb979d04fc422a1c78a89c24a26b35f3629 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 21 May 2020 10:05:09 -0400 Subject: CUDA: Factor runtime library lookup into helper method --- Source/cmComputeLinkInformation.cxx | 39 ++++++++++--------------------- Source/cmGeneratorTarget.cxx | 19 +++++++++++++++ Source/cmGeneratorTarget.h | 3 +++ Source/cmVisualStudioGeneratorOptions.cxx | 23 +++++++----------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index ea7ede4..8723d08 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -12,7 +12,6 @@ #include #include "cmComputeLinkDepends.h" -#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmListFileCache.h" @@ -587,32 +586,18 @@ void cmComputeLinkInformation::AddImplicitLinkInfo() } void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang) -{ // Add the lang runtime library flags. This is activated by the presence - // of a default selection whether or not it is overridden by a property. - std::string defaultVar = - cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT"); - cmProp langRuntimeLibraryDefault = this->Makefile->GetDef(defaultVar); - if (langRuntimeLibraryDefault && !langRuntimeLibraryDefault->empty()) { - cmProp runtimeLibraryValue = - this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY")); - if (!runtimeLibraryValue) { - runtimeLibraryValue = langRuntimeLibraryDefault; - } - - std::string runtimeLibrary = - cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( - *runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config, - this->Target)); - if (!runtimeLibrary.empty()) { - if (const char* runtimeLinkOptions = this->Makefile->GetDefinition( - "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + - runtimeLibrary)) { - std::vector libsVec = cmExpandedList(runtimeLinkOptions); - for (std::string const& i : libsVec) { - if (!cm::contains(this->ImplicitLinkLibs, i)) { - this->AddItem(i, nullptr); - } - } +{ + std::string const& runtimeLibrary = + this->Target->GetRuntimeLinkLibrary(lang, this->Config); + if (runtimeLibrary.empty()) { + return; + } + if (const char* runtimeLinkOptions = this->Makefile->GetDefinition( + "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + runtimeLibrary)) { + std::vector libsVec = cmExpandedList(runtimeLinkOptions); + for (std::string const& i : libsVec) { + if (!cm::contains(this->ImplicitLinkLibs, i)) { + this->AddItem(i, nullptr); } } } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 917985a..f2a51ab 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5710,6 +5710,25 @@ void cmGeneratorTarget::GetTargetVersion(const std::string& property, } } +std::string cmGeneratorTarget::GetRuntimeLinkLibrary( + std::string const& lang, std::string const& config) const +{ + // This is activated by the presence of a default selection whether or + // not it is overridden by a property. + cmProp runtimeLibraryDefault = this->Makefile->GetDef( + cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT")); + if (!runtimeLibraryDefault || runtimeLibraryDefault->empty()) { + return std::string(); + } + cmProp runtimeLibraryValue = + this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY")); + if (!runtimeLibraryValue) { + runtimeLibraryValue = runtimeLibraryDefault; + } + return cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( + *runtimeLibraryValue, this->LocalGenerator, config, this)); +} + std::string cmGeneratorTarget::GetFortranModuleDirectory( std::string const& working_dir) const { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index c8732bc..788fa23 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -783,6 +783,9 @@ public: const std::string& fallback_property, int& major, int& minor, int& patch) const; + std::string GetRuntimeLinkLibrary(std::string const& lang, + std::string const& config) const; + std::string GetFortranModuleDirectory(std::string const& working_dir) const; const std::string& GetSourcesProperty() const; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 7775f62..88ca92d 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -157,21 +157,14 @@ void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target) this->FlagMap.find("CudaRuntime"); if (i == this->FlagMap.end()) { // User didn't provide am override so get the property value - cmProp runtimeLibraryValue = target->GetProperty("CUDA_RUNTIME_LIBRARY"); - if (runtimeLibraryValue) { - std::string cudaRuntime = - cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate( - *runtimeLibraryValue, this->LocalGenerator, this->Configuration, - target)); - if (cudaRuntime == "STATIC") { - this->AddFlag("CudaRuntime", "Static"); - } - if (cudaRuntime == "SHARED") { - this->AddFlag("CudaRuntime", "Shared"); - } - if (cudaRuntime == "NONE") { - this->AddFlag("CudaRuntime", "None"); - } + std::string const& cudaRuntime = + target->GetRuntimeLinkLibrary("CUDA", this->Configuration); + if (cudaRuntime == "STATIC") { + this->AddFlag("CudaRuntime", "Static"); + } else if (cudaRuntime == "SHARED") { + this->AddFlag("CudaRuntime", "Shared"); + } else if (cudaRuntime == "NONE") { + this->AddFlag("CudaRuntime", "None"); } else { // nvcc default is static this->AddFlag("CudaRuntime", "Static"); -- cgit v0.12 From 5c7ca6f8a87f8c673088103a4d00a176f8cd93fe Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 22 May 2020 07:01:55 -0400 Subject: CUDA: Move VS CudaRuntime selection to be with rest of CUDA options --- Source/cmVisualStudio10TargetGenerator.cxx | 15 +++++++++++---- Source/cmVisualStudioGeneratorOptions.cxx | 21 --------------------- Source/cmVisualStudioGeneratorOptions.h | 1 - 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 97f7093..de88182 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3130,6 +3130,17 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddIncludes(this->GetIncludes(configName, "CUDA")); cudaOptions.AddFlag("UseHostInclude", "false"); + // Add runtime library selection flag. + std::string const& cudaRuntime = + this->GeneratorTarget->GetRuntimeLinkLibrary("CUDA", configName); + if (cudaRuntime == "STATIC") { + cudaOptions.AddFlag("CudaRuntime", "Static"); + } else if (cudaRuntime == "SHARED") { + cudaOptions.AddFlag("CudaRuntime", "Shared"); + } else if (cudaRuntime == "NONE") { + cudaOptions.AddFlag("CudaRuntime", "None"); + } + this->CudaOptions[configName] = std::move(pOptions); return true; } @@ -3644,10 +3655,6 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( std::vector libVec; std::vector vsTargetVec; this->AddLibraries(cli, libVec, vsTargetVec, config); - if (cm::contains(linkClosure->Languages, "CUDA") && - this->CudaOptions[config] != nullptr) { - this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget); - } std::string standardLibsVar = cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"); std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar); diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 88ca92d..937b4ce 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -151,27 +151,6 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const return false; } -void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target) -{ - std::map::const_iterator i = - this->FlagMap.find("CudaRuntime"); - if (i == this->FlagMap.end()) { - // User didn't provide am override so get the property value - std::string const& cudaRuntime = - target->GetRuntimeLinkLibrary("CUDA", this->Configuration); - if (cudaRuntime == "STATIC") { - this->AddFlag("CudaRuntime", "Static"); - } else if (cudaRuntime == "SHARED") { - this->AddFlag("CudaRuntime", "Shared"); - } else if (cudaRuntime == "NONE") { - this->AddFlag("CudaRuntime", "None"); - } else { - // nvcc default is static - this->AddFlag("CudaRuntime", "Static"); - } - } -} - void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() { // Extract temporary values stored by our flag table. diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index b335694..f9b50a7 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -63,7 +63,6 @@ public: bool UsingSBCS() const; void FixCudaCodeGeneration(); - void FixCudaRuntime(cmGeneratorTarget* target); void FixManifestUACFlags(); -- cgit v0.12 From 16bed00712a01371fd0d871ca8ce786381f457cb Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 22 May 2020 07:36:17 -0400 Subject: CUDA: Refactor implicit library filtering Filter CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES just after it is computed. Re-use the same exclusion list for filtering CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES to avoid duplication. --- Modules/CMakeDetermineCUDACompiler.cmake | 18 ++++++++++++++++++ Modules/CMakeTestCUDACompiler.cmake | 18 +++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 427e5b5..2fc7a82 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -269,6 +269,24 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") endif() endif() +# CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES is detected above as the list of +# libraries that the CUDA compiler implicitly passes to the host linker. +# CMake invokes the host linker directly and so needs to pass these libraries. +# We filter out those that should not be passed unconditionally both here +# and from CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES in CMakeTestCUDACompiler. +set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE + # The CUDA runtime libraries are controlled by CMAKE_CUDA_RUNTIME_LIBRARY. + cudart + cudart_static + cudadevrt + + # Dependencies of the CUDA static runtime library on Linux hosts. + rt + pthread + dl + ) +list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) + if(CMAKE_CUDA_COMPILER_SYSROOT) string(CONCAT _SET_CMAKE_CUDA_COMPILER_SYSROOT "set(CMAKE_CUDA_COMPILER_SYSROOT \"${CMAKE_CUDA_COMPILER_SYSROOT}\")\n" diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index b3b62bd..6d39d3e 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -67,21 +67,9 @@ else() set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}") endif() - # Remove the following libraries from CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES and - # CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES - # - # - cudart - # - cudart_static - # - cudadevrt - # - # Additionally on Linux: - # - rt - # - pthread - # - dl - # - # These are controlled by CMAKE_CUDA_RUNTIME_LIBRARY - list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt rt pthread dl) - list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt rt pthread dl) + # Filter out implicit link libraries that should not be passed unconditionally. + # See CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE in CMakeDetermineCUDACompiler. + list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") # Remove the CUDA Toolkit include directories from the set of -- cgit v0.12 From 23519dd24fc3f6c1c0f80fd57aa99fea1d869962 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 22 May 2020 07:38:42 -0400 Subject: CUDA: Fix implicit runtime library filtering on Windows The CUDA runtime library names may have a `.lib` suffix. Exclude those too. --- Modules/CMakeDetermineCUDACompiler.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 2fc7a82..f115daa 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -276,9 +276,9 @@ endif() # and from CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES in CMakeTestCUDACompiler. set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE # The CUDA runtime libraries are controlled by CMAKE_CUDA_RUNTIME_LIBRARY. - cudart - cudart_static - cudadevrt + cudart cudart.lib + cudart_static cudart_static.lib + cudadevrt cudadevrt.lib # Dependencies of the CUDA static runtime library on Linux hosts. rt -- cgit v0.12 From bcb44ac2ee0609b701fef84bcc333fda9b1c02b9 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 22 May 2020 07:48:19 -0400 Subject: CUDA: Simplify Clang implicit host linker settings The purpose of `CMAKE_CUDA_HOST_IMPLICIT_LINK_*` is to capture the extra link libraries and directories that the CUDA compiler passes when invoking the host linker. We need this when using NVCC because CMake drives the host linker directly rather than through NVCC. However, this is not needed with Clang because: * Clang does not pass any CUDA libraries automatically. * We drive linking with the Clang compiler anyway. Drop the detection logic for Clang because it only gives the normal C++ runtime libraries which we do not need here. --- Modules/CMakeDetermineCUDACompiler.cmake | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index f115daa..4a8a268 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -137,22 +137,14 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") endif() endif() - # Parsing implicit host linker info is as simple as for regular Clang. - CMAKE_PARSE_IMPLICIT_LINK_INFO("${CMAKE_CUDA_COMPILER_PRODUCED_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}") - - # Get SDK directory. - string(REGEX MATCH "Found CUDA installation: (.+), version" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - set(__cuda_directory "${CMAKE_MATCH_1}") - - # Clang doesn't add the SDK library directory to the implicit link path. Do it ourselves, so stuff works. + # Clang does not add any CUDA SDK libraries or directories when invoking the host linker. + # Add the CUDA toolkit library directory ourselves so that linking works. + # The CUDA runtime libraries are handled elsewhere by CMAKE_CUDA_RUNTIME_LIBRARY. include(Internal/CUDAToolkit) set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${CUDAToolkit_INCLUDE_DIR}") - list(APPEND CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${CUDAToolkit_LIBRARY_DIR}") + set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${CUDAToolkit_LIBRARY_DIR}") + set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "") + set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") set(_nvcc_log "") string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") -- cgit v0.12