| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file LICENSE.rst or https://cmake.org/licensing for details. */ |
| /* clang-format off */ |
| #include "cmGeneratorTarget.h" |
| /* clang-format on */ |
| |
| #include <algorithm> |
| #include <map> |
| #include <string> |
| #include <unordered_set> |
| #include <utility> |
| #include <vector> |
| |
| #include <cmext/algorithm> |
| |
| #include "cmEvaluatedTargetProperty.h" |
| #include "cmGenExContext.h" |
| #include "cmGeneratorExpressionDAGChecker.h" |
| #include "cmList.h" |
| #include "cmListFileCache.h" |
| #include "cmLocalGenerator.h" |
| #include "cmMakefile.h" |
| #include "cmMessageType.h" |
| #include "cmStringAlgorithms.h" |
| #include "cmUnreachable.h" |
| #include "cmValue.h" |
| #include "cmake.h" |
| |
| namespace { |
| |
| enum class WrapperType |
| { |
| Compile, |
| Link, |
| }; |
| |
| std::string WrapperTypeToString(WrapperType type) |
| { |
| switch (type) { |
| case WrapperType::Compile: |
| return "compile"; |
| case WrapperType::Link: |
| return "link"; |
| } |
| CM_UNREACHABLE; |
| } |
| |
| void ProcessWrappers(cmGeneratorTarget const* tgt, |
| cm::EvaluatedTargetPropertyEntries const& entries, |
| std::vector<BT<std::string>>& wrappers, |
| std::unordered_set<std::string>& uniqueWrappers, |
| WrapperType wrapperType, bool debugWrapper) |
| { |
| for (cm::EvaluatedTargetPropertyEntry const& entry : entries.Entries) { |
| std::string usedOptions; |
| for (std::string const& entryOption : entry.Values) { |
| if (uniqueWrappers.insert(entryOption).second) { |
| wrappers.emplace_back(entryOption, entry.Backtrace); |
| if (debugWrapper) { |
| usedOptions = |
| cmStrCat(std::move(usedOptions), " * ", entryOption, '\n'); |
| } |
| } |
| } |
| if (!usedOptions.empty()) { |
| tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage( |
| MessageType::LOG, |
| cmStrCat("Used ", WrapperTypeToString(wrapperType), |
| " wrappers for target ", tgt->GetName(), ":\n", usedOptions), |
| entry.Backtrace); |
| } |
| } |
| |
| // Order wrappers lexicographically based on their name. |
| std::sort(wrappers.begin(), wrappers.end(), |
| [](BT<std::string> const& a, BT<std::string> const& b) { |
| return a.Value < b.Value; |
| }); |
| } |
| } // namespace |
| |
| std::vector<BT<std::string>> cmGeneratorTarget::GetLinkWrappers( |
| std::string const& config, std::string const& lang) const |
| { |
| ConfigAndLanguage cacheKey(config, lang); |
| { |
| auto it = this->LinkWrappersCache.find(cacheKey); |
| if (it != this->LinkWrappersCache.end()) { |
| return it->second; |
| } |
| } |
| |
| std::vector<BT<std::string>> wrappers; |
| std::unordered_set<std::string> uniqueWrappers; |
| cm::GenEx::Context context(this->LocalGenerator, config, lang); |
| cmGeneratorExpressionDAGChecker dagChecker{ |
| this, "LINK_WRAPPERS", nullptr, nullptr, context, |
| }; |
| |
| cmList debugProperties{ this->Makefile->GetDefinition( |
| "CMAKE_DEBUG_TARGET_PROPERTIES") }; |
| bool debugWrappers = !this->DebugLinkWrappersDone && |
| cm::contains(debugProperties, "LINK_WRAPPERS"); |
| this->DebugLinkWrappersDone = true; |
| |
| cm::EvaluatedTargetPropertyEntries entries = |
| cm::EvaluateTargetPropertyEntries(this, context, &dagChecker, |
| this->LinkWrappersEntries); |
| AddInterfaceEntries(this, "INTERFACE_LINK_WRAPPERS", context, &dagChecker, |
| entries, cm::IncludeRuntimeInterface::Yes, UseTo::Link); |
| |
| ProcessWrappers(this, entries, wrappers, uniqueWrappers, WrapperType::Link, |
| debugWrappers); |
| |
| this->LinkWrappersCache.emplace(cacheKey, wrappers); |
| return wrappers; |
| } |
| |
| std::vector<BT<std::string>> cmGeneratorTarget::GetCompileWrappers( |
| std::string const& config, std::string const& lang) const |
| { |
| ConfigAndLanguage cacheKey(config, lang); |
| { |
| auto it = this->CompileWrappersCache.find(cacheKey); |
| if (it != this->CompileWrappersCache.end()) { |
| return it->second; |
| } |
| } |
| |
| std::vector<BT<std::string>> wrappers; |
| std::unordered_set<std::string> uniqueWrappers; |
| cm::GenEx::Context context(this->LocalGenerator, config, lang); |
| cmGeneratorExpressionDAGChecker dagChecker{ |
| this, "COMPILE_WRAPPERS", nullptr, nullptr, context, |
| }; |
| |
| cmList debugProperties{ this->Makefile->GetDefinition( |
| "CMAKE_DEBUG_TARGET_PROPERTIES") }; |
| bool debugWrappers = !this->DebugCompileWrappersDone && |
| cm::contains(debugProperties, "COMPILE_WRAPPERS"); |
| this->DebugCompileWrappersDone = true; |
| |
| cm::EvaluatedTargetPropertyEntries entries = |
| cm::EvaluateTargetPropertyEntries(this, context, &dagChecker, |
| this->CompileWrappersEntries); |
| AddInterfaceEntries(this, "INTERFACE_COMPILE_WRAPPERS", context, &dagChecker, |
| entries, cm::IncludeRuntimeInterface::Yes, |
| UseTo::Compile); |
| |
| ProcessWrappers(this, entries, wrappers, uniqueWrappers, |
| WrapperType::Compile, debugWrappers); |
| |
| this->CompileWrappersCache.emplace(cacheKey, wrappers); |
| return wrappers; |
| } |