diff options
Diffstat (limited to 'Source/cmLinkLineDeviceComputer.cxx')
-rw-r--r-- | Source/cmLinkLineDeviceComputer.cxx | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 8d2add6..d845652 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -3,21 +3,21 @@ #include "cmLinkLineDeviceComputer.h" -#include <algorithm> #include <set> -#include <sstream> #include <utility> -#include <vector> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmLinkItem.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" +#include "cmMakefile.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" class cmOutputConverter; @@ -52,7 +52,7 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( { // Determine if this item might requires device linking. // For this we only consider targets - typedef cmComputeLinkInformation::ItemVector ItemVector; + using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); for (auto const& item : items) { @@ -68,21 +68,22 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( return false; } -std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( - cmComputeLinkInformation& cli, std::string const& stdLibString) +void cmLinkLineDeviceComputer::ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString, + std::vector<BT<std::string>>& linkLibraries) { - // Write the library flags to the build rule. - std::ostringstream fout; - // Generate the unique set of link items when device linking. // The nvcc device linker is designed so that each static library // with device symbols only needs to be listed once as it doesn't // care about link order. std::set<std::string> emitted; - typedef cmComputeLinkInformation::ItemVector ItemVector; + using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); bool skipItemAfterFramework = false; + // Note: + // Any modification of this algorithm should be reflected also in + // cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions for (auto const& item : items) { if (skipItemAfterFramework) { skipItemAfterFramework = false; @@ -92,6 +93,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( if (item.Target) { bool skip = false; switch (item.Target->GetType()) { + case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: case cmStateEnums::INTERFACE_LIBRARY: skip = true; @@ -107,7 +109,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } } - std::string out; + BT<std::string> linkLib; if (item.IsPath) { // nvcc understands absolute paths to libraries ending in '.a' or '.lib'. // These should be passed to nvlink. Other extensions need to be left @@ -115,7 +117,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( // can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'. if (cmHasLiteralSuffix(item.Value, ".a") || cmHasLiteralSuffix(item.Value, ".lib")) { - out += this->ConvertToOutputFormat( + linkLib.Value += this->ConvertToOutputFormat( this->ConvertToLinkReference(item.Value)); } } else if (item.Value == "-framework") { @@ -124,19 +126,33 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( skipItemAfterFramework = true; continue; } else if (cmLinkItemValidForDevice(item.Value)) { - out += item.Value; + linkLib.Value += item.Value; } - if (emitted.insert(out).second) { - fout << out << " "; + if (emitted.insert(linkLib.Value).second) { + linkLib.Value += " "; + + const cmLinkImplementation* linkImpl = + cli.GetTarget()->GetLinkImplementation(cli.GetConfig()); + + for (const cmLinkImplItem& iter : linkImpl->Libraries) { + if (iter.Target != nullptr && + iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + std::string libPath = iter.Target->GetLocation(cli.GetConfig()); + if (item.Value == libPath) { + linkLib.Backtrace = iter.Backtrace; + break; + } + } + } + + linkLibraries.emplace_back(linkLib); } } if (!stdLibString.empty()) { - fout << stdLibString << " "; + linkLibraries.emplace_back(cmStrCat(stdLibString, ' ')); } - - return fout.str(); } std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*, @@ -156,16 +172,20 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, return false; } + if (!lg.GetMakefile()->IsOn("CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE")) { + 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); + return cmIsOn(resolveDeviceSymbols); } if (const char* separableCompilation = target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { - if (cmSystemTools::IsOn(separableCompilation)) { + if (cmIsOn(separableCompilation)) { bool doDeviceLinking = false; switch (target.GetType()) { case cmStateEnums::SHARED_LIBRARY: @@ -182,14 +202,10 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, // 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) { + if (cmContains(closure->Languages, "CUDA")) { cmComputeLinkInformation* pcli = target.GetLinkInformation(config); if (pcli) { cmLinkLineDeviceComputer deviceLinkComputer( |