/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmCxxModuleUsageEffects.h" #include #include #include #include #include "cmCryptoHash.h" #include "cmGeneratorTarget.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmTarget.h" #include "cmValue.h" namespace { bool IsMSVCWarning(cm::string_view flag) { if (flag.size() < 2) { return false; } if (flag.front() != '/' && flag.front() != '-') { return false; } flag.remove_prefix(1); if (flag.front() == 'w' || flag.front() == 'W') { return true; } if (flag.substr(0, 9) == "external:") { return true; } return false; } bool IsGNUWarning(cm::string_view flag) { if (flag.size() < 2) { return false; } if (flag.front() != '-') { return false; } flag.remove_prefix(1); if (flag.front() == 'w' || flag.front() == 'W') { return true; } if (flag.front() == '-') { flag.remove_prefix(1); } static std::set const long_names{ "pedantic", "pedantic-errors", "all-warnings", "extra-warnings", "no-warnings" }; return long_names.find(flag) != long_names.end(); } bool UnknownFilter(cm::string_view) { return false; } using FlagFilter = bool (*)(cm::string_view flag); FlagFilter GetFlagFilter(cmGeneratorTarget const* gt) { static FlagFilter filter = nullptr; if (filter) { return filter; } cmValue frontendVariant = gt->Makefile->GetDefinition("CMAKE_CXX_COMPILER_FRONTEND_VARIANT"); if (frontendVariant == "GNU") { filter = IsGNUWarning; } else if (frontendVariant == "MSVC") { filter = IsMSVCWarning; } else { filter = UnknownFilter; } return filter; } template void AppendUsageEntries(std::string& usageHashInput, Range const& entries) { std::vector entryValues; for (auto const& entry : entries) { entryValues.push_back(entry.Value); } std::sort(entryValues.begin(), entryValues.end()); for (auto const& entryValue : entryValues) { usageHashInput += entryValue; usageHashInput.push_back('\n'); } usageHashInput.push_back('\0'); } } cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const* gt) { auto const* tgt = gt->Target; auto const filter = GetFlagFilter(gt); std::string usageHashInput; if (tgt->IsImported()) { AppendUsageEntries(usageHashInput, tgt->GetImportedCxxModulesCompileFeaturesEntries()); AppendUsageEntries( usageHashInput, tgt->GetImportedCxxModulesCompileOptionsEntries().filter( [&](const BT& flag) { return !filter(flag.Value); })); } else { AppendUsageEntries(usageHashInput, tgt->GetCompileFeaturesEntries()); AppendUsageEntries( usageHashInput, tgt->GetCompileOptionsEntries().filter( [&](const BT& flag) { return !filter(flag.Value); })); } cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512); this->Hash = hasher.HashString(usageHashInput); } std::string const& cmCxxModuleUsageEffects::GetHash() const { return this->Hash; }