summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCommonTargetGenerator.cxx6
-rw-r--r--Source/cmComputeLinkDepends.cxx6
-rw-r--r--Source/cmExportBuildFileGenerator.cxx2
-rw-r--r--Source/cmExportFileGenerator.cxx21
-rw-r--r--Source/cmExportFileGenerator.h4
-rw-r--r--Source/cmExportInstallFileGenerator.cxx2
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx6
-rw-r--r--Source/cmGeneratorExpression.cxx2
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx12
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h6
-rw-r--r--Source/cmGeneratorExpressionNode.cxx20
-rw-r--r--Source/cmGeneratorTarget.cxx16
-rw-r--r--Source/cmGeneratorTarget.h50
-rw-r--r--Source/cmGeneratorTarget_CompatibleInterface.cxx8
-rw-r--r--Source/cmGeneratorTarget_IncludeDirectories.cxx13
-rw-r--r--Source/cmGeneratorTarget_Link.cxx44
-rw-r--r--Source/cmGeneratorTarget_LinkDirectories.cxx4
-rw-r--r--Source/cmGeneratorTarget_Options.cxx31
-rw-r--r--Source/cmGeneratorTarget_Sources.cxx2
-rw-r--r--Source/cmGeneratorTarget_TransitiveProperty.cxx97
-rw-r--r--Source/cmQtAutoGenInitializer.cxx9
21 files changed, 284 insertions, 77 deletions
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index fbf39e2..9f25904 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -500,9 +500,9 @@ 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);
+ 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);
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index db0d71a..cc323f4 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -581,7 +581,8 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
"LINK_LIBRARY_OVERRIDE",
nullptr,
nullptr,
- this->Target->GetLocalGenerator()
+ this->Target->GetLocalGenerator(),
+ config
};
auto overrideFeature = cmGeneratorExpression::Evaluate(
*feature, this->Target->GetLocalGenerator(), config,
@@ -599,7 +600,8 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
"LINK_LIBRARY_OVERRIDE",
nullptr,
nullptr,
- target->GetLocalGenerator() };
+ target->GetLocalGenerator(),
+ config };
auto overrideValue = cmGeneratorExpression::Evaluate(
*linkLibraryOverride, target->GetLocalGenerator(), config, target, &dag,
target, linkLanguage);
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 2345d64..d877d76 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -152,6 +152,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
gte, cmGeneratorExpression::BuildInterface, properties);
}
this->PopulateCompatibleInterfaceProperties(gte, properties);
+ this->PopulateCustomTransitiveInterfaceProperties(
+ gte, cmGeneratorExpression::BuildInterface, properties);
this->GenerateInterfaceProperties(gte, os, properties);
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 9bd7f49..a5348f2 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -604,6 +604,27 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
}
}
+void cmExportFileGenerator::PopulateCustomTransitiveInterfaceProperties(
+ cmGeneratorTarget const* target,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ ImportPropertyMap& properties)
+{
+ this->PopulateInterfaceProperty("TRANSITIVE_COMPILE_PROPERTIES", target,
+ properties);
+ this->PopulateInterfaceProperty("TRANSITIVE_LINK_PROPERTIES", target,
+ properties);
+ std::set<std::string> ifaceProperties;
+ for (std::string const& config : this->Configurations) {
+ for (auto const& i : target->GetCustomTransitiveProperties(
+ config, cmGeneratorTarget::PropertyFor::Interface)) {
+ ifaceProperties.emplace(i.second.InterfaceName);
+ }
+ }
+ for (std::string const& ip : ifaceProperties) {
+ this->PopulateInterfaceProperty(ip, target, preprocessRule, properties);
+ }
+}
+
void cmExportFileGenerator::GenerateInterfaceProperties(
const cmGeneratorTarget* target, std::ostream& os,
const ImportPropertyMap& properties)
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index f619576..f275a12 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -145,6 +145,10 @@ protected:
ImportPropertyMap& properties);
void PopulateCompatibleInterfaceProperties(cmGeneratorTarget const* target,
ImportPropertyMap& properties);
+ void PopulateCustomTransitiveInterfaceProperties(
+ cmGeneratorTarget const* target,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ ImportPropertyMap& properties);
virtual void GenerateInterfaceProperties(
cmGeneratorTarget const* target, std::ostream& os,
const ImportPropertyMap& properties);
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 5c95ecd..f5f22ef 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -160,6 +160,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
properties);
this->PopulateCompatibleInterfaceProperties(gt, properties);
+ this->PopulateCustomTransitiveInterfaceProperties(
+ gt, cmGeneratorExpression::InstallInterface, properties);
this->GenerateInterfaceProperties(gt, os, properties);
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 4c41ff5..7ce5cd9 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -76,10 +76,12 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
// To please constraint checks of DAGChecker, this property must have
// LINK_OPTIONS property as parent
parentDagChecker = cm::make_unique<cmGeneratorExpressionDAGChecker>(
- tgt, "LINK_OPTIONS", nullptr, nullptr, tgt->GetLocalGenerator());
+ tgt, "LINK_OPTIONS", nullptr, nullptr, tgt->GetLocalGenerator(),
+ this->Config);
}
cmGeneratorExpressionDAGChecker dagChecker(
- tgt, propName, nullptr, parentDagChecker.get(), tgt->GetLocalGenerator());
+ tgt, propName, nullptr, parentDagChecker.get(), tgt->GetLocalGenerator(),
+ this->Config);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 0583fd5..8e590fa 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -425,7 +425,7 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
cmGeneratorExpressionDAGChecker dagChecker(
this->HeadTarget,
property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
- nullptr, this->LocalGenerator);
+ nullptr, this->LocalGenerator, this->Config);
return this->CompiledGeneratorExpression->Evaluate(
this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index bb1f4b4..aad25f0 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -20,17 +20,19 @@
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmGeneratorTarget const* target, std::string property,
const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG)
+ cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
+ std::string const& contextConfig)
: cmGeneratorExpressionDAGChecker(cmListFileBacktrace(), target,
std::move(property), content, parent,
- contextLG)
+ contextLG, contextConfig)
{
}
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmListFileBacktrace backtrace, cmGeneratorTarget const* target,
std::string property, const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG)
+ cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
+ std::string const& contextConfig)
: Parent(parent)
, Top(parent ? parent->Top : this)
, Target(target)
@@ -42,7 +44,9 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
} else {
this->TopIsTransitiveProperty =
- this->Target->IsTransitiveProperty(this->Property, contextLG)
+ this->Target
+ ->IsTransitiveProperty(this->Property, contextLG, contextConfig,
+ this->EvaluatingLinkLibraries())
.has_value();
}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index b230188..8b0eea7 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -22,12 +22,14 @@ struct cmGeneratorExpressionDAGChecker
std::string property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent,
- cmLocalGenerator const* contextLG);
+ cmLocalGenerator const* contextLG,
+ std::string const& contextConfig);
cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
std::string property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent,
- cmLocalGenerator const* contextLG);
+ cmLocalGenerator const* contextLG,
+ std::string const& contextConfig);
enum Result
{
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 5945e41..01cd18d 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -488,7 +488,7 @@ protected:
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, context->HeadTarget,
genexOperator + ":" + expression, content, dagCheckerParent,
- context->LG);
+ context->LG, context->Config);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
@@ -2873,19 +2873,22 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return target->GetLinkerLanguage(context->Config);
}
+ bool const evaluatingLinkLibraries =
+ dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries();
+
std::string interfacePropertyName;
bool isInterfaceProperty = false;
cmGeneratorTarget::UseTo usage = cmGeneratorTarget::UseTo::Compile;
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
- target->IsTransitiveProperty(propertyName, context->LG)) {
+ target->IsTransitiveProperty(propertyName, context->LG,
+ context->Config,
+ evaluatingLinkLibraries)) {
interfacePropertyName = std::string(transitiveProp->InterfaceName);
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
usage = transitiveProp->Usage;
}
- bool evaluatingLinkLibraries = false;
-
if (dagCheckerParent) {
// This $<TARGET_PROPERTY:...> node has been reached while evaluating
// another target property value. Check that the outermost evaluation
@@ -2894,8 +2897,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
dagCheckerParent->EvaluatingPICExpression() ||
dagCheckerParent->EvaluatingLinkerLauncher()) {
// No check required.
- } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
- evaluatingLinkLibraries = true;
+ } else if (evaluatingLinkLibraries) {
if (!interfacePropertyName.empty()) {
reportError(
context, content->GetOriginalExpression(),
@@ -2915,9 +2917,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
dagCheckerParent, usage));
}
- cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, target,
- propertyName, content,
- dagCheckerParent, context->LG);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ context->Backtrace, target, propertyName, content, dagCheckerParent,
+ context->LG, context->Config);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index ce53316..aa3e36f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -511,11 +511,15 @@ void cmGeneratorTarget::ClearSourcesCache()
this->SourcesAreContextDependent = Tribool::Indeterminate;
this->Objects.clear();
this->VisitedConfigsForObjects.clear();
+ this->LinkImplClosureForLinkMap.clear();
+ this->LinkImplClosureForUsageMap.clear();
this->LinkImplMap.clear();
this->LinkImplUsageRequirementsOnlyMap.clear();
this->IncludeDirectoriesCache.clear();
this->CompileOptionsCache.clear();
this->CompileDefinitionsCache.clear();
+ this->CustomTransitiveBuildPropertiesMap.clear();
+ this->CustomTransitiveInterfacePropertiesMap.clear();
this->PrecompileHeadersCache.clear();
this->LinkOptionsCache.clear();
this->LinkDirectoriesCache.clear();
@@ -707,8 +711,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, propName, nullptr, nullptr, this->LocalGenerator, config);
auto ltype =
cmGeneratorExpression::Evaluate(*linkerType, this->GetLocalGenerator(),
config, this, &dagChecker, this, lang);
@@ -1174,7 +1178,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
if (iter == this->SystemIncludesCache.end()) {
cmGeneratorExpressionDAGChecker dagChecker(
this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr,
- this->LocalGenerator);
+ this->LocalGenerator, config);
bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
@@ -1186,7 +1190,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
}
std::vector<cmGeneratorTarget const*> const& deps =
- this->GetLinkImplementationClosure(config);
+ this->GetLinkImplementationClosure(config, UseTo::Compile);
for (cmGeneratorTarget const* dep : deps) {
handleSystemIncludesDep(this->LocalGenerator, dep, config, this,
&dagChecker, result, excludeImported, language);
@@ -1934,8 +1938,8 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
return;
}
- cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr,
- nullptr, this->LocalGenerator);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "AUTOUIC_OPTIONS", nullptr, nullptr, this->LocalGenerator, config);
cmExpandList(cmGeneratorExpression::Evaluate(prop, this->LocalGenerator,
config, this, &dagChecker),
result);
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 51f112e..8f27a91 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -892,6 +892,13 @@ public:
struct TransitiveProperty
{
+#if defined(__SUNPRO_CC) || (defined(__ibmxl__) && defined(__clang__))
+ TransitiveProperty(cm::string_view interfaceName, UseTo usage)
+ : InterfaceName(interfaceName)
+ , Usage(usage)
+ {
+ }
+#endif
cm::string_view InterfaceName;
UseTo Usage;
};
@@ -900,7 +907,8 @@ public:
BuiltinTransitiveProperties;
cm::optional<TransitiveProperty> IsTransitiveProperty(
- cm::string_view prop, cmLocalGenerator const* lg) const;
+ cm::string_view prop, cmLocalGenerator const* lg,
+ std::string const& config, bool evaluatingLinkLibraries) const;
bool HaveInstallTreeRPATH(const std::string& config) const;
@@ -982,6 +990,30 @@ public:
bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
std::string const& config);
+ class CustomTransitiveProperty : public TransitiveProperty
+ {
+ std::unique_ptr<std::string> InterfaceNameBuf;
+ CustomTransitiveProperty(std::unique_ptr<std::string> interfaceNameBuf,
+ UseTo usage);
+
+ public:
+ CustomTransitiveProperty(std::string interfaceName, UseTo usage);
+ };
+ struct CustomTransitiveProperties
+ : public std::map<std::string, CustomTransitiveProperty>
+ {
+ void Add(cmValue props, UseTo usage);
+ };
+
+ enum class PropertyFor
+ {
+ Build,
+ Interface,
+ };
+
+ CustomTransitiveProperties const& GetCustomTransitiveProperties(
+ std::string const& config, PropertyFor propertyFor) const;
+
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -1049,6 +1081,11 @@ private:
std::string const& base, std::string const& suffix,
std::string const& name, cmValue version) const;
+ mutable std::map<std::string, CustomTransitiveProperties>
+ CustomTransitiveBuildPropertiesMap;
+ mutable std::map<std::string, CustomTransitiveProperties>
+ CustomTransitiveInterfacePropertiesMap;
+
struct CompatibleInterfacesBase
{
std::set<std::string> PropsBool;
@@ -1080,7 +1117,8 @@ private:
{
bool Done = false;
};
- mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
+ mutable std::map<std::string, LinkImplClosure> LinkImplClosureForLinkMap;
+ mutable std::map<std::string, LinkImplClosure> LinkImplClosureForUsageMap;
using LinkInterfaceMapType = std::map<std::string, cmHeadToLinkInterfaceMap>;
mutable LinkInterfaceMapType LinkInterfaceMap;
@@ -1298,9 +1336,15 @@ private:
void ComputeLinkInterfaceRuntimeLibraries(
const std::string& config, cmOptionalLinkInterface& iface) const;
+ // If this method is made public, or call sites are added outside of
+ // methods computing cached members, add dedicated caching members.
+ std::vector<cmGeneratorTarget const*> GetLinkInterfaceClosure(
+ std::string const& config, cmGeneratorTarget const* headTarget,
+ UseTo usage) const;
+
public:
const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
- const std::string& config) const;
+ const std::string& config, UseTo usage) const;
mutable std::map<std::string, std::string> MaxLanguageStandards;
std::map<std::string, std::string> const& GetMaxLanguageStandards() const
diff --git a/Source/cmGeneratorTarget_CompatibleInterface.cxx b/Source/cmGeneratorTarget_CompatibleInterface.cxx
index b6eb373..3af205e 100644
--- a/Source/cmGeneratorTarget_CompatibleInterface.cxx
+++ b/Source/cmGeneratorTarget_CompatibleInterface.cxx
@@ -31,6 +31,10 @@
#include "cmSystemTools.h"
#include "cmValue.h"
+namespace {
+using UseTo = cmGeneratorTarget::UseTo;
+}
+
const cmGeneratorTarget::CompatibleInterfacesBase&
cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
{
@@ -41,7 +45,7 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
compat.PropsString.insert("AUTOUIC_OPTIONS");
std::vector<cmGeneratorTarget const*> const& deps =
- this->GetLinkImplementationClosure(config);
+ this->GetLinkImplementationClosure(config, UseTo::Compile);
for (cmGeneratorTarget const* li : deps) {
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
if (cmValue prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
@@ -573,7 +577,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet));
std::vector<cmGeneratorTarget const*> const& deps =
- tgt->GetLinkImplementationClosure(config);
+ tgt->GetLinkImplementationClosure(config, UseTo::Compile);
if (deps.empty()) {
return propContent;
diff --git a/Source/cmGeneratorTarget_IncludeDirectories.cxx b/Source/cmGeneratorTarget_IncludeDirectories.cxx
index eaa3959..2b45e1c 100644
--- a/Source/cmGeneratorTarget_IncludeDirectories.cxx
+++ b/Source/cmGeneratorTarget_IncludeDirectories.cxx
@@ -48,8 +48,8 @@ std::string AddLangSpecificInterfaceIncludeDirectories(
cmGeneratorExpressionDAGChecker* context)
{
cmGeneratorExpressionDAGChecker dag{
- target->GetBacktrace(), target, propertyName, nullptr, context,
- target->GetLocalGenerator()
+ target->GetBacktrace(), target, propertyName, nullptr, context,
+ target->GetLocalGenerator(), config
};
switch (dag.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
@@ -101,8 +101,8 @@ void AddLangSpecificImplicitIncludeDirectories(
if (const auto* libraries =
target->GetLinkImplementationLibraries(config, UseTo::Compile)) {
cmGeneratorExpressionDAGChecker dag{
- target->GetBacktrace(), target, propertyName, nullptr, nullptr,
- target->GetLocalGenerator()
+ target->GetBacktrace(), target, propertyName, nullptr, nullptr,
+ target->GetLocalGenerator(), config
};
for (const cmLinkImplItem& library : libraries->Libraries) {
@@ -254,8 +254,9 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
+ nullptr, nullptr,
+ this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
diff --git a/Source/cmGeneratorTarget_Link.cxx b/Source/cmGeneratorTarget_Link.cxx
index 3ab36b6..0799429 100644
--- a/Source/cmGeneratorTarget_Link.cxx
+++ b/Source/cmGeneratorTarget_Link.cxx
@@ -268,23 +268,40 @@ static void processILibs(const std::string& config,
cmGeneratorTarget const* headTarget,
cmLinkItem const& item, cmGlobalGenerator* gg,
std::vector<cmGeneratorTarget const*>& tgts,
- std::set<cmGeneratorTarget const*>& emitted)
+ std::set<cmGeneratorTarget const*>& emitted,
+ UseTo usage)
{
if (item.Target && emitted.insert(item.Target).second) {
tgts.push_back(item.Target);
if (cmLinkInterfaceLibraries const* iface =
- item.Target->GetLinkInterfaceLibraries(config, headTarget,
- UseTo::Compile)) {
+ item.Target->GetLinkInterfaceLibraries(config, headTarget, usage)) {
for (cmLinkItem const& lib : iface->Libraries) {
- processILibs(config, headTarget, lib, gg, tgts, emitted);
+ processILibs(config, headTarget, lib, gg, tgts, emitted, usage);
}
}
}
}
+std::vector<cmGeneratorTarget const*>
+cmGeneratorTarget::GetLinkInterfaceClosure(std::string const& config,
+ cmGeneratorTarget const* headTarget,
+ UseTo usage) const
+{
+ cmGlobalGenerator* gg = this->GetLocalGenerator()->GetGlobalGenerator();
+ std::vector<cmGeneratorTarget const*> tgts;
+ std::set<cmGeneratorTarget const*> emitted;
+ if (cmLinkInterfaceLibraries const* iface =
+ this->GetLinkInterfaceLibraries(config, headTarget, usage)) {
+ for (cmLinkItem const& lib : iface->Libraries) {
+ processILibs(config, headTarget, lib, gg, tgts, emitted, usage);
+ }
+ }
+ return tgts;
+}
+
const std::vector<const cmGeneratorTarget*>&
-cmGeneratorTarget::GetLinkImplementationClosure(
- const std::string& config) const
+cmGeneratorTarget::GetLinkImplementationClosure(const std::string& config,
+ UseTo usage) const
{
// There is no link implementation for targets that cannot compile sources.
if (!this->CanCompileSources()) {
@@ -292,18 +309,21 @@ cmGeneratorTarget::GetLinkImplementationClosure(
return empty;
}
- LinkImplClosure& tgts = this->LinkImplClosureMap[config];
+ LinkImplClosure& tgts =
+ (usage == UseTo::Compile ? this->LinkImplClosureForUsageMap[config]
+ : this->LinkImplClosureForLinkMap[config]);
if (!tgts.Done) {
tgts.Done = true;
std::set<cmGeneratorTarget const*> emitted;
cmLinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibraries(config, UseTo::Compile);
+ this->GetLinkImplementationLibraries(config, usage);
assert(impl);
for (cmLinkImplItem const& lib : impl->Libraries) {
processILibs(config, this, lib,
- this->LocalGenerator->GetGlobalGenerator(), tgts, emitted);
+ this->LocalGenerator->GetGlobalGenerator(), tgts, emitted,
+ usage);
}
}
return tgts;
@@ -518,7 +538,7 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
}
// Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr,
- this->LocalGenerator);
+ this->LocalGenerator, config);
// The $<LINK_ONLY> expression may be in a link interface to specify
// private link dependencies that are otherwise excluded from usage
// requirements.
@@ -1268,8 +1288,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "LINK_LIBRARIES", nullptr, nullptr, this->LocalGenerator, config);
// The $<LINK_ONLY> expression may be used to specify link dependencies
// that are otherwise excluded from usage requirements.
if (usage == UseTo::Compile) {
diff --git a/Source/cmGeneratorTarget_LinkDirectories.cxx b/Source/cmGeneratorTarget_LinkDirectories.cxx
index 0955dfb..bd89497 100644
--- a/Source/cmGeneratorTarget_LinkDirectories.cxx
+++ b/Source/cmGeneratorTarget_LinkDirectories.cxx
@@ -125,8 +125,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "LINK_DIRECTORIES", nullptr, nullptr, this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
diff --git a/Source/cmGeneratorTarget_Options.cxx b/Source/cmGeneratorTarget_Options.cxx
index 05f325d..f77ef72 100644
--- a/Source/cmGeneratorTarget_Options.cxx
+++ b/Source/cmGeneratorTarget_Options.cxx
@@ -217,8 +217,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "COMPILE_OPTIONS", nullptr, nullptr, this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -258,8 +258,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "COMPILE_FEATURES", nullptr, nullptr, this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -308,8 +308,9 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
+ nullptr, nullptr,
+ this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -372,8 +373,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
}
std::unordered_set<std::string> uniqueOptions;
- cmGeneratorExpressionDAGChecker dagChecker(
- this, "PRECOMPILE_HEADERS", nullptr, nullptr, this->LocalGenerator);
+ cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
+ nullptr, nullptr,
+ this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -430,8 +432,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "LINK_OPTIONS", nullptr, nullptr, this->LocalGenerator, config);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -599,8 +601,9 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
+ nullptr, nullptr,
+ this->LocalGenerator, config);
EvaluatedTargetPropertyEntries entries;
if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
@@ -631,8 +634,8 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "LINK_DEPENDS", nullptr, nullptr, this->LocalGenerator, config);
EvaluatedTargetPropertyEntries entries;
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
diff --git a/Source/cmGeneratorTarget_Sources.cxx b/Source/cmGeneratorTarget_Sources.cxx
index de18df5..94e8897 100644
--- a/Source/cmGeneratorTarget_Sources.cxx
+++ b/Source/cmGeneratorTarget_Sources.cxx
@@ -265,7 +265,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
}
cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, nullptr,
- this->LocalGenerator);
+ this->LocalGenerator, config);
EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
this, config, std::string(), &dagChecker, this->SourceEntries);
diff --git a/Source/cmGeneratorTarget_TransitiveProperty.cxx b/Source/cmGeneratorTarget_TransitiveProperty.cxx
index f5d9a1a..ac929eb 100644
--- a/Source/cmGeneratorTarget_TransitiveProperty.cxx
+++ b/Source/cmGeneratorTarget_TransitiveProperty.cxx
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>
@@ -19,6 +20,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionNode.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
@@ -107,9 +109,9 @@ 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);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ context->Backtrace, this, prop, nullptr, dagCheckerParent,
+ this->LocalGenerator, context->Config);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.ReportError(
@@ -176,11 +178,16 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
cm::optional<cmGeneratorTarget::TransitiveProperty>
cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
- cmLocalGenerator const* lg) const
+ cmLocalGenerator const* lg,
+ std::string const& config,
+ bool evaluatingLinkLibraries) const
{
cm::optional<TransitiveProperty> result;
static const cm::string_view kINTERFACE_ = "INTERFACE_"_s;
- if (cmHasPrefix(prop, kINTERFACE_)) {
+ PropertyFor const propertyFor = cmHasPrefix(prop, kINTERFACE_)
+ ? PropertyFor::Interface
+ : PropertyFor::Build;
+ if (propertyFor == PropertyFor::Interface) {
prop = prop.substr(kINTERFACE_.length());
}
auto i = BuiltinTransitiveProperties.find(prop);
@@ -202,6 +209,86 @@ cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
result = TransitiveProperty{ "INTERFACE_COMPILE_DEFINITIONS"_s,
UseTo::Compile };
}
+ } else if (!evaluatingLinkLibraries) {
+ // Honor TRANSITIVE_COMPILE_PROPERTIES and TRANSITIVE_LINK_PROPERTIES
+ // from the link closure when we are not evaluating the closure itself.
+ CustomTransitiveProperties const& ctp =
+ this->GetCustomTransitiveProperties(config, propertyFor);
+ auto ci = ctp.find(std::string(prop));
+ if (ci != ctp.end()) {
+ result = ci->second;
+ }
}
return result;
}
+
+cmGeneratorTarget::CustomTransitiveProperty::CustomTransitiveProperty(
+ std::string interfaceName, UseTo usage)
+ : CustomTransitiveProperty(
+ cm::make_unique<std::string>(std::move(interfaceName)), usage)
+{
+}
+cmGeneratorTarget::CustomTransitiveProperty::CustomTransitiveProperty(
+ std::unique_ptr<std::string> interfaceNameBuf, UseTo usage)
+ : TransitiveProperty{ *interfaceNameBuf, usage }
+ , InterfaceNameBuf(std::move(interfaceNameBuf))
+{
+}
+
+void cmGeneratorTarget::CustomTransitiveProperties::Add(cmValue props,
+ UseTo usage)
+{
+ if (props) {
+ cmList propsList(*props);
+ for (std::string p : propsList) {
+ std::string ip;
+ static const cm::string_view kINTERFACE_ = "INTERFACE_"_s;
+ if (cmHasPrefix(p, kINTERFACE_)) {
+ ip = std::move(p);
+ p = ip.substr(kINTERFACE_.length());
+ } else {
+ ip = cmStrCat(kINTERFACE_, p);
+ }
+ this->emplace(std::move(p),
+ CustomTransitiveProperty(std::move(ip), usage));
+ }
+ }
+}
+
+cmGeneratorTarget::CustomTransitiveProperties const&
+cmGeneratorTarget::GetCustomTransitiveProperties(std::string const& config,
+ PropertyFor propertyFor) const
+{
+ std::map<std::string, CustomTransitiveProperties>& ctpm =
+ propertyFor == PropertyFor::Build
+ ? this->CustomTransitiveBuildPropertiesMap
+ : this->CustomTransitiveInterfacePropertiesMap;
+ auto i = ctpm.find(config);
+ if (i == ctpm.end()) {
+ CustomTransitiveProperties ctp;
+ auto addTransitiveProperties = [this, &config, propertyFor,
+ &ctp](std::string const& tp, UseTo usage) {
+ // Add transitive properties named by the target itself.
+ ctp.Add(this->GetProperty(tp), usage);
+ // Add transitive properties named by the target's link dependencies.
+ if (propertyFor == PropertyFor::Build) {
+ for (cmGeneratorTarget const* gt :
+ this->GetLinkImplementationClosure(config, usage)) {
+ ctp.Add(gt->GetProperty(tp), usage);
+ }
+ } else {
+ // The set of custom transitive INTERFACE_ properties does not
+ // depend on the consumer. Use the target as its own head.
+ cmGeneratorTarget const* headTarget = this;
+ for (cmGeneratorTarget const* gt :
+ this->GetLinkInterfaceClosure(config, headTarget, usage)) {
+ ctp.Add(gt->GetProperty(tp), usage);
+ }
+ }
+ };
+ addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES", UseTo::Link);
+ addTransitiveProperties("TRANSITIVE_COMPILE_PROPERTIES", UseTo::Compile);
+ i = ctpm.emplace(config, std::move(ctp)).first;
+ }
+ return i->second;
+}
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 44af9ce..ee53a8e 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1918,14 +1918,14 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetBool("MOC_RELAXED_MODE", this->Moc.RelaxedMode);
info.SetBool("MOC_PATH_PREFIX", this->Moc.PathPrefix);
- cmGeneratorExpressionDAGChecker dagChecker(this->GenTarget,
- "AUTOMOC_MACRO_NAMES", nullptr,
- nullptr, this->LocalGen);
EvaluatedTargetPropertyEntries InterfaceAutoMocMacroNamesEntries;
if (this->MultiConfig) {
for (auto const& cfg : this->ConfigsList) {
if (!cfg.empty()) {
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr,
+ this->LocalGen, cfg);
AddInterfaceEntries(this->GenTarget, cfg,
"INTERFACE_AUTOMOC_MACRO_NAMES", "CXX",
&dagChecker, InterfaceAutoMocMacroNamesEntries,
@@ -1933,6 +1933,9 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
}
}
} else {
+ 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,