From dcadde3662a61d403b6995ced385a0f953b8e172 Mon Sep 17 00:00:00 2001 From: Taylor Sasser Date: Tue, 18 Nov 2025 14:31:15 -0500 Subject: [PATCH] CPS: Refactor ForbidGeneratorExpressions into cmGeneratorExpression --- Source/cmExportPackageInfoGenerator.cxx | 63 +++++-------------------- Source/cmGeneratorExpression.cxx | 48 +++++++++++++++++++ Source/cmGeneratorExpression.h | 9 ++++ 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/Source/cmExportPackageInfoGenerator.cxx b/Source/cmExportPackageInfoGenerator.cxx index a3ad46e82f..92f21fdd4c 100644 --- a/Source/cmExportPackageInfoGenerator.cxx +++ b/Source/cmExportPackageInfoGenerator.cxx @@ -2,7 +2,6 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmExportPackageInfoGenerator.h" -#include #include #include #include @@ -295,51 +294,6 @@ bool cmExportPackageInfoGenerator::GenerateInterfaceProperties( return result; } -namespace { -bool ForbidGeneratorExpressions( - cmGeneratorTarget const* target, std::string const& propertyName, - std::string const& propertyValue, std::string& evaluatedValue, - std::map>& allowList) -{ - size_t const allowedExpressions = allowList.size(); - evaluatedValue = cmGeneratorExpression::Collect(propertyValue, allowList); - if (evaluatedValue != propertyValue && - allowList.size() > allowedExpressions) { - target->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Property \"", propertyName, "\" of target \"", - target->GetName(), - "\" contains a generator expression. This is not allowed.")); - return false; - } - // Forbid Nested Generator Expressions - for (auto const& genexp : allowList) { - for (auto const& value : genexp.second) { - if (value.find("$<") != std::string::npos) { - target->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat( - "$<", genexp.first, ":...> expression in \"", propertyName, - "\" of target \"", target->GetName(), - "\" contains a generator expression. This is not allowed.")); - return false; - } - } - } - return true; -} - -bool ForbidGeneratorExpressions(cmGeneratorTarget const* target, - std::string const& propertyName, - std::string const& propertyValue) -{ - std::map> allowList; - std::string evaluatedValue; - return ForbidGeneratorExpressions(target, propertyName, propertyValue, - evaluatedValue, allowList); -} -} - bool cmExportPackageInfoGenerator::NoteLinkedTarget( cmGeneratorTarget const* target, std::string const& linkedName, cmGeneratorTarget const* linkedTarget) @@ -446,8 +400,9 @@ void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties( std::map> allowList = { { "LINK_ONLY", {} } }; std::string interfaceLinkLibraries; - if (!ForbidGeneratorExpressions(target, iter->first, iter->second, - interfaceLinkLibraries, allowList)) { + if (!cmGeneratorExpression::ForbidGeneratorExpressions( + target, iter->first, iter->second, interfaceLinkLibraries, + allowList)) { result = false; return; } @@ -490,7 +445,8 @@ void cmExportPackageInfoGenerator::GenerateInterfaceCompileFeatures( return; } - if (!ForbidGeneratorExpressions(target, iter->first, iter->second)) { + if (!cmGeneratorExpression::ForbidGeneratorExpressions(target, iter->first, + iter->second)) { result = false; return; } @@ -519,7 +475,8 @@ void cmExportPackageInfoGenerator::GenerateInterfaceCompileDefines( } // TODO: Support language-specific defines. - if (!ForbidGeneratorExpressions(target, iter->first, iter->second)) { + if (!cmGeneratorExpression::ForbidGeneratorExpressions(target, iter->first, + iter->second)) { result = false; return; } @@ -550,7 +507,8 @@ void cmExportPackageInfoGenerator::GenerateInterfaceListProperty( return; } - if (!ForbidGeneratorExpressions(target, prop, iter->second)) { + if (!cmGeneratorExpression::ForbidGeneratorExpressions(target, prop, + iter->second)) { result = false; return; } @@ -571,7 +529,8 @@ void cmExportPackageInfoGenerator::GenerateProperty( return; } - if (!ForbidGeneratorExpressions(target, inName, iter->second)) { + if (!cmGeneratorExpression::ForbidGeneratorExpressions(target, inName, + iter->second)) { result = false; return; } diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index f6c4880467..c7fffb4924 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -18,8 +19,11 @@ #include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionLexer.h" #include "cmGeneratorExpressionParser.h" +#include "cmGeneratorTarget.h" #include "cmList.h" #include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmMessageType.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -414,6 +418,50 @@ std::string cmGeneratorExpression::Collect( return extractAllGeneratorExpressions(input, &collected); } +bool cmGeneratorExpression::ForbidGeneratorExpressions( + cmGeneratorTarget const* target, std::string const& propertyName, + std::string const& propertyValue) +{ + std::map> allowList; + std::string evaluatedValue; + return ForbidGeneratorExpressions(target, propertyName, propertyValue, + evaluatedValue, allowList); +} + +bool cmGeneratorExpression::ForbidGeneratorExpressions( + cmGeneratorTarget const* target, std::string const& propertyName, + std::string const& propertyValue, std::string& evaluatedValue, + std::map>& allowList) +{ + size_t const initialAllowedGenExps = allowList.size(); + evaluatedValue = Collect(propertyValue, allowList); + if (evaluatedValue != propertyValue && + allowList.size() > initialAllowedGenExps) { + target->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Property \"", propertyName, "\" of target \"", + target->GetName(), + "\" contains a generator expression. This is not allowed.")); + return false; + } + + // Check for nested generator expressions (e.g., $>). + for (auto const& genexp : allowList) { + for (auto const& value : genexp.second) { + if (value.find("$<") != std::string::npos) { + target->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("$<", genexp.first, ":...> expression in \"", propertyName, + "\" of target \"", target->GetName(), + "\" contains a generator expression. This is not " + "allowed.")); + return false; + } + } + } + return true; +} + cm::string_view::size_type cmGeneratorExpression::Find(cm::string_view input) { cm::string_view::size_type const openpos = input.find("$<"); diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index a84b7ac7b2..210cd0ab7c 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -58,6 +58,15 @@ public: cmGeneratorTarget const* currentTarget = nullptr, std::string const& language = std::string()); + static bool ForbidGeneratorExpressions( + cmGeneratorTarget const* target, std::string const& propertyName, + std::string const& propertyValue, std::string& evaluatedValue, + std::map>& allowList); + + static bool ForbidGeneratorExpressions(cmGeneratorTarget const* target, + std::string const& propertyName, + std::string const& propertyValue); + enum PreprocessContext { StripAllGeneratorExpressions,