cmLinkLineDeviceComputer.cxx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmLinkLineDeviceComputer.h"
  4. #include <set>
  5. #include <sstream>
  6. #include <utility>
  7. #include "cmAlgorithms.h"
  8. #include "cmComputeLinkInformation.h"
  9. #include "cmGeneratorTarget.h"
  10. #include "cmGlobalNinjaGenerator.h"
  11. #include "cmStateTypes.h"
  12. class cmOutputConverter;
  13. cmLinkLineDeviceComputer::cmLinkLineDeviceComputer(
  14. cmOutputConverter* outputConverter, cmStateDirectory const& stateDir)
  15. : cmLinkLineComputer(outputConverter, stateDir)
  16. {
  17. }
  18. cmLinkLineDeviceComputer::~cmLinkLineDeviceComputer()
  19. {
  20. }
  21. std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
  22. cmComputeLinkInformation& cli, std::string const& stdLibString)
  23. {
  24. // Write the library flags to the build rule.
  25. std::ostringstream fout;
  26. // Generate the unique set of link items when device linking.
  27. // The nvcc device linker is designed so that each static library
  28. // with device symbols only needs to be listed once as it doesn't
  29. // care about link order.
  30. std::set<std::string> emitted;
  31. typedef cmComputeLinkInformation::ItemVector ItemVector;
  32. ItemVector const& items = cli.GetItems();
  33. std::string config = cli.GetConfig();
  34. for (auto const& item : items) {
  35. if (item.Target) {
  36. bool skip = false;
  37. switch (item.Target->GetType()) {
  38. case cmStateEnums::MODULE_LIBRARY:
  39. case cmStateEnums::INTERFACE_LIBRARY:
  40. skip = true;
  41. break;
  42. case cmStateEnums::STATIC_LIBRARY:
  43. skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
  44. break;
  45. default:
  46. break;
  47. }
  48. if (skip) {
  49. continue;
  50. }
  51. }
  52. std::string out;
  53. if (item.IsPath) {
  54. // nvcc understands absolute paths to libraries ending in '.a' should
  55. // be passed to nvlink. Other extensions like '.so' or '.dylib' are
  56. // rejected by the nvcc front-end even though nvlink knows to ignore
  57. // them. Bypass the front-end via '-Xnvlink'.
  58. if (!cmHasLiteralSuffix(item.Value, ".a")) {
  59. out += "-Xnvlink ";
  60. }
  61. out +=
  62. this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value));
  63. } else {
  64. out += item.Value;
  65. }
  66. if (emitted.insert(out).second) {
  67. fout << out << " ";
  68. }
  69. }
  70. if (!stdLibString.empty()) {
  71. fout << stdLibString << " ";
  72. }
  73. return fout.str();
  74. }
  75. std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*,
  76. std::string const&)
  77. {
  78. return "CUDA";
  79. }
  80. cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer(
  81. cmOutputConverter* outputConverter, cmStateDirectory const& stateDir,
  82. cmGlobalNinjaGenerator const* gg)
  83. : cmLinkLineDeviceComputer(outputConverter, stateDir)
  84. , GG(gg)
  85. {
  86. }
  87. std::string cmNinjaLinkLineDeviceComputer::ConvertToLinkReference(
  88. std::string const& lib) const
  89. {
  90. return GG->ConvertToNinjaPath(lib);
  91. }