mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
cmGeneratorExpressionDAGChecker: Simplify transitive property table
Refactor the table of builtin transitive properties to avoid preprocessor-generated cascading-if blocks with duplicate code.
This commit is contained in:
@@ -2,9 +2,11 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmExportTryCompileFileGenerator.h"
|
#include "cmExportTryCompileFileGenerator.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <cm/memory>
|
#include <cm/memory>
|
||||||
|
#include <cm/string_view>
|
||||||
|
|
||||||
#include "cmFileSet.h"
|
#include "cmFileSet.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
@@ -44,12 +46,10 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
|
|||||||
ImportPropertyMap properties;
|
ImportPropertyMap properties;
|
||||||
|
|
||||||
for (std::string const& lang : this->Languages) {
|
for (std::string const& lang : this->Languages) {
|
||||||
#define FIND_TARGETS(PROPERTY) \
|
for (auto i : cmGeneratorTarget::BuiltinTransitiveProperties) {
|
||||||
this->FindTargets("INTERFACE_" #PROPERTY, te, lang, emittedDeps);
|
this->FindTargets(std::string(i.second.InterfaceName), te, lang,
|
||||||
|
emittedDeps);
|
||||||
CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS)
|
}
|
||||||
|
|
||||||
#undef FIND_TARGETS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->PopulateProperties(te, properties, emittedDeps);
|
this->PopulateProperties(te, properties, emittedDeps);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmGeneratorExpressionDAGChecker.h"
|
#include "cmGeneratorExpressionDAGChecker.h"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
#include <cm/string_view>
|
#include <cm/string_view>
|
||||||
#include <cmext/string_view>
|
#include <cmext/string_view>
|
||||||
|
|
||||||
@@ -38,14 +38,12 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
|
|||||||
, Content(content)
|
, Content(content)
|
||||||
, Backtrace(std::move(backtrace))
|
, Backtrace(std::move(backtrace))
|
||||||
{
|
{
|
||||||
static_cast<void>(contextLG);
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
|
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
|
||||||
} else {
|
} else {
|
||||||
#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) this->METHOD() ||
|
this->TopIsTransitiveProperty =
|
||||||
this->TopIsTransitiveProperty = (CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
|
this->Target->IsTransitiveProperty(this->Property, contextLG)
|
||||||
TEST_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(*)
|
.has_value();
|
||||||
#undef TEST_TRANSITIVE_PROPERTY_METHOD
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->CheckResult = this->CheckGraph();
|
this->CheckResult = this->CheckGraph();
|
||||||
@@ -171,6 +169,12 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileExpression() const
|
|||||||
property == "COMPILE_DEFINITIONS"_s || property == "COMPILE_OPTIONS"_s;
|
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
|
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
|
||||||
{
|
{
|
||||||
cm::string_view property(this->Top->Property);
|
cm::string_view property(this->Top->Property);
|
||||||
@@ -224,39 +228,3 @@ cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
|
|||||||
{
|
{
|
||||||
return this->Top->Target;
|
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
|
|
||||||
|
|||||||
@@ -15,33 +15,6 @@ struct cmGeneratorExpressionContext;
|
|||||||
class cmGeneratorTarget;
|
class cmGeneratorTarget;
|
||||||
class cmLocalGenerator;
|
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
|
struct cmGeneratorExpressionDAGChecker
|
||||||
{
|
{
|
||||||
cmGeneratorExpressionDAGChecker(cmListFileBacktrace backtrace,
|
cmGeneratorExpressionDAGChecker(cmListFileBacktrace backtrace,
|
||||||
@@ -86,11 +59,7 @@ struct cmGeneratorExpressionDAGChecker
|
|||||||
bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr,
|
bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr,
|
||||||
ForGenex genex = ForGenex::ANY) const;
|
ForGenex genex = ForGenex::ANY) const;
|
||||||
|
|
||||||
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
|
bool EvaluatingSources() const;
|
||||||
|
|
||||||
CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
|
|
||||||
|
|
||||||
#undef DECLARE_TRANSITIVE_PROPERTY_METHOD
|
|
||||||
|
|
||||||
bool GetTransitivePropertiesOnly() const;
|
bool GetTransitivePropertiesOnly() const;
|
||||||
void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
|
void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
|
||||||
|
|||||||
@@ -2877,24 +2877,11 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||||||
std::string interfacePropertyName;
|
std::string interfacePropertyName;
|
||||||
bool isInterfaceProperty = false;
|
bool isInterfaceProperty = false;
|
||||||
|
|
||||||
#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
|
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
|
||||||
if (propertyName == #prop) { \
|
target->IsTransitiveProperty(propertyName, context->LG)) {
|
||||||
interfacePropertyName = "INTERFACE_" #prop; \
|
interfacePropertyName = std::string(transitiveProp->InterfaceName);
|
||||||
} else if (propertyName == "INTERFACE_" #prop) { \
|
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
|
||||||
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";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#undef POPULATE_INTERFACE_PROPERTY_NAME
|
|
||||||
|
|
||||||
bool evaluatingLinkLibraries = false;
|
bool evaluatingLinkLibraries = false;
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
using LinkInterfaceFor = cmGeneratorTarget::LinkInterfaceFor;
|
using LinkInterfaceFor = cmGeneratorTarget::LinkInterfaceFor;
|
||||||
|
using TransitiveProperty = cmGeneratorTarget::TransitiveProperty;
|
||||||
|
|
||||||
const std::string kINTERFACE_LINK_LIBRARIES = "INTERFACE_LINK_LIBRARIES";
|
const std::string kINTERFACE_LINK_LIBRARIES = "INTERFACE_LINK_LIBRARIES";
|
||||||
const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
|
const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
|
||||||
@@ -73,6 +74,23 @@ const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE =
|
|||||||
"INTERFACE_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 <>
|
template <>
|
||||||
cmValue cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
|
cmValue cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
|
||||||
cmGeneratorTarget const* tgt, cmMakefile const& /* mf */)
|
cmGeneratorTarget const* tgt, cmMakefile const& /* mf */)
|
||||||
@@ -1517,6 +1535,28 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
|
|||||||
return result;
|
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 {
|
namespace {
|
||||||
|
|
||||||
enum class IncludeDirectoryFallBack
|
enum class IncludeDirectoryFallBack
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cm/optional>
|
#include <cm/optional>
|
||||||
|
#include <cm/string_view>
|
||||||
|
|
||||||
#include "cmAlgorithms.h"
|
#include "cmAlgorithms.h"
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
@@ -885,6 +886,17 @@ public:
|
|||||||
cmGeneratorExpressionDAGChecker* dagCheckerParent,
|
cmGeneratorExpressionDAGChecker* dagCheckerParent,
|
||||||
LinkInterfaceFor interfaceFor) const;
|
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 HaveInstallTreeRPATH(const std::string& config) const;
|
||||||
|
|
||||||
bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
|
bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user