cmLinkLineDeviceComputer.cxx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. static bool cmLinkItemValidForDevice(std::string const& item)
  22. {
  23. // Valid items are:
  24. // * Non-flags (does not start in '-')
  25. // * Specific flags --library, --library-path, -l, -L
  26. // For example:
  27. // * 'cublas_device' => pass-along
  28. // * '--library pthread' => pass-along
  29. // * '-lpthread' => pass-along
  30. // * '-pthread' => drop
  31. // * '-a' => drop
  32. return (!cmHasLiteralPrefix(item, "-") || //
  33. cmHasLiteralPrefix(item, "-l") || //
  34. cmHasLiteralPrefix(item, "-L") || //
  35. cmHasLiteralPrefix(item, "--library"));
  36. }
  37. std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
  38. cmComputeLinkInformation& cli, std::string const& stdLibString)
  39. {
  40. // Write the library flags to the build rule.
  41. std::ostringstream fout;
  42. // Generate the unique set of link items when device linking.
  43. // The nvcc device linker is designed so that each static library
  44. // with device symbols only needs to be listed once as it doesn't
  45. // care about link order.
  46. std::set<std::string> emitted;
  47. typedef cmComputeLinkInformation::ItemVector ItemVector;
  48. ItemVector const& items = cli.GetItems();
  49. std::string config = cli.GetConfig();
  50. for (auto const& item : items) {
  51. if (item.Target) {
  52. bool skip = false;
  53. switch (item.Target->GetType()) {
  54. case cmStateEnums::MODULE_LIBRARY:
  55. case cmStateEnums::INTERFACE_LIBRARY:
  56. skip = true;
  57. break;
  58. case cmStateEnums::STATIC_LIBRARY:
  59. skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
  60. break;
  61. default:
  62. break;
  63. }
  64. if (skip) {
  65. continue;
  66. }
  67. }
  68. std::string out;
  69. if (item.IsPath) {
  70. // nvcc understands absolute paths to libraries ending in '.a' or '.lib'.
  71. // These should be passed to nvlink. Other extensions need to be left
  72. // out because nvlink may not understand or need them. Even though it
  73. // can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'.
  74. if (cmHasLiteralSuffix(item.Value, ".a") ||
  75. cmHasLiteralSuffix(item.Value, ".lib")) {
  76. out += this->ConvertToOutputFormat(
  77. this->ConvertToLinkReference(item.Value));
  78. }
  79. } else if (cmLinkItemValidForDevice(item.Value)) {
  80. out += item.Value;
  81. }
  82. if (emitted.insert(out).second) {
  83. fout << out << " ";
  84. }
  85. }
  86. if (!stdLibString.empty()) {
  87. fout << stdLibString << " ";
  88. }
  89. return fout.str();
  90. }
  91. std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*,
  92. std::string const&)
  93. {
  94. return "CUDA";
  95. }
  96. cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer(
  97. cmOutputConverter* outputConverter, cmStateDirectory const& stateDir,
  98. cmGlobalNinjaGenerator const* gg)
  99. : cmLinkLineDeviceComputer(outputConverter, stateDir)
  100. , GG(gg)
  101. {
  102. }
  103. std::string cmNinjaLinkLineDeviceComputer::ConvertToLinkReference(
  104. std::string const& lib) const
  105. {
  106. return GG->ConvertToNinjaPath(lib);
  107. }