summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2024-04-29 18:25:34 (GMT)
committerBrad King <brad.king@kitware.com>2024-04-29 21:39:12 (GMT)
commit79a3ae9a0d6b4cf8369b40e5c371617ad3cc9e11 (patch)
tree83dd913f57a8b29bf1a68e40093de92cd8567b93
parente8010b67c7050aca36f5db9a75027606af35b93a (diff)
downloadCMake-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.cxx12
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx52
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h33
-rw-r--r--Source/cmGeneratorExpressionNode.cxx21
-rw-r--r--Source/cmGeneratorTarget.cxx40
-rw-r--r--Source/cmGeneratorTarget.h12
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;