mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-17 07:11:52 +08:00
GenEx: Fix evaluation of LINK_LIBRARIES as custom transitive property
Fix logic from commit b9ee79b8a1
(GenEx: Add support for custom
transitive compile properties, 2024-05-09, v3.30.0-rc1~82^2~1) to more
precisely know when we are computing the link dependency graph.
Issue: #20416
Issue: #26709
This commit is contained in:
@@ -21,21 +21,22 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
|
|||||||
cmGeneratorTarget const* target, std::string property,
|
cmGeneratorTarget const* target, std::string property,
|
||||||
GeneratorExpressionContent const* content,
|
GeneratorExpressionContent const* content,
|
||||||
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
|
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
|
||||||
std::string const& contextConfig, cmListFileBacktrace backtrace)
|
std::string const& contextConfig, cmListFileBacktrace backtrace,
|
||||||
|
ComputingLinkLibraries computingLinkLibraries)
|
||||||
: Parent(parent)
|
: Parent(parent)
|
||||||
, Top(parent ? parent->Top : this)
|
, Top(parent ? parent->Top : this)
|
||||||
, Target(target)
|
, Target(target)
|
||||||
, Property(std::move(property))
|
, Property(std::move(property))
|
||||||
, Content(content)
|
, Content(content)
|
||||||
, Backtrace(std::move(backtrace))
|
, Backtrace(std::move(backtrace))
|
||||||
|
, ComputingLinkLibraries_(computingLinkLibraries)
|
||||||
{
|
{
|
||||||
if (parent) {
|
if (parent) {
|
||||||
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
|
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
|
||||||
} else {
|
} else {
|
||||||
this->TopIsTransitiveProperty =
|
this->TopIsTransitiveProperty =
|
||||||
this->Target
|
this->Target
|
||||||
->IsTransitiveProperty(this->Property, contextLG, contextConfig,
|
->IsTransitiveProperty(this->Property, contextLG, contextConfig, this)
|
||||||
this->EvaluatingLinkLibraries())
|
|
||||||
.has_value();
|
.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +194,11 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkerLauncher() const
|
|||||||
"_LINKER_LAUNCHER"_s;
|
"_LINKER_LAUNCHER"_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmGeneratorExpressionDAGChecker::IsComputingLinkLibraries() const
|
||||||
|
{
|
||||||
|
return this->Top->ComputingLinkLibraries_ == ComputingLinkLibraries::Yes;
|
||||||
|
}
|
||||||
|
|
||||||
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
|
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
|
||||||
cmGeneratorTarget const* tgt, ForGenex genex) const
|
cmGeneratorTarget const* tgt, ForGenex genex) const
|
||||||
{
|
{
|
||||||
|
@@ -17,12 +17,19 @@ class cmLocalGenerator;
|
|||||||
|
|
||||||
struct cmGeneratorExpressionDAGChecker
|
struct cmGeneratorExpressionDAGChecker
|
||||||
{
|
{
|
||||||
|
enum class ComputingLinkLibraries
|
||||||
|
{
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
cmGeneratorExpressionDAGChecker(
|
cmGeneratorExpressionDAGChecker(
|
||||||
cmGeneratorTarget const* target, std::string property,
|
cmGeneratorTarget const* target, std::string property,
|
||||||
GeneratorExpressionContent const* content,
|
GeneratorExpressionContent const* content,
|
||||||
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
|
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
|
||||||
std::string const& contextConfig,
|
std::string const& contextConfig,
|
||||||
cmListFileBacktrace backtrace = cmListFileBacktrace());
|
cmListFileBacktrace backtrace = cmListFileBacktrace(),
|
||||||
|
ComputingLinkLibraries computingLinkLibraries =
|
||||||
|
ComputingLinkLibraries::No);
|
||||||
|
|
||||||
enum Result
|
enum Result
|
||||||
{
|
{
|
||||||
@@ -45,6 +52,11 @@ struct cmGeneratorExpressionDAGChecker
|
|||||||
bool EvaluatingLinkOptionsExpression() const;
|
bool EvaluatingLinkOptionsExpression() const;
|
||||||
bool EvaluatingLinkerLauncher() const;
|
bool EvaluatingLinkerLauncher() const;
|
||||||
|
|
||||||
|
/** Returns true only when computing the actual link dependency
|
||||||
|
graph for cmGeneratorTarget::GetLinkImplementationLibraries
|
||||||
|
or cmGeneratorTarget::GetLinkInterfaceLibraries. */
|
||||||
|
bool IsComputingLinkLibraries() const;
|
||||||
|
|
||||||
enum class ForGenex
|
enum class ForGenex
|
||||||
{
|
{
|
||||||
ANY,
|
ANY,
|
||||||
@@ -78,4 +90,6 @@ private:
|
|||||||
bool TransitivePropertiesOnly = false;
|
bool TransitivePropertiesOnly = false;
|
||||||
bool CMP0131 = false;
|
bool CMP0131 = false;
|
||||||
bool TopIsTransitiveProperty = false;
|
bool TopIsTransitiveProperty = false;
|
||||||
|
ComputingLinkLibraries const ComputingLinkLibraries_ =
|
||||||
|
ComputingLinkLibraries::No;
|
||||||
};
|
};
|
||||||
|
@@ -2957,8 +2957,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||||||
|
|
||||||
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
|
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
|
||||||
target->IsTransitiveProperty(propertyName, context->LG,
|
target->IsTransitiveProperty(propertyName, context->LG,
|
||||||
context->Config,
|
context->Config, dagCheckerParent)) {
|
||||||
evaluatingLinkLibraries)) {
|
|
||||||
interfacePropertyName = std::string(transitiveProp->InterfaceName);
|
interfacePropertyName = std::string(transitiveProp->InterfaceName);
|
||||||
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
|
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
|
||||||
usage = transitiveProp->Usage;
|
usage = transitiveProp->Usage;
|
||||||
|
@@ -935,7 +935,8 @@ public:
|
|||||||
|
|
||||||
cm::optional<TransitiveProperty> IsTransitiveProperty(
|
cm::optional<TransitiveProperty> IsTransitiveProperty(
|
||||||
cm::string_view prop, cmLocalGenerator const* lg,
|
cm::string_view prop, cmLocalGenerator const* lg,
|
||||||
std::string const& config, bool evaluatingLinkLibraries) const;
|
std::string const& config,
|
||||||
|
cmGeneratorExpressionDAGChecker const* dagChecker) const;
|
||||||
|
|
||||||
bool HaveInstallTreeRPATH(const std::string& config) const;
|
bool HaveInstallTreeRPATH(const std::string& config) const;
|
||||||
|
|
||||||
|
@@ -565,7 +565,14 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
|
|||||||
}
|
}
|
||||||
// Keep this logic in sync with ComputeLinkImplementationLibraries.
|
// Keep this logic in sync with ComputeLinkImplementationLibraries.
|
||||||
cmGeneratorExpressionDAGChecker dagChecker{
|
cmGeneratorExpressionDAGChecker dagChecker{
|
||||||
this, prop, nullptr, nullptr, this->LocalGenerator, config,
|
this,
|
||||||
|
prop,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
this->LocalGenerator,
|
||||||
|
config,
|
||||||
|
cmListFileBacktrace(),
|
||||||
|
cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
|
||||||
};
|
};
|
||||||
// The $<LINK_ONLY> expression may be in a link interface to specify
|
// The $<LINK_ONLY> expression may be in a link interface to specify
|
||||||
// private link dependencies that are otherwise excluded from usage
|
// private link dependencies that are otherwise excluded from usage
|
||||||
@@ -1322,7 +1329,14 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
|
|||||||
for (auto const& entry : entryRange) {
|
for (auto const& entry : entryRange) {
|
||||||
// Keep this logic in sync with ExpandLinkItems.
|
// Keep this logic in sync with ExpandLinkItems.
|
||||||
cmGeneratorExpressionDAGChecker dagChecker{
|
cmGeneratorExpressionDAGChecker dagChecker{
|
||||||
this, "LINK_LIBRARIES", nullptr, nullptr, this->LocalGenerator, config,
|
this,
|
||||||
|
"LINK_LIBRARIES",
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
this->LocalGenerator,
|
||||||
|
config,
|
||||||
|
cmListFileBacktrace(),
|
||||||
|
cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
|
||||||
};
|
};
|
||||||
// The $<LINK_ONLY> expression may be used to specify link dependencies
|
// The $<LINK_ONLY> expression may be used to specify link dependencies
|
||||||
// that are otherwise excluded from usage requirements.
|
// that are otherwise excluded from usage requirements.
|
||||||
|
@@ -183,10 +183,9 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cm::optional<cmGeneratorTarget::TransitiveProperty>
|
cm::optional<cmGeneratorTarget::TransitiveProperty>
|
||||||
cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
|
cmGeneratorTarget::IsTransitiveProperty(
|
||||||
cmLocalGenerator const* lg,
|
cm::string_view prop, cmLocalGenerator const* lg, std::string const& config,
|
||||||
std::string const& config,
|
cmGeneratorExpressionDAGChecker const* dagChecker) const
|
||||||
bool evaluatingLinkLibraries) const
|
|
||||||
{
|
{
|
||||||
cm::optional<TransitiveProperty> result;
|
cm::optional<TransitiveProperty> result;
|
||||||
static const cm::string_view kINTERFACE_ = "INTERFACE_"_s;
|
static const cm::string_view kINTERFACE_ = "INTERFACE_"_s;
|
||||||
@@ -215,7 +214,7 @@ cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
|
|||||||
result = TransitiveProperty{ "INTERFACE_COMPILE_DEFINITIONS"_s,
|
result = TransitiveProperty{ "INTERFACE_COMPILE_DEFINITIONS"_s,
|
||||||
UseTo::Compile };
|
UseTo::Compile };
|
||||||
}
|
}
|
||||||
} else if (!evaluatingLinkLibraries) {
|
} else if (!dagChecker || !dagChecker->IsComputingLinkLibraries()) {
|
||||||
// Honor TRANSITIVE_COMPILE_PROPERTIES and TRANSITIVE_LINK_PROPERTIES
|
// Honor TRANSITIVE_COMPILE_PROPERTIES and TRANSITIVE_LINK_PROPERTIES
|
||||||
// from the link closure when we are not evaluating the closure itself.
|
// from the link closure when we are not evaluating the closure itself.
|
||||||
CustomTransitiveProperties const& ctp =
|
CustomTransitiveProperties const& ctp =
|
||||||
|
@@ -200,14 +200,12 @@ add_custom_target(check ALL VERBATIM
|
|||||||
# / \
|
# / \
|
||||||
# "static10[iface11];iface11[iface10]"
|
# "static10[iface11];iface11[iface10]"
|
||||||
"$<TARGET_PROPERTY:static10,INTERFACE_LINK_LIBRARIES>" "iface11;iface10"
|
"$<TARGET_PROPERTY:static10,INTERFACE_LINK_LIBRARIES>" "iface11;iface10"
|
||||||
"$<TARGET_PROPERTY:static11,LINK_LIBRARIES>" "static10;iface11;iface11;iface10;iface10"
|
"$<TARGET_PROPERTY:static11,LINK_LIBRARIES>" "static10;iface11;iface11;iface10"
|
||||||
# / / \ \ \___ extra!
|
|
||||||
# __/ __/ \__ \__________
|
# __/ __/ \__ \__________
|
||||||
# / / \ \
|
# / / \ \
|
||||||
# "static11[static10;iface11];static10[iface11;iface11[iface10]]"
|
# "static11[static10;iface11];static10[iface11;iface11[iface10]]"
|
||||||
"$<TARGET_PROPERTY:static11,INTERFACE_LINK_LIBRARIES>" "static10;iface11;iface11;iface10;iface10"
|
"$<TARGET_PROPERTY:static11,INTERFACE_LINK_LIBRARIES>" "static10;iface11;iface11;iface10"
|
||||||
"$<TARGET_PROPERTY:main10,LINK_LIBRARIES>" "static11;static10;static10;iface11;iface11;iface10;iface10;iface11;iface10"
|
"$<TARGET_PROPERTY:main10,LINK_LIBRARIES>" "static11;static10;static10;iface11;iface11;iface10"
|
||||||
# / / | | \ \ \_______\_______\____ extra!
|
|
||||||
# _______/ _______/ | | \______ \______________
|
# _______/ _______/ | | \______ \______________
|
||||||
# / / | | \ \
|
# / / | | \ \
|
||||||
# "main10[static11;static10];static11[static10;iface11;static10[iface11;iface11[iface10]]]"
|
# "main10[static11;static10];static11[static10;iface11;static10[iface11;iface11[iface10]]]"
|
||||||
|
@@ -47,9 +47,9 @@ iface11 LINK_LIBRARIES: ''
|
|||||||
iface11 INTERFACE_LINK_LIBRARIES: 'iface10'
|
iface11 INTERFACE_LINK_LIBRARIES: 'iface10'
|
||||||
static10 LINK_LIBRARIES: 'iface11;iface10'
|
static10 LINK_LIBRARIES: 'iface11;iface10'
|
||||||
static10 INTERFACE_LINK_LIBRARIES: 'iface11;iface10'
|
static10 INTERFACE_LINK_LIBRARIES: 'iface11;iface10'
|
||||||
static11 LINK_LIBRARIES: 'static10;iface11;iface11;iface10;iface10'
|
static11 LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||||
static11 INTERFACE_LINK_LIBRARIES: 'static10;iface11;iface11;iface10;iface10'
|
static11 INTERFACE_LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||||
main10 LINK_LIBRARIES: 'static11;static10;static10;iface11;iface11;iface10;iface10;iface11;iface10'
|
main10 LINK_LIBRARIES: 'static11;static10;static10;iface11;iface11;iface10'
|
||||||
main10 INTERFACE_LINK_LIBRARIES: ''
|
main10 INTERFACE_LINK_LIBRARIES: ''
|
||||||
]])
|
]])
|
||||||
string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
|
string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
|
||||||
|
Reference in New Issue
Block a user