Merge topic 'backport-3.30-custom-transitive-properties' into release-3.30

8b5af40b34 GenEx: Fix evaluation of LINK_LIBRARIES as custom transitive property
161f703e76 GenEx: Restore evaluation context for conditional transitive properties
419c19d531 Tests: Extend CustomTransitiveProperties with custom transitive LINK_LIBRARIES
ff2004d430 Tests: Extend CustomTransitiveProperties with non-transitive LINK_LIBRARIES
d7f1a100d9 Tests: Split CustomTransitiveProperties argument checks into helper
99fee5720d cmGeneratorExpressionDAGChecker: De-duplicate constructor signature
82151ea289 cmGeneratorExpressionDAGChecker: Construct with initializer list syntax

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !10384
This commit is contained in:
Brad King
2025-02-24 09:17:13 -05:00
23 changed files with 311 additions and 141 deletions
+4 -3
View File
@@ -500,9 +500,10 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
std::string propName = lang + "_LINKER_LAUNCHER";
cmValue launcherProp = this->GeneratorTarget->GetProperty(propName);
if (cmNonempty(launcherProp)) {
cmGeneratorExpressionDAGChecker dagChecker(
this->GeneratorTarget, propName, nullptr, nullptr,
this->LocalCommonGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this->GeneratorTarget, propName, nullptr, nullptr,
this->LocalCommonGenerator, config,
};
std::string evaluatedLinklauncher = cmGeneratorExpression::Evaluate(
*launcherProp, this->LocalCommonGenerator, config, this->GeneratorTarget,
&dagChecker, this->GeneratorTarget, lang);
+15 -13
View File
@@ -583,18 +583,18 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
if (cmValue feature = this->Target->GetProperty(key)) {
if (!feature->empty() && key.length() > lloPrefix.length()) {
auto item = key.substr(lloPrefix.length());
cmGeneratorExpressionDAGChecker dag{
this->Target->GetBacktrace(),
cmGeneratorExpressionDAGChecker dagChecker{
this->Target,
"LINK_LIBRARY_OVERRIDE",
nullptr,
nullptr,
this->Target->GetLocalGenerator(),
config
config,
this->Target->GetBacktrace(),
};
auto overrideFeature = cmGeneratorExpression::Evaluate(
*feature, this->Target->GetLocalGenerator(), config,
this->Target, &dag, this->Target, linkLanguage);
this->Target, &dagChecker, this->Target, linkLanguage);
this->LinkLibraryOverride.emplace(item, overrideFeature);
}
}
@@ -603,16 +603,18 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
// global override property
if (cmValue linkLibraryOverride =
this->Target->GetProperty("LINK_LIBRARY_OVERRIDE")) {
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(),
target,
"LINK_LIBRARY_OVERRIDE",
nullptr,
nullptr,
target->GetLocalGenerator(),
config };
cmGeneratorExpressionDAGChecker dagChecker{
target,
"LINK_LIBRARY_OVERRIDE",
nullptr,
nullptr,
target->GetLocalGenerator(),
config,
target->GetBacktrace(),
};
auto overrideValue = cmGeneratorExpression::Evaluate(
*linkLibraryOverride, target->GetLocalGenerator(), config, target, &dag,
target, linkLanguage);
*linkLibraryOverride, target->GetLocalGenerator(), config, target,
&dagChecker, target, linkLanguage);
auto overrideList = cmTokenize(overrideValue, ","_s);
if (overrideList.size() >= 2) {
+8 -3
View File
@@ -79,9 +79,14 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
tgt, "LINK_OPTIONS", nullptr, nullptr, tgt->GetLocalGenerator(),
this->Config);
}
cmGeneratorExpressionDAGChecker dagChecker(
tgt, propName, nullptr, parentDagChecker.get(), tgt->GetLocalGenerator(),
this->Config);
cmGeneratorExpressionDAGChecker dagChecker{
tgt,
propName,
nullptr,
parentDagChecker.get(),
tgt->GetLocalGenerator(),
this->Config,
};
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
+7 -3
View File
@@ -422,10 +422,14 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
this->GeneratorExpression.Parse(std::move(expression));
// Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
cmGeneratorExpressionDAGChecker dagChecker(
cmGeneratorExpressionDAGChecker dagChecker{
this->HeadTarget,
property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
nullptr, this->LocalGenerator, this->Config);
property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property,
nullptr,
nullptr,
this->LocalGenerator,
this->Config,
};
return this->CompiledGeneratorExpression->Evaluate(
this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
+10 -15
View File
@@ -19,34 +19,24 @@
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmGeneratorTarget const* target, std::string property,
const GeneratorExpressionContent* content,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
std::string const& contextConfig)
: cmGeneratorExpressionDAGChecker(cmListFileBacktrace(), target,
std::move(property), content, parent,
contextLG, contextConfig)
{
}
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmListFileBacktrace backtrace, cmGeneratorTarget const* target,
std::string property, const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
std::string const& contextConfig)
std::string const& contextConfig, cmListFileBacktrace backtrace,
ComputingLinkLibraries computingLinkLibraries)
: Parent(parent)
, Top(parent ? parent->Top : this)
, Target(target)
, Property(std::move(property))
, Content(content)
, Backtrace(std::move(backtrace))
, ComputingLinkLibraries_(computingLinkLibraries)
{
if (parent) {
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
} else {
this->TopIsTransitiveProperty =
this->Target
->IsTransitiveProperty(this->Property, contextLG, contextConfig,
this->EvaluatingLinkLibraries())
->IsTransitiveProperty(this->Property, contextLG, contextConfig, this)
.has_value();
}
@@ -204,6 +194,11 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkerLauncher() const
"_LINKER_LAUNCHER"_s;
}
bool cmGeneratorExpressionDAGChecker::IsComputingLinkLibraries() const
{
return this->Top->ComputingLinkLibraries_ == ComputingLinkLibraries::Yes;
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
cmGeneratorTarget const* tgt, ForGenex genex) const
{
+20 -13
View File
@@ -17,19 +17,19 @@ class cmLocalGenerator;
struct cmGeneratorExpressionDAGChecker
{
cmGeneratorExpressionDAGChecker(cmListFileBacktrace backtrace,
cmGeneratorTarget const* target,
std::string property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent,
cmLocalGenerator const* contextLG,
std::string const& contextConfig);
cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
std::string property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent,
cmLocalGenerator const* contextLG,
std::string const& contextConfig);
enum class ComputingLinkLibraries
{
No,
Yes,
};
cmGeneratorExpressionDAGChecker(
cmGeneratorTarget const* target, std::string property,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
std::string const& contextConfig,
cmListFileBacktrace backtrace = cmListFileBacktrace(),
ComputingLinkLibraries computingLinkLibraries =
ComputingLinkLibraries::No);
enum Result
{
@@ -52,6 +52,11 @@ struct cmGeneratorExpressionDAGChecker
bool EvaluatingLinkOptionsExpression() 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
{
ANY,
@@ -85,4 +90,6 @@ private:
bool TransitivePropertiesOnly = false;
bool CMP0131 = false;
bool TopIsTransitiveProperty = false;
ComputingLinkLibraries const ComputingLinkLibraries_ =
ComputingLinkLibraries::No;
};
+19 -9
View File
@@ -485,10 +485,15 @@ protected:
cmGeneratorExpressionDAGChecker* dagCheckerParent) const
{
if (context->HeadTarget) {
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, context->HeadTarget,
genexOperator + ":" + expression, content, dagCheckerParent,
context->LG, context->Config);
cmGeneratorExpressionDAGChecker dagChecker{
context->HeadTarget,
genexOperator + ":" + expression,
content,
dagCheckerParent,
context->LG,
context->Config,
context->Backtrace,
};
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
@@ -2952,8 +2957,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
target->IsTransitiveProperty(propertyName, context->LG,
context->Config,
evaluatingLinkLibraries)) {
context->Config, dagCheckerParent)) {
interfacePropertyName = std::string(transitiveProp->InterfaceName);
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
usage = transitiveProp->Usage;
@@ -2987,9 +2991,15 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
dagCheckerParent, usage));
}
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, target, propertyName, content, dagCheckerParent,
context->LG, context->Config);
cmGeneratorExpressionDAGChecker dagChecker{
target,
propertyName,
content,
dagCheckerParent,
context->LG,
context->Config,
context->Backtrace,
};
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+10 -7
View File
@@ -711,8 +711,9 @@ std::string cmGeneratorTarget::GetLinkerTypeProperty(
std::string propName{ "LINKER_TYPE" };
auto linkerType = this->GetProperty(propName);
if (!linkerType.IsEmpty()) {
cmGeneratorExpressionDAGChecker dagChecker(
this, propName, nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, propName, nullptr, nullptr, this->LocalGenerator, config,
};
auto ltype =
cmGeneratorExpression::Evaluate(*linkerType, this->GetLocalGenerator(),
config, this, &dagChecker, this, lang);
@@ -1176,9 +1177,10 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
auto iter = this->SystemIncludesCache.find(key);
if (iter == this->SystemIncludesCache.end()) {
cmGeneratorExpressionDAGChecker dagChecker(
this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr,
nullptr, this->LocalGenerator, config,
};
bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
@@ -1938,8 +1940,9 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
return;
}
cmGeneratorExpressionDAGChecker dagChecker(
this, "AUTOUIC_OPTIONS", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "AUTOUIC_OPTIONS", nullptr, nullptr, this->LocalGenerator, config,
};
cmExpandList(cmGeneratorExpression::Evaluate(prop, this->LocalGenerator,
config, this, &dagChecker),
result);
+2 -1
View File
@@ -935,7 +935,8 @@ public:
cm::optional<TransitiveProperty> IsTransitiveProperty(
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;
+26 -15
View File
@@ -47,13 +47,18 @@ std::string AddLangSpecificInterfaceIncludeDirectories(
const std::string& propertyName, IncludeDirectoryFallBack mode,
cmGeneratorExpressionDAGChecker* context)
{
cmGeneratorExpressionDAGChecker dag{
target->GetBacktrace(), target, propertyName, nullptr, context,
target->GetLocalGenerator(), config
cmGeneratorExpressionDAGChecker dagChecker{
target,
propertyName,
nullptr,
context,
target->GetLocalGenerator(),
config,
target->GetBacktrace(),
};
switch (dag.Check()) {
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dag.ReportError(
dagChecker.ReportError(
nullptr, "$<TARGET_PROPERTY:" + target->GetName() + ",propertyName");
CM_FALLTHROUGH;
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
@@ -100,9 +105,14 @@ void AddLangSpecificImplicitIncludeDirectories(
{
if (const auto* libraries =
target->GetLinkImplementationLibraries(config, UseTo::Compile)) {
cmGeneratorExpressionDAGChecker dag{
target->GetBacktrace(), target, propertyName, nullptr, nullptr,
target->GetLocalGenerator(), config
cmGeneratorExpressionDAGChecker dagChecker{
target,
propertyName,
nullptr,
nullptr,
target->GetLocalGenerator(),
config,
target->GetBacktrace(),
};
for (const cmLinkImplItem& library : libraries->Libraries) {
@@ -128,10 +138,10 @@ void AddLangSpecificImplicitIncludeDirectories(
}
}
cmExpandList(
AddLangSpecificInterfaceIncludeDirectories(
target, dependency, lang, config, propertyName, mode, &dag),
entry.Values);
cmExpandList(AddLangSpecificInterfaceIncludeDirectories(
target, dependency, lang, config, propertyName, mode,
&dagChecker),
entry.Values);
entries.Entries.emplace_back(std::move(entry));
}
}
@@ -257,9 +267,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
std::vector<BT<std::string>> includes;
std::unordered_set<std::string> uniqueIncludes;
cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "INCLUDE_DIRECTORIES", nullptr,
nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
+20 -4
View File
@@ -564,8 +564,16 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
return;
}
// Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this,
prop,
nullptr,
nullptr,
this->LocalGenerator,
config,
cmListFileBacktrace(),
cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
};
// The $<LINK_ONLY> expression may be in a link interface to specify
// private link dependencies that are otherwise excluded from usage
// requirements.
@@ -1320,8 +1328,16 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
// Collect libraries directly linked in this configuration.
for (auto const& entry : entryRange) {
// Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(
this, "LINK_LIBRARIES", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this,
"LINK_LIBRARIES",
nullptr,
nullptr,
this->LocalGenerator,
config,
cmListFileBacktrace(),
cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
};
// The $<LINK_ONLY> expression may be used to specify link dependencies
// that are otherwise excluded from usage requirements.
if (usage == UseTo::Compile) {
+3 -2
View File
@@ -125,8 +125,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueDirectories;
cmGeneratorExpressionDAGChecker dagChecker(
this, "LINK_DIRECTORIES", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "LINK_DIRECTORIES", nullptr, nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
+23 -17
View File
@@ -217,8 +217,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(
this, "COMPILE_OPTIONS", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "COMPILE_OPTIONS", nullptr, nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -258,8 +259,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueFeatures;
cmGeneratorExpressionDAGChecker dagChecker(
this, "COMPILE_FEATURES", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "COMPILE_FEATURES", nullptr, nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -308,9 +310,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
std::vector<BT<std::string>> list;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "COMPILE_DEFINITIONS", nullptr,
nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -373,9 +376,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
}
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "PRECOMPILE_HEADERS", nullptr, nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -432,8 +435,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(
this, "LINK_OPTIONS", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "LINK_OPTIONS", nullptr, nullptr, this->LocalGenerator, config,
};
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -601,9 +605,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "STATIC_LIBRARY_OPTIONS", nullptr,
nullptr, this->LocalGenerator, config,
};
EvaluatedTargetPropertyEntries entries;
if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
@@ -634,8 +639,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
{
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(
this, "LINK_DEPENDS", nullptr, nullptr, this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "LINK_DEPENDS", nullptr, nullptr, this->LocalGenerator, config,
};
EvaluatedTargetPropertyEntries entries;
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
+3 -2
View File
@@ -264,8 +264,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
this->DebugSourcesDone = true;
}
cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, nullptr,
this->LocalGenerator, config);
cmGeneratorExpressionDAGChecker dagChecker{
this, "SOURCES", nullptr, nullptr, this->LocalGenerator, config,
};
EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
this, config, std::string(), &dagChecker, this->SourceEntries);
@@ -109,9 +109,15 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
// Evaluate $<TARGET_PROPERTY:this,prop> as if it were compiled. This is
// a subset of TargetPropertyNode::Evaluate without stringify/parse steps
// but sufficient for transitive interface properties.
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, this, prop, nullptr, dagCheckerParent,
this->LocalGenerator, context->Config);
cmGeneratorExpressionDAGChecker dagChecker{
this,
prop,
nullptr,
dagCheckerParent,
context->LG,
context->Config,
context->Backtrace,
};
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.ReportError(
@@ -177,10 +183,9 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
cm::optional<cmGeneratorTarget::TransitiveProperty>
cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
cmLocalGenerator const* lg,
std::string const& config,
bool evaluatingLinkLibraries) const
cmGeneratorTarget::IsTransitiveProperty(
cm::string_view prop, cmLocalGenerator const* lg, std::string const& config,
cmGeneratorExpressionDAGChecker const* dagChecker) const
{
cm::optional<TransitiveProperty> result;
static const cm::string_view kINTERFACE_ = "INTERFACE_"_s;
@@ -209,7 +214,7 @@ cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
result = TransitiveProperty{ "INTERFACE_COMPILE_DEFINITIONS"_s,
UseTo::Compile };
}
} else if (!evaluatingLinkLibraries) {
} else if (!dagChecker || !dagChecker->IsComputingLinkLibraries()) {
// Honor TRANSITIVE_COMPILE_PROPERTIES and TRANSITIVE_LINK_PROPERTIES
// from the link closure when we are not evaluating the closure itself.
CustomTransitiveProperties const& ctp =
+8 -6
View File
@@ -1923,9 +1923,10 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
if (this->MultiConfig) {
for (auto const& cfg : this->ConfigsList) {
if (!cfg.empty()) {
cmGeneratorExpressionDAGChecker dagChecker(
this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr,
this->LocalGen, cfg);
cmGeneratorExpressionDAGChecker dagChecker{
this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr,
nullptr, this->LocalGen, cfg,
};
AddInterfaceEntries(this->GenTarget, cfg,
"INTERFACE_AUTOMOC_MACRO_NAMES", "CXX",
&dagChecker, InterfaceAutoMocMacroNamesEntries,
@@ -1933,9 +1934,10 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
}
}
} else {
cmGeneratorExpressionDAGChecker dagChecker(
this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr,
this->LocalGen, this->ConfigDefault);
cmGeneratorExpressionDAGChecker dagChecker{
this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr,
nullptr, this->LocalGen, this->ConfigDefault,
};
AddInterfaceEntries(this->GenTarget, this->ConfigDefault,
"INTERFACE_AUTOMOC_MACRO_NAMES", "CXX", &dagChecker,
InterfaceAutoMocMacroNamesEntries,
@@ -90,9 +90,22 @@ target_compile_definitions(CustomTransitiveProperties PRIVATE
$<TARGET_PROPERTY:CUSTOM_W>
)
# Test TRANSITIVE_LINK_PROPERTIES containing LINK_LIBRARIES itself.
add_library(iface10 INTERFACE)
set_property(TARGET iface10 PROPERTY TRANSITIVE_LINK_PROPERTIES "LINK_LIBRARIES")
add_library(iface11 INTERFACE)
target_link_libraries(iface11 INTERFACE iface10)
add_library(static10 STATIC static10.c)
target_link_libraries(static10 PRIVATE iface11)
add_library(static11 STATIC static11.c)
target_link_libraries(static11 PRIVATE static10 iface11)
add_executable(main10 main10.c)
target_link_libraries(main10 PRIVATE static11 static10)
# Test TRANSITIVE_*_PROPERTY evaluation outside of usage requirements.
add_executable(check-args check-args.c)
set(out "${CMAKE_CURRENT_BINARY_DIR}/out-$<CONFIG>.txt")
file(GENERATE OUTPUT "${out}" CONTENT "# file(GENERATE) produced:
set(in_CUSTOM [====[
iface1 CUSTOM_A: '$<TARGET_PROPERTY:iface1,CUSTOM_A>'
iface1 INTERFACE_CUSTOM_A: '$<TARGET_PROPERTY:iface1,INTERFACE_CUSTOM_A>'
iface2 CUSTOM_A: '$<TARGET_PROPERTY:iface2,CUSTOM_A>'
@@ -125,10 +138,35 @@ main CUSTOM_V: '$<TARGET_PROPERTY:CustomTransitiveProperties,CUSTOM_V>'
main INTERFACE_CUSTOM_V: '$<TARGET_PROPERTY:CustomTransitiveProperties,INTERFACE_CUSTOM_V>'
main CUSTOM_W: '$<TARGET_PROPERTY:CustomTransitiveProperties,CUSTOM_W>'
main INTERFACE_CUSTOM_W: '$<TARGET_PROPERTY:CustomTransitiveProperties,INTERFACE_CUSTOM_W>'
]====])
set(in_LINK_LIBRARIES [====[
iface1 LINK_LIBRARIES: '$<TARGET_PROPERTY:iface1,LINK_LIBRARIES>'
iface1 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:iface1,INTERFACE_LINK_LIBRARIES>'
iface2 LINK_LIBRARIES: '$<TARGET_PROPERTY:iface2,LINK_LIBRARIES>'
iface2 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:iface2,INTERFACE_LINK_LIBRARIES>'
static1 LINK_LIBRARIES: '$<TARGET_PROPERTY:static1,LINK_LIBRARIES>'
static1 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:static1,INTERFACE_LINK_LIBRARIES>'
main LINK_LIBRARIES: '$<TARGET_PROPERTY:CustomTransitiveProperties,LINK_LIBRARIES>'
main INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:CustomTransitiveProperties,INTERFACE_LINK_LIBRARIES>'
iface10 LINK_LIBRARIES: '$<TARGET_PROPERTY:iface10,LINK_LIBRARIES>'
iface10 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:iface10,INTERFACE_LINK_LIBRARIES>'
iface11 LINK_LIBRARIES: '$<TARGET_PROPERTY:iface11,LINK_LIBRARIES>'
iface11 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:iface11,INTERFACE_LINK_LIBRARIES>'
static10 LINK_LIBRARIES: '$<TARGET_PROPERTY:static10,LINK_LIBRARIES>'
static10 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:static10,INTERFACE_LINK_LIBRARIES>'
static11 LINK_LIBRARIES: '$<TARGET_PROPERTY:static11,LINK_LIBRARIES>'
static11 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:static11,INTERFACE_LINK_LIBRARIES>'
main10 LINK_LIBRARIES: '$<TARGET_PROPERTY:main10,LINK_LIBRARIES>'
main10 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:main10,INTERFACE_LINK_LIBRARIES>'
]====])
file(GENERATE OUTPUT "${out}" CONTENT "# file(GENERATE) produced:
${in_CUSTOM}
${in_LINK_LIBRARIES}
")
add_custom_target(check ALL VERBATIM
COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> -Dout=${out} -P${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
COMMAND CustomTransitiveProperties
COMMAND check-args
"$<TARGET_PROPERTY:static1,CUSTOM_A>" "CUSTOM_A_STATIC1;CUSTOM_A_IFACE2;CUSTOM_A_TARGET_TYPE_STATIC_LIBRARY;CUSTOM_A_IFACE1;CUSTOM_A_TARGET_NAME_STATIC1"
"$<TARGET_PROPERTY:static1,CUSTOM_B>" "CUSTOM_B_STATIC1;CUSTOM_B_IFACE1"
"$<TARGET_PROPERTY:static1,CUSTOM_U>" "CUSTOM_U_STATIC1;CUSTOM_U_IFACE2;CUSTOM_U_TARGET_TYPE_STATIC_LIBRARY;CUSTOM_U_IFACE1;CUSTOM_U_TARGET_NAME_STATIC1"
@@ -143,4 +181,33 @@ add_custom_target(check ALL VERBATIM
"$<TARGET_PROPERTY:CustomTransitiveProperties,CUSTOM_U>" "CUSTOM_U_MAIN;CUSTOM_U_STATIC1_IFACE;CUSTOM_U_IFACE2;CUSTOM_U_TARGET_TYPE_EXECUTABLE;CUSTOM_U_IFACE1;CUSTOM_U_TARGET_NAME_CUSTOMTRANSITIVEPROPERTIES;CUSTOM_U_OBJECT1_IFACE"
"$<TARGET_PROPERTY:CustomTransitiveProperties,CUSTOM_V>" "CUSTOM_V_MAIN;CUSTOM_V_STATIC1_IFACE;CUSTOM_V_IFACE1"
"$<TARGET_PROPERTY:CustomTransitiveProperties,CUSTOM_W>" "CUSTOM_W_MAIN;CUSTOM_W_IFACE1;CUSTOM_W_OBJECT1_IFACE"
COMMAND check-args
"$<TARGET_PROPERTY:iface1,LINK_LIBRARIES>" ""
"$<TARGET_PROPERTY:iface1,INTERFACE_LINK_LIBRARIES>" ""
"$<TARGET_PROPERTY:iface2,LINK_LIBRARIES>" ""
"$<TARGET_PROPERTY:iface2,INTERFACE_LINK_LIBRARIES>" "iface1"
"$<TARGET_PROPERTY:static1,LINK_LIBRARIES>" "iface2"
"$<TARGET_PROPERTY:static1,INTERFACE_LINK_LIBRARIES>" "$<LINK_ONLY:iface2$<ANGLE-R>"
"$<TARGET_PROPERTY:CustomTransitiveProperties,LINK_LIBRARIES>" "static1;object1"
"$<TARGET_PROPERTY:CustomTransitiveProperties,INTERFACE_LINK_LIBRARIES>" ""
COMMAND check-args
"$<TARGET_PROPERTY:iface10,LINK_LIBRARIES>" ""
"$<TARGET_PROPERTY:iface10,INTERFACE_LINK_LIBRARIES>" ""
"$<TARGET_PROPERTY:iface11,LINK_LIBRARIES>" ""
"$<TARGET_PROPERTY:iface11,INTERFACE_LINK_LIBRARIES>" "iface10"
"$<TARGET_PROPERTY:static10,LINK_LIBRARIES>" "iface11;iface10"
# _/ \__
# / \
# "static10[iface11];iface11[iface10]"
"$<TARGET_PROPERTY:static10,INTERFACE_LINK_LIBRARIES>" "iface11;iface10"
"$<TARGET_PROPERTY:static11,LINK_LIBRARIES>" "static10;iface11;iface11;iface10"
# __/ __/ \__ \__________
# / / \ \
# "static11[static10;iface11];static10[iface11;iface11[iface10]]"
"$<TARGET_PROPERTY:static11,INTERFACE_LINK_LIBRARIES>" "static10;iface11;iface11;iface10"
"$<TARGET_PROPERTY:main10,LINK_LIBRARIES>" "static11;static10;static10;iface11;iface11;iface10"
# _______/ _______/ | | \______ \______________
# / / | | \ \
# "main10[static11;static10];static11[static10;iface11;static10[iface11;iface11[iface10]]]"
"$<TARGET_PROPERTY:main10,INTERFACE_LINK_LIBRARIES>" ""
)
@@ -0,0 +1,16 @@
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv)
{
int result = 0;
int i;
for (i = 2; i < argc; i += 2) {
if (strcmp(argv[i - 1], argv[i]) != 0) {
fprintf(stderr, "Argument %d expected '%s' but got '%s'.\n", i, argv[i],
argv[i - 1]);
result = 1;
}
}
return result;
}
@@ -32,6 +32,25 @@ main CUSTOM_V: 'CUSTOM_V_MAIN;CUSTOM_V_STATIC1_IFACE;CUSTOM_V_IFACE1'
main INTERFACE_CUSTOM_V: ''
main CUSTOM_W: 'CUSTOM_W_MAIN;CUSTOM_W_IFACE1;CUSTOM_W_OBJECT1_IFACE'
main INTERFACE_CUSTOM_W: ''
iface1 LINK_LIBRARIES: ''
iface1 INTERFACE_LINK_LIBRARIES: ''
iface2 LINK_LIBRARIES: ''
iface2 INTERFACE_LINK_LIBRARIES: 'iface1'
static1 LINK_LIBRARIES: 'iface2'
static1 INTERFACE_LINK_LIBRARIES: '\$<LINK_ONLY:iface2>'
main LINK_LIBRARIES: 'static1;object1'
main INTERFACE_LINK_LIBRARIES: ''
iface10 LINK_LIBRARIES: ''
iface10 INTERFACE_LINK_LIBRARIES: ''
iface11 LINK_LIBRARIES: ''
iface11 INTERFACE_LINK_LIBRARIES: 'iface10'
static10 LINK_LIBRARIES: 'iface11;iface10'
static10 INTERFACE_LINK_LIBRARIES: 'iface11;iface10'
static11 LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
static11 INTERFACE_LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
main10 LINK_LIBRARIES: 'static11;static10;static10;iface11;iface11;iface10'
main10 INTERFACE_LINK_LIBRARIES: ''
]])
string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
string(REGEX REPLACE "\n+$" "" expect "${expect}")
+2 -19
View File
@@ -1,6 +1,3 @@
#include <stdio.h>
#include <string.h>
#ifdef CUSTOM_A_IFACE1
# error "CUSTOM_A_IFACE1 incorrectly defined"
#endif
@@ -117,21 +114,7 @@
extern int static1(void);
extern int object1(void);
int check_args(int argc, char** argv)
int main(void)
{
int result = 0;
int i;
for (i = 2; i < argc; i += 2) {
if (strcmp(argv[i - 1], argv[i]) != 0) {
fprintf(stderr, "Argument %d expected '%s' but got '%s'.\n", i, argv[i],
argv[i - 1]);
result = 1;
}
}
return result;
}
int main(int argc, char** argv)
{
return static1() + object1() + check_args(argc, argv);
return static1() + object1();
}
@@ -0,0 +1,7 @@
extern int static10(void);
extern int static11(void);
int main(void)
{
return static10() + static11();
}
@@ -0,0 +1,4 @@
int static10(void)
{
return 0;
}
@@ -0,0 +1,4 @@
int static11(void)
{
return 0;
}