diff options
-rw-r--r-- | Source/cmLinkLineDeviceComputer.cxx | 97 | ||||
-rw-r--r-- | Source/cmLinkLineDeviceComputer.h | 6 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 18 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 51 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 30 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 18 | ||||
-rwxr-xr-x | bootstrap | 1 |
7 files changed, 113 insertions, 108 deletions
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 72edba3..6cfe5bb 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -3,14 +3,20 @@ #include "cmLinkLineDeviceComputer.h" +#include <algorithm> #include <set> #include <sstream> #include <utility> +#include <vector> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" +#include "cmLocalGenerator.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmSystemTools.h" class cmOutputConverter; @@ -40,6 +46,27 @@ static bool cmLinkItemValidForDevice(std::string const& item) cmHasLiteralPrefix(item, "--library")); } +bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( + cmComputeLinkInformation& cli) +{ + // Determine if this item might requires device linking. + // For this we only consider targets + typedef cmComputeLinkInformation::ItemVector ItemVector; + ItemVector const& items = cli.GetItems(); + std::string config = cli.GetConfig(); + for (auto const& item : items) { + if (item.Target && + item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) { + if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) && + item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + // this dependency requires us to device link it + return true; + } + } + } + return false; +} + std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( cmComputeLinkInformation& cli, std::string const& stdLibString) { @@ -62,17 +89,12 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } if (item.Target) { - bool skip = false; - switch (item.Target->GetType()) { - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::INTERFACE_LIBRARY: - skip = true; - break; - case cmStateEnums::STATIC_LIBRARY: - skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); - break; - default: - break; + bool skip = true; + if (item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) { + if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) && + item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + skip = false; + } } if (skip) { continue; @@ -116,3 +138,56 @@ std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*, { return "CUDA"; } + +bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, + const std::string& config) +{ + + if (target.GetType() == cmStateEnums::OBJECT_LIBRARY) { + return false; + } + + if (const char* resolveDeviceSymbols = + target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { + // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need + // to honor the value no matter what it is. + return cmSystemTools::IsOn(resolveDeviceSymbols); + } + + if (const char* separableCompilation = + target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { + if (cmSystemTools::IsOn(separableCompilation)) { + bool doDeviceLinking = false; + switch (target.GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::EXECUTABLE: + doDeviceLinking = true; + break; + default: + break; + } + return doDeviceLinking; + } + } + + // Determine if we have any dependencies that require + // us to do a device link step + const std::string cuda_lang("CUDA"); + cmGeneratorTarget::LinkClosure const* closure = + target.GetLinkClosure(config); + + bool closureHasCUDA = + (std::find(closure->Languages.begin(), closure->Languages.end(), + cuda_lang) != closure->Languages.end()); + if (closureHasCUDA) { + cmComputeLinkInformation* pcli = target.GetLinkInformation(config); + if (pcli) { + cmLinkLineDeviceComputer deviceLinkComputer( + &lg, lg.GetStateSnapshot().GetDirectory()); + return deviceLinkComputer.ComputeRequiresDeviceLinking(*pcli); + } + return true; + } + return false; +} diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h index 26fc125..0ea5f69 100644 --- a/Source/cmLinkLineDeviceComputer.h +++ b/Source/cmLinkLineDeviceComputer.h @@ -12,6 +12,7 @@ class cmComputeLinkInformation; class cmGeneratorTarget; +class cmLocalGenerator; class cmOutputConverter; class cmStateDirectory; @@ -26,6 +27,8 @@ public: cmLinkLineDeviceComputer& operator=(cmLinkLineDeviceComputer const&) = delete; + bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli); + std::string ComputeLinkLibraries(cmComputeLinkInformation& cli, std::string const& stdLibString) override; @@ -33,4 +36,7 @@ public: std::string const& config) override; }; +bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, + const std::string& config); + #endif diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index beabf91..1113a2c 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileExecutableTargetGenerator.h" -#include <algorithm> #include <memory> // IWYU pragma: keep #include <set> #include <sstream> @@ -87,20 +86,9 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( return; } - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - - bool doDeviceLinking = true; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (!hasCUDA || !doDeviceLinking) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (!requiresDeviceLinking) { return; } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index f5d1fc9..d4d565d 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileLibraryTargetGenerator.h" -#include <algorithm> #include <memory> // IWYU pragma: keep #include <set> #include <sstream> @@ -124,20 +123,10 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules() void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() { - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - - bool doDeviceLinking = false; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (hasCUDA && doDeviceLinking) { + + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (requiresDeviceLinking) { std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; this->WriteDeviceLibraryRules(linkRuleVar, false); } @@ -163,19 +152,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) } if (!relink) { - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - bool doDeviceLinking = true; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (hasCUDA && doDeviceLinking) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (requiresDeviceLinking) { std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; this->WriteDeviceLibraryRules(linkRuleVar, relink); } @@ -209,19 +188,9 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) { if (!relink) { - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - this->GeneratorTarget->GetLinkClosure(this->ConfigName); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - bool doDeviceLinking = true; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } - if (hasCUDA && doDeviceLinking) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); + if (requiresDeviceLinking) { std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; this->WriteDeviceLibraryRules(linkRuleVar, relink); } diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 4d13006..f8a13ce 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -18,6 +18,7 @@ #include "cmGeneratorTarget.h" #include "cmGlobalNinjaGenerator.h" #include "cmLinkLineComputer.h" +#include "cmLinkLineDeviceComputer.h" #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" @@ -571,32 +572,9 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() cmGeneratorTarget& genTarget = *this->GetGeneratorTarget(); - // determine if we need to do any device linking for this target - const std::string cuda_lang("CUDA"); - cmGeneratorTarget::LinkClosure const* closure = - genTarget.GetLinkClosure(this->GetConfigName()); - - const bool hasCUDA = - (std::find(closure->Languages.begin(), closure->Languages.end(), - cuda_lang) != closure->Languages.end()); - - bool doDeviceLinking = false; - if (const char* resolveDeviceSymbols = - genTarget.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } else { - switch (genTarget.GetType()) { - case cmStateEnums::SHARED_LIBRARY: - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::EXECUTABLE: - doDeviceLinking = true; - break; - default: - break; - } - } - - if (!(doDeviceLinking && hasCUDA)) { + bool requiresDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName); + if (!requiresDeviceLinking) { return; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index c60706d..0685a41 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -10,6 +10,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalVisualStudio10Generator.h" +#include "cmLinkLineDeviceComputer.h" #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" #include "cmSourceFile.h" @@ -3007,21 +3008,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( Options& cudaLinkOptions = *pOptions; // Determine if we need to do a device link - bool doDeviceLinking = false; - if (const char* resolveDeviceSymbols = - this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { - doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols); - } else { - switch (this->GeneratorTarget->GetType()) { - case cmStateEnums::SHARED_LIBRARY: - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::EXECUTABLE: - doDeviceLinking = true; - break; - default: - break; - } - } + bool doDeviceLinking = requireDeviceLinking( + *this->GeneratorTarget, *this->LocalGenerator, configName); cudaLinkOptions.AddFlag("PerformDeviceLink", doDeviceLinking ? "true" : "false"); @@ -359,6 +359,7 @@ CMAKE_CXX_SOURCES="\ cmLinkDirectoriesCommand \ cmLinkItem \ cmLinkLineComputer \ + cmLinkLineDeviceComputer \ cmListCommand \ cmListFileCache \ cmLocalCommonGenerator \ |