cmEvaluatedTargetProperty.cxx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file LICENSE.rst or https://cmake.org/licensing for details. */
  3. #include "cmEvaluatedTargetProperty.h"
  4. #include <unordered_map>
  5. #include <utility>
  6. #include "cmGenExContext.h"
  7. #include "cmGenExEvaluation.h"
  8. #include "cmGeneratorTarget.h"
  9. #include "cmLinkItem.h"
  10. #include "cmList.h"
  11. struct cmGeneratorExpressionDAGChecker;
  12. EvaluatedTargetPropertyEntry::EvaluatedTargetPropertyEntry(
  13. cmLinkImplItem const& item, cmListFileBacktrace bt)
  14. : LinkImplItem(item)
  15. , Backtrace(std::move(bt))
  16. {
  17. }
  18. EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
  19. cmGeneratorTarget const* thisTarget, std::string const& config,
  20. std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
  21. cmGeneratorTarget::TargetPropertyEntry& entry)
  22. {
  23. EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace());
  24. cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config,
  25. thisTarget, dagChecker, lang),
  26. ee.Values);
  27. if (entry.GetHadContextSensitiveCondition()) {
  28. ee.ContextDependent = true;
  29. }
  30. return ee;
  31. }
  32. EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
  33. cmGeneratorTarget const* thisTarget, std::string const& config,
  34. std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
  35. std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
  36. in)
  37. {
  38. EvaluatedTargetPropertyEntries out;
  39. out.Entries.reserve(in.size());
  40. for (auto const& entry : in) {
  41. out.Entries.emplace_back(EvaluateTargetPropertyEntry(
  42. thisTarget, config, lang, dagChecker, *entry));
  43. }
  44. return out;
  45. }
  46. namespace {
  47. void addInterfaceEntry(cmGeneratorTarget const* headTarget,
  48. std::string const& config, std::string const& prop,
  49. std::string const& lang,
  50. cmGeneratorExpressionDAGChecker* dagChecker,
  51. EvaluatedTargetPropertyEntries& entries,
  52. cmGeneratorTarget::UseTo usage,
  53. std::vector<cmLinkImplItem> const& libraries)
  54. {
  55. for (cmLinkImplItem const& lib : libraries) {
  56. if (lib.Target) {
  57. EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
  58. // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
  59. // caller's property and hand-evaluate it as if it were compiled.
  60. // Create a context as cmCompiledGeneratorExpression::Evaluate does.
  61. cm::GenEx::Evaluation eval(
  62. cm::GenEx::Context(headTarget->GetLocalGenerator(), config, lang),
  63. false, headTarget, headTarget, true, lib.Backtrace);
  64. cmExpandList(
  65. lib.Target->EvaluateInterfaceProperty(prop, &eval, dagChecker, usage),
  66. ee.Values);
  67. ee.ContextDependent = eval.HadContextSensitiveCondition;
  68. entries.Entries.emplace_back(std::move(ee));
  69. }
  70. }
  71. }
  72. }
  73. void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
  74. std::string const& config, std::string const& prop,
  75. std::string const& lang,
  76. cmGeneratorExpressionDAGChecker* dagChecker,
  77. EvaluatedTargetPropertyEntries& entries,
  78. IncludeRuntimeInterface searchRuntime,
  79. cmGeneratorTarget::UseTo usage)
  80. {
  81. if (searchRuntime == IncludeRuntimeInterface::Yes) {
  82. if (cmLinkImplementation const* impl =
  83. headTarget->GetLinkImplementation(config, usage)) {
  84. entries.HadContextSensitiveCondition =
  85. impl->HadContextSensitiveCondition;
  86. auto runtimeLibIt = impl->LanguageRuntimeLibraries.find(lang);
  87. if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) {
  88. addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
  89. usage, runtimeLibIt->second);
  90. }
  91. addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
  92. usage, impl->Libraries);
  93. }
  94. } else {
  95. if (cmLinkImplementationLibraries const* impl =
  96. headTarget->GetLinkImplementationLibraries(config, usage)) {
  97. entries.HadContextSensitiveCondition =
  98. impl->HadContextSensitiveCondition;
  99. addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
  100. usage, impl->Libraries);
  101. }
  102. }
  103. }