From 82e91e34872fd8fa394d14f1e4fac60f9e993a35 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 10:28:08 -0400 Subject: [PATCH 01/12] cmComputeLinkDepends: Convert AddLinkEntries to a template Allow the method to be called with a vector of any type that can be converted to cmLinkItem. --- Source/cmComputeLinkDepends.cxx | 5 +++-- Source/cmComputeLinkDepends.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 6170e92e9..c13da50da 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -553,15 +553,16 @@ void cmComputeLinkDepends::AddDirectLinkEntries() } //---------------------------------------------------------------------------- +template void cmComputeLinkDepends::AddLinkEntries( - int depender_index, std::vector const& libs) + int depender_index, std::vector const& libs) { // Track inferred dependency sets implied by this list. std::map dependSets; // Loop over the libraries linked directly by the depender. - for(std::vector::const_iterator li = libs.begin(); + for(typename std::vector::const_iterator li = libs.begin(); li != libs.end(); ++li) { // Skip entries that will resolve to the target getting linked or diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 3207ecbf5..a931726d9 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -80,8 +80,8 @@ private: int AddLinkEntry(cmLinkItem const& item); void AddVarLinkEntries(int depender_index, const char* value); void AddDirectLinkEntries(); - void AddLinkEntries(int depender_index, - std::vector const& libs); + template + void AddLinkEntries(int depender_index, std::vector const& libs); cmTarget const* FindTargetToLink(int depender_index, const std::string& name); From f85ccf23eeec08fff46c0788b8ee357b3f5220e4 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 10:31:01 -0400 Subject: [PATCH 02/12] cmGeneratorExpressionEvaluator: Shorten some long lines Adjust the definitions of getLinkedTargetsContent to avoid long lines. --- Source/cmGeneratorExpressionEvaluator.cxx | 29 +++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index b648eb2d8..cf112ecff 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -799,13 +799,14 @@ static const char* targetPropertyTransitiveWhitelist[] = { #undef TRANSITIVE_PROPERTY_NAME -std::string getLinkedTargetsContent( - std::vector &targets, - cmTarget const* target, - cmTarget const* headTarget, - cmGeneratorExpressionContext *context, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string &interfacePropertyName) +std::string +getLinkedTargetsContent( + std::vector &targets, + cmTarget const* target, + cmTarget const* headTarget, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) { cmGeneratorExpression ge(&context->Backtrace); @@ -841,12 +842,14 @@ std::string getLinkedTargetsContent( return linkedTargetsContent; } -std::string getLinkedTargetsContent(std::vector const &libraries, - cmTarget const* target, - cmTarget const* headTarget, - cmGeneratorExpressionContext *context, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string &interfacePropertyName) +std::string +getLinkedTargetsContent( + std::vector const &libraries, + cmTarget const* target, + cmTarget const* headTarget, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) { std::vector tgts; for (std::vector::const_iterator From 848c8ccf18e325e0d2833ac468f733261832feca Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 10:38:59 -0400 Subject: [PATCH 03/12] cmTarget: Refactor LinkImplementation to allow more information Create a cmLinkImplItem class derived from cmLinkItem so more information can be added to link implementation entries than link interface entries. Convert the LinkImplementation Libraries member to hold it. Update client sites accordingly. --- Source/cmComputeTargetDepends.cxx | 2 +- Source/cmGeneratorExpressionEvaluator.cxx | 4 ++-- Source/cmGeneratorTarget.cxx | 4 ++-- Source/cmTarget.cxx | 19 +++++++++++-------- Source/cmTarget.h | 12 +++++++++++- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 3929af40d..75d3967bc 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -255,7 +255,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // A target should not depend on itself. emitted.insert(depender->GetName()); - for(std::vector::const_iterator + for(std::vector::const_iterator lib = impl->Libraries.begin(); lib != impl->Libraries.end(); ++lib) { diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index cf112ecff..13eac3bd3 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -844,7 +844,7 @@ getLinkedTargetsContent( std::string getLinkedTargetsContent( - std::vector const &libraries, + std::vector const &libraries, cmTarget const* target, cmTarget const* headTarget, cmGeneratorExpressionContext *context, @@ -852,7 +852,7 @@ getLinkedTargetsContent( const std::string &interfacePropertyName) { std::vector tgts; - for (std::vector::const_iterator + for (std::vector::const_iterator it = libraries.begin(); it != libraries.end(); ++it) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index fd82d1742..eccb06ada 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -475,8 +475,8 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir, } std::set uniqueDeps; - for(std::vector::const_iterator li = impl->Libraries.begin(); - li != impl->Libraries.end(); ++li) + for(std::vector::const_iterator + li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { cmTarget const* tgt = li->Target; if (!tgt) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d27293a4d..94b339b5e 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2281,7 +2281,7 @@ cmTarget::GetIncludeDirectories(const std::string& config) const if(this->Makefile->IsOn("APPLE")) { LinkImplementation const* impl = this->GetLinkImplementation(config); - for(std::vector::const_iterator + for(std::vector::const_iterator it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { @@ -3675,7 +3675,8 @@ void cmTarget::ComputeLinkClosure(const std::string& config, // Add interface languages from linked targets. cmTargetCollectLinkLanguages cll(this, config, languages, this); - for(std::vector::const_iterator li = impl->Libraries.begin(); + for(std::vector::const_iterator + li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { cll.Visit(*li); @@ -6242,7 +6243,8 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const cmTarget::LinkImplementation const* impl = this->GetLinkImplementationLibraries(config); - for(std::vector::const_iterator it = impl->Libraries.begin(); + for(std::vector::const_iterator + it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { processILibs(config, this, *it, tgts , emitted); @@ -6383,7 +6385,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, // The link implementation is the default link interface. LinkImplementation const* impl = this->GetLinkImplementationLibrariesInternal(config, headTarget); - iface.Libraries = impl->Libraries; + std::copy(impl->Libraries.begin(), impl->Libraries.end(), + std::back_inserter(iface.Libraries)); if(this->PolicyStatusCMP0022 == cmPolicies::WARN && !this->Internal->PolicyWarnedCMP0022 && !usage_requirements_only) { @@ -6397,12 +6400,12 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, headTarget, usage_requirements_only, ifaceLibs); } - if (ifaceLibs != impl->Libraries) + if (ifaceLibs != iface.Libraries) { std::string oldLibraries; std::string newLibraries; const char *sep = ""; - for(std::vector::const_iterator it + for(std::vector::const_iterator it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { oldLibraries += sep; @@ -6470,7 +6473,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, { cmTarget::LinkImplementation const* impl = thisTarget->GetLinkImplementation(config); - for(std::vector::const_iterator + for(std::vector::const_iterator li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { if(emitted.insert(*li).second) @@ -6674,7 +6677,7 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, // The entry is meant for this configuration. impl.Libraries.push_back( - cmLinkItem(name, this->FindTargetToLink(name))); + cmLinkImplItem(name, this->FindTargetToLink(name))); } std::set const& seenProps = cge->GetSeenTargetProperties(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 9d1f96614..8578c5152 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -54,6 +54,16 @@ public: cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {} cmTarget const* Target; }; +class cmLinkImplItem: public cmLinkItem +{ +public: + cmLinkImplItem(): cmLinkItem() {} + cmLinkImplItem(std::string const& n, + cmTarget const* t): + cmLinkItem(n, t) {} + cmLinkImplItem(cmLinkImplItem const& r): + cmLinkItem(r) {} +}; struct cmTargetLinkInformationMap: public std::map @@ -296,7 +306,7 @@ public: std::vector Languages; // Libraries linked directly in this configuration. - std::vector Libraries; + std::vector Libraries; // Libraries linked directly in other configurations. // Needed only for OLD behavior of CMP0003. From 251e835b3f7320f0099d003de5a675af58e62e46 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 10:43:36 -0400 Subject: [PATCH 04/12] cmTarget: Add to LinkImplementation a backtrace for each library Allow clients to provide backtrace context on evaluation diagnostics. --- Source/cmTarget.cxx | 2 +- Source/cmTarget.h | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 94b339b5e..6bc427397 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -6677,7 +6677,7 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, // The entry is meant for this configuration. impl.Libraries.push_back( - cmLinkImplItem(name, this->FindTargetToLink(name))); + cmLinkImplItem(name, this->FindTargetToLink(name), le->Backtrace)); } std::set const& seenProps = cge->GetSeenTargetProperties(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 8578c5152..5f2a5574a 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -57,12 +57,14 @@ public: class cmLinkImplItem: public cmLinkItem { public: - cmLinkImplItem(): cmLinkItem() {} + cmLinkImplItem(): cmLinkItem(), Backtrace(0) {} cmLinkImplItem(std::string const& n, - cmTarget const* t): - cmLinkItem(n, t) {} + cmTarget const* t, + cmListFileBacktrace const& bt): + cmLinkItem(n, t), Backtrace(bt) {} cmLinkImplItem(cmLinkImplItem const& r): - cmLinkItem(r) {} + cmLinkItem(r), Backtrace(r.Backtrace) {} + cmListFileBacktrace Backtrace; }; struct cmTargetLinkInformationMap: From 363cd33ebe5a8fb495fffc07cf39c59082e83bbf Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 10:47:21 -0400 Subject: [PATCH 05/12] cmTarget: Add method to add usage requirements from linked interfaces Create a cmTargetInternals::AddInterfaceEntries method to construct a $ generator expression and evaluate it for every target in the link implementation. This will be useful to de-duplicate such evaluation for each usage requirement separately. The new method will soon be used in the implementation of the INTERFACE_* usage requirement lookup methods (GetSourceFiles, GetCompileOptions, GetCompileDefinitions, GetCompileFeatures, GetIncludeDirectories). It is necessary for these methods to determine whether an expression in LinkImplementationPropertyEntries evaluates to a target or not because generator expression evaluation reports an error for non-targets and we construct a $ expression for each entry that is a target. The implementation of each usage requirement currently processes the LinkImplementationPropertyEntries and evaluates all generator expressions to determine targets. That is no longer necessary because GetLinkImplementationLibraries now returns resolved and cached targets together with their name. Use it to implement AddInterfaceEntries. --- Source/cmTarget.cxx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 6bc427397..0ad4ffb0a 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -181,6 +181,10 @@ public: std::vector SourceEntries; std::vector LinkImplementationPropertyEntries; + void AddInterfaceEntries( + cmTarget const* thisTarget, std::string const& config, + std::string const& prop, std::vector& entries); + std::map > CachedLinkInterfaceIncludeDirectoriesEntries; std::map > @@ -6549,6 +6553,31 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, iface.Complete = true; } +//---------------------------------------------------------------------------- +void cmTargetInternals::AddInterfaceEntries( + cmTarget const* thisTarget, std::string const& config, + std::string const& prop, std::vector& entries) +{ + if(cmTarget::LinkImplementation const* impl = + thisTarget->GetLinkImplementationLibraries(config)) + { + for (std::vector::const_iterator + it = impl->Libraries.begin(), end = impl->Libraries.end(); + it != end; ++it) + { + if(it->Target) + { + std::string genex = + "$"; + cmGeneratorExpression ge(&it->Backtrace); + cmsys::auto_ptr cge = ge.Parse(genex); + entries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge, *it)); + } + } + } +} + //---------------------------------------------------------------------------- cmTarget::LinkImplementation const* cmTarget::GetLinkImplementation(const std::string& config) const From 3156275bc74e355f8309617344693a0f14b7a370 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 19 Jun 2014 13:37:30 -0400 Subject: [PATCH 06/12] cmTarget: Simplify INTERFACE_SOURCES usage requirement lookup Use the AddInterfaceEntries helper to avoid duplication. --- Source/cmTarget.cxx | 42 ++----------------- .../Languages/LINK_LANGUAGE-genex-stderr.txt | 6 ++- ...ink-libraries-TARGET_FILE-genex-stderr.txt | 4 +- 3 files changed, 10 insertions(+), 42 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0ad4ffb0a..a87e98d30 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -774,45 +774,9 @@ void cmTarget::GetSourceFiles(std::vector &files, if (!this->Internal->CacheLinkInterfaceSourcesDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, &dagChecker); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string sourceGenex = "$Value + ",INTERFACE_SOURCES>"; - 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. - sourceGenex = "$<$Value + ">:" + sourceGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - sourceGenex); - - this->Internal - ->CachedLinkInterfaceSourcesEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_SOURCES", + this->Internal->CachedLinkInterfaceSourcesEntries[config]); } std::vector::size_type numFilesBefore = files.size(); diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt index a5d5d5088..3a7f4806c 100644 --- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt @@ -1,7 +1,9 @@ -CMake Error: +CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\): Error evaluating generator expression: \$ LINKER_LANGUAGE target property can not be used while evaluating link - libraries + libraries for a static library +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt index 2d7a3c9d6..d8bc2387b 100644 --- a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt @@ -1,7 +1,9 @@ -CMake Error: +CMake Error at link-libraries-TARGET_FILE-genex.cmake:[0-9]+ \(target_link_libraries\): Error evaluating generator expression: \$ Expressions which require the linker language may not be used while evaluating link libraries +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) From d9586f83f11f56d8d9f88892f543918f50e9525c Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 19 Jun 2014 13:38:26 -0400 Subject: [PATCH 07/12] cmTarget: Simplify INTERFACE_COMPILE_OPTIONS usage requirement lookup Use the AddInterfaceEntries helper to avoid duplication. --- Source/cmTarget.cxx | 42 +++--------------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a87e98d30..2cc21f56c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2430,45 +2430,9 @@ void cmTarget::GetCompileOptions(std::vector &result, if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string optionGenex = "$Value + ",INTERFACE_COMPILE_OPTIONS>"; - 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. - optionGenex = "$<$Value + ">:" + optionGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - optionGenex); - - this->Internal - ->CachedLinkInterfaceCompileOptionsEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_OPTIONS", + this->Internal->CachedLinkInterfaceCompileOptionsEntries[config]); } processCompileOptions(this, From 61ef8daad5d15256daec08eeb0437fdece330001 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 19 Jun 2014 13:38:51 -0400 Subject: [PATCH 08/12] cmTarget: Simplify INTERFACE_COMPILE_DEFINITIONS usage requirement lookup Use the AddInterfaceEntries helper to avoid duplication. --- Source/cmTarget.cxx | 42 +++--------------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 2cc21f56c..e35167ea4 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2504,45 +2504,9 @@ void cmTarget::GetCompileDefinitions(std::vector &list, if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string defsGenex = "$Value + ",INTERFACE_COMPILE_DEFINITIONS>"; - 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. - defsGenex = "$<$Value + ">:" + defsGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - defsGenex); - - this->Internal - ->CachedLinkInterfaceCompileDefinitionsEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_DEFINITIONS", + this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[config]); if (!config.empty()) { std::string configPropName = "COMPILE_DEFINITIONS_" From f77b384cf6a4e9206e6067b7bfe0677a962268c4 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 19 Jun 2014 13:39:25 -0400 Subject: [PATCH 09/12] cmTarget: Simplify INTERFACE_COMPILE_FEATURES usage requirement lookup Use the AddInterfaceEntries helper to avoid duplication. --- Source/cmTarget.cxx | 42 +++--------------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e35167ea4..98a9920e0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2615,45 +2615,9 @@ void cmTarget::GetCompileFeatures(std::vector &result, if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string targetResult = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(targetResult)) - { - continue; - } - } - std::string featureGenex = "$Value + ",INTERFACE_COMPILE_FEATURES>"; - 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. - featureGenex = "$<$Value + ">:" + featureGenex + ">"; - } - cmGeneratorExpression ge(&it->Backtrace); - cmsys::auto_ptr cge = ge.Parse( - featureGenex); - - this->Internal - ->CachedLinkInterfaceCompileFeaturesEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_FEATURES", + this->Internal->CachedLinkInterfaceCompileFeaturesEntries[config]); } processCompileFeatures(this, From 5e07dcf7c8e884380e1ad5ab64ba3bcdef601eee Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 11:39:09 -0400 Subject: [PATCH 10/12] cmTarget: Add to LinkImplementation whether each library was a genex Implementation of CMP0027 OLD behavior needs to know whether each entry in LinkImplementation::Libraries came from a generator expression or not. Add a FromGenex member to cmLinkImplItem to record this. --- Source/cmTarget.cxx | 12 +++++------- Source/cmTarget.h | 10 ++++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 98a9920e0..9ba845668 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -6509,12 +6509,9 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, cmGeneratorExpression ge(&le->Backtrace); cmsys::auto_ptr const cge = ge.Parse(le->Value); - cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, - config, - false, - head, - &dagChecker), - llibs); + std::string const evaluated = + cge->Evaluate(this->Makefile, config, false, head, &dagChecker); + cmSystemTools::ExpandListArgument(evaluated, llibs); for(std::vector::const_iterator li = llibs.begin(); li != llibs.end(); ++li) @@ -6562,7 +6559,8 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, // The entry is meant for this configuration. impl.Libraries.push_back( - cmLinkImplItem(name, this->FindTargetToLink(name), le->Backtrace)); + cmLinkImplItem(name, this->FindTargetToLink(name), + le->Backtrace, evaluated != le->Value)); } std::set const& seenProps = cge->GetSeenTargetProperties(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 5f2a5574a..dc67f1e78 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -57,14 +57,16 @@ public: class cmLinkImplItem: public cmLinkItem { public: - cmLinkImplItem(): cmLinkItem(), Backtrace(0) {} + cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {} cmLinkImplItem(std::string const& n, cmTarget const* t, - cmListFileBacktrace const& bt): - cmLinkItem(n, t), Backtrace(bt) {} + cmListFileBacktrace const& bt, + bool fromGenex): + cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {} cmLinkImplItem(cmLinkImplItem const& r): - cmLinkItem(r), Backtrace(r.Backtrace) {} + cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {} cmListFileBacktrace Backtrace; + bool FromGenex; }; struct cmTargetLinkInformationMap: From b5b098ebb39c97f3420eb7c24f0d4d5bc2d15a5a Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 11:41:54 -0400 Subject: [PATCH 11/12] cmTarget: Simplify CMP0027 logic in processIncludeDirectories Evaluate and lookup the target name only once per TargetPropertyEntry instead of repeating it for each include directory entry. Use a local checkCMP0027 variable to record whether the policy should be checked. Evaluate the target name as a generator expression only if it looks like one. Lookup the target by name only after evaluation of generator expressions. --- Source/cmTarget.cxx | 46 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9ba845668..0c96c9104 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2012,6 +2012,24 @@ static void processIncludeDirectories(cmTarget const* tgt, for (std::vector::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { + std::string targetName = (*it)->TargetName; + bool checkCMP0027 = false; + if(!cmGeneratorExpression::IsValidTargetName(targetName) + && cmGeneratorExpression::Find(targetName) != std::string::npos) + { + std::string evaluatedTargetName; + cmGeneratorExpression ge; + cmsys::auto_ptr cge = + ge.Parse(targetName); + evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0); + checkCMP0027 = evaluatedTargetName != targetName; + targetName = evaluatedTargetName; + } + cmTarget *dependentTarget = mf->FindTargetToUse(targetName); + + const bool fromImported = + dependentTarget && dependentTarget->IsImported(); + bool testIsOff = true; bool cacheIncludes = false; std::vector& entryIncludes = (*it)->CachedEntries; @@ -2037,36 +2055,12 @@ static void processIncludeDirectories(cmTarget const* tgt, for(std::vector::iterator li = entryIncludes.begin(); li != entryIncludes.end(); ++li) { - std::string targetName = (*it)->TargetName; - std::string evaluatedTargetName; - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(targetName); - evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0); - } - - cmTarget *dependentTarget = mf->FindTargetToUse(targetName); - - const bool fromImported = dependentTarget - && dependentTarget->IsImported(); - - cmTarget *evaluatedDependentTarget = - (targetName != evaluatedTargetName) - ? mf->FindTargetToUse(evaluatedTargetName) - : 0; - - targetName = evaluatedTargetName; - - const bool fromEvaluatedImported = evaluatedDependentTarget - && evaluatedDependentTarget->IsImported(); - - if ((fromImported || fromEvaluatedImported) + if (fromImported && !cmSystemTools::FileExists(li->c_str())) { cmOStringStream e; cmake::MessageType messageType = cmake::FATAL_ERROR; - if (fromEvaluatedImported) + if (checkCMP0027) { switch(tgt->GetPolicyStatusCMP0027()) { From 93790506f52cb4e420be6a1a6988613380ecb1bc Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 30 Jun 2014 13:23:49 -0400 Subject: [PATCH 12/12] cmTarget: Simplify INTERFACE_INCLUDE_DIRECTORIES usage requirement lookup Use the AddInterfaceEntries helper to avoid duplication. In TargetPropertyEntry, replace the TargetName string member with a reference to the full cmLinkImplItem that produced the entry. This is possible because the cmLinkImplItem is available in AddInterfaceEntries (it was not available in GetIncludeDirectories). Having the full cmLinkImplItem allows processIncludeDirectories to implement CMP0027 OLD behavior without repeating the target name lookup. Update the RunCMake.CompatibleInterface test DebugProperties case expected output for the new order of the messages. --- Source/cmTarget.cxx | 76 ++++--------------- .../DebugProperties-stderr.txt | 14 ++-- 2 files changed, 22 insertions(+), 68 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0c96c9104..0a7724cb8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -165,14 +165,16 @@ public: std::set UtilityItems; bool UtilityItemsDone; - struct TargetPropertyEntry { + class TargetPropertyEntry { + static cmLinkImplItem NoLinkImplItem; + public: TargetPropertyEntry(cmsys::auto_ptr cge, - const std::string &targetName = std::string()) - : ge(cge), TargetName(targetName) + cmLinkImplItem const& item = NoLinkImplItem) + : ge(cge), LinkImplItem(item) {} const cmsys::auto_ptr ge; std::vector CachedEntries; - const std::string TargetName; + cmLinkImplItem const& LinkImplItem; }; std::vector IncludeDirectoriesEntries; std::vector CompileOptionsEntries; @@ -206,6 +208,8 @@ public: std::map CacheLinkImplementationClosureDone; }; +cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; + //---------------------------------------------------------------------------- void deleteAndClear( std::vector &entries) @@ -2012,24 +2016,10 @@ static void processIncludeDirectories(cmTarget const* tgt, for (std::vector::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { - std::string targetName = (*it)->TargetName; - bool checkCMP0027 = false; - if(!cmGeneratorExpression::IsValidTargetName(targetName) - && cmGeneratorExpression::Find(targetName) != std::string::npos) - { - std::string evaluatedTargetName; - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(targetName); - evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0); - checkCMP0027 = evaluatedTargetName != targetName; - targetName = evaluatedTargetName; - } - cmTarget *dependentTarget = mf->FindTargetToUse(targetName); - - const bool fromImported = - dependentTarget && dependentTarget->IsImported(); - + cmLinkImplItem const& item = (*it)->LinkImplItem; + std::string const& targetName = item; + bool const fromImported = item.Target && item.Target->IsImported(); + bool const checkCMP0027 = item.FromGenex; bool testIsOff = true; bool cacheIncludes = false; std::vector& entryIncludes = (*it)->CachedEntries; @@ -2200,45 +2190,9 @@ cmTarget::GetIncludeDirectories(const std::string& config) const if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[config]) { - for (std::vector::const_iterator - it = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmGeneratorExpression ge; - cmsys::auto_ptr cge = - ge.Parse(it->Value); - std::string result = cge->Evaluate(this->Makefile, config, - false, this, 0, 0); - if (!this->Makefile->FindTargetToUse(result)) - { - 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( - includeGenex); - - this->Internal - ->CachedLinkInterfaceIncludeDirectoriesEntries[config].push_back( - new cmTargetInternals::TargetPropertyEntry(cge, - it->Value)); - } + this->Internal->AddInterfaceEntries( + this, config, "INTERFACE_INCLUDE_DIRECTORIES", + this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[config]); if(this->Makefile->IsOn("APPLE")) { diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt index 82a34d530..17b8a5cfe 100644 --- a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt +++ b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt @@ -1,10 +1,3 @@ -CMake Debug Log: - Boolean compatibility of property "BOOL_PROP7" for target - "CompatibleInterface" \(result: "FALSE"\): - - \* Target "CompatibleInterface" property is implied by use. - \* Target "iface1" property value "FALSE" \(Agree\) -+ CMake Debug Log: Boolean compatibility of property "BOOL_PROP1" for target "CompatibleInterface" \(result: "TRUE"\): @@ -46,6 +39,13 @@ CMake Debug Log: \* Target "iface1" property value "FALSE" \(Interface set\) \* Target "iface2" property value "FALSE" \(Agree\) + +CMake Debug Log: + Boolean compatibility of property "BOOL_PROP7" for target + "CompatibleInterface" \(result: "FALSE"\): + + \* Target "CompatibleInterface" property is implied by use. + \* Target "iface1" property value "FALSE" \(Agree\) ++ CMake Debug Log: String compatibility of property "STRING_PROP1" for target "CompatibleInterface" \(result: "prop1"\):