diff options
author | Brad King <brad.king@kitware.com> | 2024-04-29 18:25:34 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2024-04-29 21:39:12 (GMT) |
commit | 79a3ae9a0d6b4cf8369b40e5c371617ad3cc9e11 (patch) | |
tree | 83dd913f57a8b29bf1a68e40093de92cd8567b93 | |
parent | e8010b67c7050aca36f5db9a75027606af35b93a (diff) | |
download | CMake-79a3ae9a0d6b4cf8369b40e5c371617ad3cc9e11.zip CMake-79a3ae9a0d6b4cf8369b40e5c371617ad3cc9e11.tar.gz CMake-79a3ae9a0d6b4cf8369b40e5c371617ad3cc9e11.tar.bz2 |
cmGeneratorExpressionDAGChecker: Simplify transitive property table
Refactor the table of builtin transitive properties to avoid
preprocessor-generated cascading-if blocks with duplicate code.
-rw-r--r-- | Source/cmExportTryCompileFileGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionDAGChecker.cxx | 52 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionDAGChecker.h | 33 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 21 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 40 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 12 |
6 files changed, 73 insertions, 97 deletions
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 41b1049..4c41ff5 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -2,9 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportTryCompileFileGenerator.h" +#include <map> #include <utility> #include <cm/memory> +#include <cm/string_view> #include "cmFileSet.h" #include "cmGeneratorExpression.h" @@ -44,12 +46,10 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) ImportPropertyMap properties; for (std::string const& lang : this->Languages) { -#define FIND_TARGETS(PROPERTY) \ - this->FindTargets("INTERFACE_" #PROPERTY, te, lang, emittedDeps); - - CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS) - -#undef FIND_TARGETS + for (auto i : cmGeneratorTarget::BuiltinTransitiveProperties) { + this->FindTargets(std::string(i.second.InterfaceName), te, lang, + emittedDeps); + } } this->PopulateProperties(te, properties, emittedDeps); diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 8bad91b..bb1f4b4 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -2,10 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGeneratorExpressionDAGChecker.h" -#include <cstring> #include <sstream> #include <utility> +#include <cm/optional> #include <cm/string_view> #include <cmext/string_view> @@ -38,14 +38,12 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( , Content(content) , Backtrace(std::move(backtrace)) { - static_cast<void>(contextLG); if (parent) { this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty; } else { -#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) this->METHOD() || - this->TopIsTransitiveProperty = (CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( - TEST_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(*) -#undef TEST_TRANSITIVE_PROPERTY_METHOD + this->TopIsTransitiveProperty = + this->Target->IsTransitiveProperty(this->Property, contextLG) + .has_value(); } this->CheckResult = this->CheckGraph(); @@ -171,6 +169,12 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileExpression() const property == "COMPILE_DEFINITIONS"_s || property == "COMPILE_OPTIONS"_s; } +bool cmGeneratorExpressionDAGChecker::EvaluatingSources() const +{ + return this->Property == "SOURCES"_s || + this->Property == "INTERFACE_SOURCES"_s; +} + bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const { cm::string_view property(this->Top->Property); @@ -224,39 +228,3 @@ cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const { return this->Top->Target; } - -enum class TransitiveProperty -{ -#define DEFINE_ENUM_ENTRY(NAME) NAME, - CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(DEFINE_ENUM_ENTRY) -#undef DEFINE_ENUM_ENTRY - Terminal -}; - -template <TransitiveProperty> -bool additionalTest(const char* const /*unused*/) -{ - return false; -} - -template <> -bool additionalTest<TransitiveProperty::COMPILE_DEFINITIONS>( - const char* const prop) -{ - return cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_"); -} - -#define DEFINE_TRANSITIVE_PROPERTY_METHOD(METHOD, PROPERTY) \ - bool cmGeneratorExpressionDAGChecker::METHOD() const \ - { \ - const char* const prop = this->Property.c_str(); \ - if (strcmp(prop, #PROPERTY) == 0 || \ - strcmp(prop, "INTERFACE_" #PROPERTY) == 0) { \ - return true; \ - } \ - return additionalTest<TransitiveProperty::PROPERTY>(prop); \ - } - -CM_FOR_EACH_TRANSITIVE_PROPERTY(DEFINE_TRANSITIVE_PROPERTY_METHOD) - -#undef DEFINE_TRANSITIVE_PROPERTY_METHOD diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index ea29b96..b230188 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -15,33 +15,6 @@ struct cmGeneratorExpressionContext; class cmGeneratorTarget; class cmLocalGenerator; -#define CM_SELECT_BOTH(F, A1, A2) F(A1, A2) -#define CM_SELECT_FIRST(F, A1, A2) F(A1) -#define CM_SELECT_SECOND(F, A1, A2) F(A2) - -#define CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, SELECT) \ - SELECT(F, EvaluatingIncludeDirectories, INCLUDE_DIRECTORIES) \ - SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES) \ - SELECT(F, EvaluatingCompileDefinitions, COMPILE_DEFINITIONS) \ - SELECT(F, EvaluatingCompileOptions, COMPILE_OPTIONS) \ - SELECT(F, EvaluatingAutoMocMacroNames, AUTOMOC_MACRO_NAMES) \ - SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS) \ - SELECT(F, EvaluatingSources, SOURCES) \ - SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \ - SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \ - SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES) \ - SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) \ - SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS) - -#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \ - CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH) - -#define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F) \ - CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_FIRST) - -#define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \ - CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_SECOND) - struct cmGeneratorExpressionDAGChecker { cmGeneratorExpressionDAGChecker(cmListFileBacktrace backtrace, @@ -86,11 +59,7 @@ struct cmGeneratorExpressionDAGChecker bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr, ForGenex genex = ForGenex::ANY) const; -#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const; - - CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD) - -#undef DECLARE_TRANSITIVE_PROPERTY_METHOD + bool EvaluatingSources() const; bool GetTransitivePropertiesOnly() const; void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; } diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 34c0b7b..52ba8bc 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -2877,24 +2877,11 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode std::string interfacePropertyName; bool isInterfaceProperty = false; -#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ - if (propertyName == #prop) { \ - interfacePropertyName = "INTERFACE_" #prop; \ - } else if (propertyName == "INTERFACE_" #prop) { \ - interfacePropertyName = "INTERFACE_" #prop; \ - isInterfaceProperty = true; \ - } else - - CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) - // Note that the above macro terminates with an else - /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) { - cmPolicies::PolicyStatus polSt = - context->LG->GetPolicyStatus(cmPolicies::CMP0043); - if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) { - interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; - } + if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp = + target->IsTransitiveProperty(propertyName, context->LG)) { + interfacePropertyName = std::string(transitiveProp->InterfaceName); + isInterfaceProperty = transitiveProp->InterfaceName == propertyName; } -#undef POPULATE_INTERFACE_PROPERTY_NAME bool evaluatingLinkLibraries = false; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 13ac815..d0573da 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -65,6 +65,7 @@ namespace { using LinkInterfaceFor = cmGeneratorTarget::LinkInterfaceFor; +using TransitiveProperty = cmGeneratorTarget::TransitiveProperty; const std::string kINTERFACE_LINK_LIBRARIES = "INTERFACE_LINK_LIBRARIES"; const std::string kINTERFACE_LINK_LIBRARIES_DIRECT = @@ -73,6 +74,23 @@ const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE = "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"; } +const std::map<cm::string_view, TransitiveProperty> + cmGeneratorTarget::BuiltinTransitiveProperties = { + { "AUTOMOC_MACRO_NAMES"_s, { "INTERFACE_AUTOMOC_MACRO_NAMES"_s } }, + { "AUTOUIC_OPTIONS"_s, { "INTERFACE_AUTOUIC_OPTIONS"_s } }, + { "COMPILE_DEFINITIONS"_s, { "INTERFACE_COMPILE_DEFINITIONS"_s } }, + { "COMPILE_FEATURES"_s, { "INTERFACE_COMPILE_FEATURES"_s } }, + { "COMPILE_OPTIONS"_s, { "INTERFACE_COMPILE_OPTIONS"_s } }, + { "INCLUDE_DIRECTORIES"_s, { "INTERFACE_INCLUDE_DIRECTORIES"_s } }, + { "LINK_DEPENDS"_s, { "INTERFACE_LINK_DEPENDS"_s } }, + { "LINK_DIRECTORIES"_s, { "INTERFACE_LINK_DIRECTORIES"_s } }, + { "LINK_OPTIONS"_s, { "INTERFACE_LINK_OPTIONS"_s } }, + { "PRECOMPILE_HEADERS"_s, { "INTERFACE_PRECOMPILE_HEADERS"_s } }, + { "SOURCES"_s, { "INTERFACE_SOURCES"_s } }, + { "SYSTEM_INCLUDE_DIRECTORIES"_s, + { "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"_s } }, + }; + template <> cmValue cmTargetPropertyComputer::GetSources<cmGeneratorTarget>( cmGeneratorTarget const* tgt, cmMakefile const& /* mf */) @@ -1517,6 +1535,28 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( return result; } +cm::optional<cmGeneratorTarget::TransitiveProperty> +cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop, + cmLocalGenerator const* lg) const +{ + cm::optional<TransitiveProperty> result; + static const cm::string_view kINTERFACE_ = "INTERFACE_"_s; + if (cmHasPrefix(prop, kINTERFACE_)) { + prop = prop.substr(kINTERFACE_.length()); + } + auto i = BuiltinTransitiveProperties.find(prop); + if (i != BuiltinTransitiveProperties.end()) { + result = i->second; + } else if (cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_")) { + cmPolicies::PolicyStatus cmp0043 = + lg->GetPolicyStatus(cmPolicies::CMP0043); + if (cmp0043 == cmPolicies::WARN || cmp0043 == cmPolicies::OLD) { + result = TransitiveProperty{ "INTERFACE_COMPILE_DEFINITIONS"_s }; + } + } + return result; +} + namespace { enum class IncludeDirectoryFallBack diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index fbc71e5..fc625b9 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -15,6 +15,7 @@ #include <vector> #include <cm/optional> +#include <cm/string_view> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" @@ -885,6 +886,17 @@ public: cmGeneratorExpressionDAGChecker* dagCheckerParent, LinkInterfaceFor interfaceFor) const; + struct TransitiveProperty + { + cm::string_view InterfaceName; + }; + + static const std::map<cm::string_view, TransitiveProperty> + BuiltinTransitiveProperties; + + cm::optional<TransitiveProperty> IsTransitiveProperty( + cm::string_view prop, cmLocalGenerator const* lg) const; + bool HaveInstallTreeRPATH(const std::string& config) const; bool GetBuildRPATH(const std::string& config, std::string& rpath) const; |