From b8259c3d69258b884383559b74d37486b6a06ca2 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 29 Apr 2013 11:54:19 +0200 Subject: Centralize maintenance of usage requirement include directories Maintain a target's internal list of usage requirement include directories whenever the LINK_LIBRARIES property is set by either target_link_libraries or set_property. --- Source/cmTarget.cxx | 23 +++++++++++++++++------ Source/cmTarget.h | 1 - Source/cmTargetLinkLibrariesCommand.cxx | 8 -------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 66c22b1..186e203 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2706,6 +2706,15 @@ void cmTarget::SetProperty(const char* prop, const char* value) new cmTargetInternals::IncludeDirectoriesEntry(cge)); return; } + if (strcmp(prop, "LINK_LIBRARIES") == 0) + { + this->Internal->LinkInterfaceIncludeDirectoriesEntries.clear(); + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + // Fall through + } this->Properties.SetProperty(prop, value, cmProperty::TARGET); this->MaybeInvalidatePropertyCache(prop); } @@ -2727,6 +2736,14 @@ void cmTarget::AppendProperty(const char* prop, const char* value, new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value))); return; } + if (strcmp(prop, "LINK_LIBRARIES") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + // Fall through + } this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); this->MaybeInvalidatePropertyCache(prop); } @@ -2763,12 +2780,6 @@ void cmTarget::AppendBuildInterfaceIncludes() } //---------------------------------------------------------------------------- -void cmTarget::AppendTllInclude(const cmValueWithOrigin &entry) -{ - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); -} - -//---------------------------------------------------------------------------- void cmTarget::InsertInclude(const cmValueWithOrigin &entry, bool before) { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e25133e..9d46796 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -495,7 +495,6 @@ public: std::vector GetIncludeDirectories(const char *config); void InsertInclude(const cmValueWithOrigin &entry, bool before = false); - void AppendTllInclude(const cmValueWithOrigin &entry); void AppendBuildInterfaceIncludes(); diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 3f652c9..b7b7691 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -259,14 +259,6 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, // Handle normal case first. if(this->CurrentProcessingState != ProcessingLinkInterface) { - { - cmListFileBacktrace lfbt; - this->Makefile->GetBacktrace(lfbt); - cmValueWithOrigin entry(this->Target->GetDebugGeneratorExpressions(lib, - llt), - lfbt); - this->Target->AppendTllInclude(entry); - } this->Makefile ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); if (this->CurrentProcessingState != ProcessingPublicInterface) -- cgit v0.12 From 26dba6a1622422d3742254aa2ecab97f9a58cb2b Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 29 Apr 2013 12:00:53 +0200 Subject: Fix include dir propagation from conditionally linked targets Generator expressions, including configuration-specific expressions may be used as link libraries of targets. The old-style keywords of target_link_libraries are handled in terms of new generator expressions. However, the generator expressions expect target names to be valid against a regular expression, whereas target_link_libraries does not require validation. In generator expression constructed without any action from the user we need to ensure that only valid expressions are generated. Ensure that strings which are not valid target names are not used in generator expressions which validate the argument. Code like target_link_libraries(B debug A) generates usage requirement references such as "$<$:A>". When cmTarget::GetIncludeDirectories uses such references it generates expressions like: $:A>,INTERFACE_INCLUDE_DIRECTORIES> When the conditions are false such references evaluate as an empty string and the expression fails with an error such as: $ expression requires a non-empty target name. Fix this by teaching cmTarget::GetIncludeDirectories to wrap the above expression inside a conditional: $<$:A>>:...> so that $ will not be evaluated with an empty target. --- Source/cmTarget.cxx | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 186e203..1ccfa47 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2709,10 +2709,14 @@ void cmTarget::SetProperty(const char* prop, const char* value) if (strcmp(prop, "LINK_LIBRARIES") == 0) { this->Internal->LinkInterfaceIncludeDirectoriesEntries.clear(); - cmListFileBacktrace lfbt; - this->Makefile->GetBacktrace(lfbt); - cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + if (cmGeneratorExpression::IsValidTargetName(value) + || cmGeneratorExpression::Find(value) != std::string::npos) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + } // Fall through } this->Properties.SetProperty(prop, value, cmProperty::TARGET); @@ -2738,10 +2742,14 @@ void cmTarget::AppendProperty(const char* prop, const char* value, } if (strcmp(prop, "LINK_LIBRARIES") == 0) { - cmListFileBacktrace lfbt; - this->Makefile->GetBacktrace(lfbt); - cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + if (cmGeneratorExpression::IsValidTargetName(value) + || cmGeneratorExpression::Find(value) != std::string::npos) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(value, lfbt); + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + } // Fall through } this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); @@ -2950,16 +2958,23 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) ge.Parse(it->Value); std::string result = cge->Evaluate(this->Makefile, config, false, this, 0, 0); - if (!cmGeneratorExpression::IsValidTargetName(result.c_str()) - || !this->Makefile->FindTargetToUse(result.c_str())) + if (!this->Makefile->FindTargetToUse(result.c_str())) { continue; } } + std::string includeGenex = "$Value + ",INTERFACE_INCLUDE_DIRECTORIES>"; + if (cmGeneratorExpression::Find(it->Value) != std::string::npos) + { + // Because it->Value is a generator expression, ensure that it + // evaluates to the non-empty string before being used in the + // TARGET_PROPERTY expression. + includeGenex = "$<$Value + ">:" + includeGenex + ">"; + } cmGeneratorExpression ge(it->Backtrace); cmsys::auto_ptr cge = ge.Parse( - "$Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); + includeGenex); this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back( new cmTargetInternals::IncludeDirectoriesEntry(cge, -- cgit v0.12 From dea1df4e5e05b8ba3de5099741a50cdea384f88e Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 2 May 2013 16:52:48 +0200 Subject: Memoize usage requirement include directories in a config-specific map Commit 42ebb188 (Memoize includes and defines from interface libraries., 2013-02-22) introduced caching of the includes. Fix the memoization to be configuration-specific so that we do not accumulate entries across multiple evaluations in a multi-config generator. --- Source/cmTarget.cxx | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1ccfa47..d14bfca 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -142,7 +142,7 @@ public: std::vector IncludeDirectoriesEntries; std::vector LinkInterfaceIncludeDirectoriesEntries; - std::vector + std::map > CachedLinkInterfaceIncludeDirectoriesEntries; std::map CachedLinkInterfaceCompileDefinitions; @@ -165,6 +165,19 @@ void deleteAndClear( } //---------------------------------------------------------------------------- +void deleteAndClear( + std::map > &entries) +{ + for (std::map >::iterator + it = entries.begin(), end = entries.end(); it != end; ++it) + { + deleteAndClear(it->second); + } +} + +//---------------------------------------------------------------------------- cmTargetInternals::~cmTargetInternals() { deleteAndClear(CachedLinkInterfaceIncludeDirectoriesEntries); @@ -2976,14 +2989,15 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) cmsys::auto_ptr cge = ge.Parse( includeGenex); - this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back( + this->Internal + ->CachedLinkInterfaceIncludeDirectoriesEntries[configString].push_back( new cmTargetInternals::IncludeDirectoriesEntry(cge, it->Value)); } } processIncludeDirectories(this, - this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries, + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[configString], includes, uniqueIncludes, &dagChecker, @@ -2993,7 +3007,7 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) if (!this->Makefile->IsGeneratingBuildSystem()) { deleteAndClear( - this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries); + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries); } else { -- cgit v0.12