blob: 760e868ddc92968369caed91d632ce388f154327 [file]
/* 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 <algorithm>
#include <set>
#include <vector>
#include <cm/string_view>
#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<cm::string_view> 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 <typename Range>
void AppendUsageEntries(std::string& usageHashInput, Range const& entries)
{
std::vector<std::string> 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<std::string>& flag) { return !filter(flag.Value); }));
} else {
AppendUsageEntries(usageHashInput, tgt->GetCompileFeaturesEntries());
AppendUsageEntries(
usageHashInput,
tgt->GetCompileOptionsEntries().filter(
[&](const BT<std::string>& flag) { return !filter(flag.Value); }));
}
cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
this->Hash = hasher.HashString(usageHashInput);
}
std::string const& cmCxxModuleUsageEffects::GetHash() const
{
return this->Hash;
}