From 9d13e1679f2b52e88748a710edd201ed9fba7447 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jul 2014 11:14:26 -0400 Subject: cmTarget: Remove duplicate link interface map No target is both imported and not imported so we do not need separate link interface maps for them. --- Source/cmTarget.cxx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9d00591..dc8384d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -141,11 +141,6 @@ public: LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; bool PolicyWarnedCMP0022; - typedef std::map - ImportLinkInterfaceMapType; - ImportLinkInterfaceMapType ImportLinkInterfaceMap; - ImportLinkInterfaceMapType ImportLinkInterfaceUsageRequirementsOnlyMap; - typedef std::map OutputInfoMapType; OutputInfoMapType OutputInfoMap; @@ -528,8 +523,6 @@ void cmTarget::ClearLinkMaps() this->Internal->LinkImplMap.clear(); this->Internal->LinkInterfaceMap.clear(); this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear(); - this->Internal->ImportLinkInterfaceMap.clear(); - this->Internal->ImportLinkInterfaceUsageRequirementsOnlyMap.clear(); this->Internal->LinkClosureMap.clear(); for (cmTargetLinkInformationMap::const_iterator it = this->LinkInformation.begin(); @@ -5826,10 +5819,10 @@ cmTarget::GetImportLinkInterface(const std::string& config, } TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config)); - cmTargetInternals::ImportLinkInterfaceMapType& lim = + cmTargetInternals::LinkInterfaceMapType& lim = (usage_requirements_only ? - this->Internal->ImportLinkInterfaceUsageRequirementsOnlyMap : - this->Internal->ImportLinkInterfaceMap); + this->Internal->LinkInterfaceUsageRequirementsOnlyMap : + this->Internal->LinkInterfaceMap); cmTargetInternals::OptionalLinkInterface& iface = lim[key]; if(!iface.AllDone) -- cgit v0.12 From fe665fdda8986b3af061ec91a7ab5fbe8f606e4f Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jul 2014 11:26:10 -0400 Subject: cmTarget: Refactor link interface map storage Convert LinkInterfaceMapType and LinkImplMapType to nested maps that index on configuration first and 'head' target second. --- Source/cmTarget.cxx | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index dc8384d..52b7e68 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -88,11 +88,6 @@ struct cmTarget::CompileInfo std::string CompilePdbDir; }; -struct TargetConfigPair : public std::pair { - TargetConfigPair(cmTarget const* tgt, const std::string &config) - : std::pair(tgt, config) {} -}; - //---------------------------------------------------------------------------- class cmTargetInternals { @@ -135,7 +130,9 @@ public: cmTarget const* head, bool usage_requirements_only); - typedef std::map + struct HeadToLinkInterfaceMap: + public std::map {}; + typedef std::map LinkInterfaceMapType; LinkInterfaceMapType LinkInterfaceMap; LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; @@ -158,8 +155,10 @@ public: bool LibrariesDone; bool LanguagesDone; }; - typedef std::map LinkImplMapType; + struct HeadToLinkImplementationMap: + public std::map {}; + typedef std::map LinkImplMapType; LinkImplMapType LinkImplMap; typedef std::map LinkClosureMapType; @@ -5746,10 +5745,10 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( } // Lookup any existing link interface for this configuration. - TargetConfigPair key(head, cmSystemTools::UpperCase(config)); + std::string CONFIG = cmSystemTools::UpperCase(config); cmTargetInternals::OptionalLinkInterface& - iface = this->Internal->LinkInterfaceMap[key]; + iface = this->Internal->LinkInterfaceMap[CONFIG][head]; if(!iface.LibrariesDone) { iface.LibrariesDone = true; @@ -5789,13 +5788,13 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config, } // Lookup any existing link interface for this configuration. - TargetConfigPair key(head, cmSystemTools::UpperCase(config)); + std::string CONFIG = cmSystemTools::UpperCase(config); cmTargetInternals::LinkInterfaceMapType& lim = (usage_requirements_only ? this->Internal->LinkInterfaceUsageRequirementsOnlyMap : this->Internal->LinkInterfaceMap); - cmTargetInternals::OptionalLinkInterface& iface = lim[key]; + cmTargetInternals::OptionalLinkInterface& iface = lim[CONFIG][head]; if(!iface.LibrariesDone) { iface.LibrariesDone = true; @@ -5818,13 +5817,13 @@ cmTarget::GetImportLinkInterface(const std::string& config, return 0; } - TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config)); cmTargetInternals::LinkInterfaceMapType& lim = (usage_requirements_only ? this->Internal->LinkInterfaceUsageRequirementsOnlyMap : this->Internal->LinkInterfaceMap); - cmTargetInternals::OptionalLinkInterface& iface = lim[key]; + std::string CONFIG = cmSystemTools::UpperCase(config); + cmTargetInternals::OptionalLinkInterface& iface = lim[CONFIG][headTarget]; if(!iface.AllDone) { iface.AllDone = true; @@ -6226,9 +6225,9 @@ cmTarget::GetLinkImplementation(const std::string& config) const } // Populate the link implementation for this configuration. - TargetConfigPair key(this, cmSystemTools::UpperCase(config)); + std::string CONFIG = cmSystemTools::UpperCase(config); cmTargetInternals::OptionalLinkImplementation& - impl = this->Internal->LinkImplMap[key]; + impl = this->Internal->LinkImplMap[CONFIG][this]; if(!impl.LibrariesDone) { impl.LibrariesDone = true; @@ -6261,9 +6260,9 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, } // Populate the link implementation libraries for this configuration. - TargetConfigPair key(head, cmSystemTools::UpperCase(config)); + std::string CONFIG = cmSystemTools::UpperCase(config); cmTargetInternals::OptionalLinkImplementation& - impl = this->Internal->LinkImplMap[key]; + impl = this->Internal->LinkImplMap[CONFIG][head]; if(!impl.LibrariesDone) { impl.LibrariesDone = true; -- cgit v0.12 From 438d9c7c822f42c4fccd77a47b1a32f52a87e617 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jul 2014 11:36:16 -0400 Subject: cmTarget: Re-order link interface map lookup logic In GetLinkInterface, GetLinkInterfaceLibraries, and GetImportLinkInterface, lookup the HeadToLinkInterfaceMap for the current configuration first, and then index it by head target. In GetLinkImplementationLibrariesInternal, lookup the HeadToLinkImplementationMap for the current configuration first, and then index it by head target. --- Source/cmTarget.cxx | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 52b7e68..df65a68 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -5746,9 +5746,9 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( // Lookup any existing link interface for this configuration. std::string CONFIG = cmSystemTools::UpperCase(config); - - cmTargetInternals::OptionalLinkInterface& - iface = this->Internal->LinkInterfaceMap[CONFIG][head]; + cmTargetInternals::HeadToLinkInterfaceMap& hm = + this->Internal->LinkInterfaceMap[CONFIG]; + cmTargetInternals::OptionalLinkInterface& iface = hm[head]; if(!iface.LibrariesDone) { iface.LibrariesDone = true; @@ -5789,12 +5789,11 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config, // Lookup any existing link interface for this configuration. std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::LinkInterfaceMapType& lim = + cmTargetInternals::HeadToLinkInterfaceMap& hm = (usage_requirements_only ? - this->Internal->LinkInterfaceUsageRequirementsOnlyMap : - this->Internal->LinkInterfaceMap); - - cmTargetInternals::OptionalLinkInterface& iface = lim[CONFIG][head]; + this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] : + this->Internal->LinkInterfaceMap[CONFIG]); + cmTargetInternals::OptionalLinkInterface& iface = hm[head]; if(!iface.LibrariesDone) { iface.LibrariesDone = true; @@ -5817,13 +5816,12 @@ cmTarget::GetImportLinkInterface(const std::string& config, return 0; } - cmTargetInternals::LinkInterfaceMapType& lim = - (usage_requirements_only ? - this->Internal->LinkInterfaceUsageRequirementsOnlyMap : - this->Internal->LinkInterfaceMap); - std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::OptionalLinkInterface& iface = lim[CONFIG][headTarget]; + cmTargetInternals::HeadToLinkInterfaceMap& hm = + (usage_requirements_only ? + this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] : + this->Internal->LinkInterfaceMap[CONFIG]); + cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget]; if(!iface.AllDone) { iface.AllDone = true; @@ -6261,8 +6259,9 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, // Populate the link implementation libraries for this configuration. std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::OptionalLinkImplementation& - impl = this->Internal->LinkImplMap[CONFIG][head]; + cmTargetInternals::HeadToLinkImplementationMap& hm = + this->Internal->LinkImplMap[CONFIG]; + cmTargetInternals::OptionalLinkImplementation& impl = hm[head]; if(!impl.LibrariesDone) { impl.LibrariesDone = true; -- cgit v0.12 From 46099b82ed71394f1dc6e0bbb91704d274edab7d Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jul 2014 11:55:56 -0400 Subject: cmTarget: Move ComputeLinkImplementation* to internals There are no external callers, and this will allow the methods to see the full OptionalLinkImplementation internal structure. --- Source/cmTarget.cxx | 76 ++++++++++++++++++++++++++++++++--------------------- Source/cmTarget.h | 5 ---- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index df65a68..353a3a6 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -155,6 +155,15 @@ public: bool LibrariesDone; bool LanguagesDone; }; + void ComputeLinkImplementationLibraries(cmTarget const* thisTarget, + const std::string& config, + OptionalLinkImplementation& impl, + cmTarget const* head) const; + void ComputeLinkImplementationLanguages(cmTarget const* thisTarget, + const std::string& config, + OptionalLinkImplementation& impl + ) const; + struct HeadToLinkImplementationMap: public std::map {}; typedef std::mapComputeLinkImplementationLibraries(config, impl, this); + this->Internal + ->ComputeLinkImplementationLibraries(this, config, impl, this); } if(!impl.LanguagesDone) { impl.LanguagesDone = true; - this->ComputeLinkImplementationLanguages(config, impl); + this->Internal->ComputeLinkImplementationLanguages(this, config, impl); } return &impl; } @@ -6265,51 +6275,54 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, if(!impl.LibrariesDone) { impl.LibrariesDone = true; - this->ComputeLinkImplementationLibraries(config, impl, head); + this->Internal + ->ComputeLinkImplementationLibraries(this, config, impl, head); } return &impl; } //---------------------------------------------------------------------------- void -cmTarget::ComputeLinkImplementationLibraries(const std::string& config, - LinkImplementation& impl, - cmTarget const* head) const +cmTargetInternals::ComputeLinkImplementationLibraries( + cmTarget const* thisTarget, + const std::string& config, + OptionalLinkImplementation& impl, + cmTarget const* head) const { // Collect libraries directly linked in this configuration. for (std::vector::const_iterator - le = this->Internal->LinkImplementationPropertyEntries.begin(), - end = this->Internal->LinkImplementationPropertyEntries.end(); + le = this->LinkImplementationPropertyEntries.begin(), + end = this->LinkImplementationPropertyEntries.end(); le != end; ++le) { std::vector llibs; cmGeneratorExpressionDAGChecker dagChecker( - this->GetName(), + thisTarget->GetName(), "LINK_LIBRARIES", 0, 0); cmGeneratorExpression ge(&le->Backtrace); cmsys::auto_ptr const cge = ge.Parse(le->Value); std::string const evaluated = - cge->Evaluate(this->Makefile, config, false, head, &dagChecker); + cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker); cmSystemTools::ExpandListArgument(evaluated, llibs); for(std::vector::const_iterator li = llibs.begin(); li != llibs.end(); ++li) { // Skip entries that resolve to the target itself or are empty. - std::string name = this->CheckCMP0004(*li); - if(name == this->GetName() || name.empty()) + std::string name = thisTarget->CheckCMP0004(*li); + if(name == thisTarget->GetName() || name.empty()) { - if(name == this->GetName()) + if(name == thisTarget->GetName()) { bool noMessage = false; cmake::MessageType messageType = cmake::FATAL_ERROR; cmOStringStream e; - switch(this->GetPolicyStatusCMP0038()) + switch(thisTarget->GetPolicyStatusCMP0038()) { case cmPolicies::WARN: { - e << (this->Makefile->GetPolicies() + e << (thisTarget->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0038)) << "\n"; messageType = cmake::AUTHOR_WARNING; } @@ -6325,9 +6338,9 @@ cmTarget::ComputeLinkImplementationLibraries(const std::string& config, if(!noMessage) { - e << "Target \"" << this->GetName() << "\" links to itself."; - this->Makefile->GetCMakeInstance()->IssueMessage( - messageType, e.str(), this->GetBacktrace()); + e << "Target \"" << thisTarget->GetName() << "\" links to itself."; + thisTarget->Makefile->GetCMakeInstance()->IssueMessage( + messageType, e.str(), thisTarget->GetBacktrace()); if (messageType == cmake::FATAL_ERROR) { return; @@ -6339,7 +6352,7 @@ cmTarget::ComputeLinkImplementationLibraries(const std::string& config, // The entry is meant for this configuration. impl.Libraries.push_back( - cmLinkImplItem(name, this->FindTargetToLink(name), + cmLinkImplItem(name, thisTarget->FindTargetToLink(name), le->Backtrace, evaluated != le->Value)); } @@ -6347,42 +6360,45 @@ cmTarget::ComputeLinkImplementationLibraries(const std::string& config, for (std::set::const_iterator it = seenProps.begin(); it != seenProps.end(); ++it) { - if (!this->GetProperty(*it)) + if (!thisTarget->GetProperty(*it)) { - this->LinkImplicitNullProperties.insert(*it); + thisTarget->LinkImplicitNullProperties.insert(*it); } } - cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards); + cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards); } - cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); - LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries(); + cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config); + cmTarget::LinkLibraryVectorType const& oldllibs = + thisTarget->GetOriginalLinkLibraries(); for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin(); li != oldllibs.end(); ++li) { if(li->second != cmTarget::GENERAL && li->second != linkType) { - std::string name = this->CheckCMP0004(li->first); - if(name == this->GetName() || name.empty()) + std::string name = thisTarget->CheckCMP0004(li->first); + if(name == thisTarget->GetName() || name.empty()) { continue; } // Support OLD behavior for CMP0003. impl.WrongConfigLibraries.push_back( - cmLinkItem(name, this->FindTargetToLink(name))); + cmLinkItem(name, thisTarget->FindTargetToLink(name))); } } } //---------------------------------------------------------------------------- void -cmTarget::ComputeLinkImplementationLanguages(const std::string& config, - LinkImplementation& impl) const +cmTargetInternals::ComputeLinkImplementationLanguages( + cmTarget const* thisTarget, + const std::string& config, + OptionalLinkImplementation& impl) const { // This target needs runtime libraries for its source languages. std::set languages; // Get languages used in our source files. - this->GetLanguages(languages, config); + thisTarget->GetLanguages(languages, config); // Copy the set of langauges to the link implementation. for(std::set::iterator li = languages.begin(); li != languages.end(); ++li) diff --git a/Source/cmTarget.h b/Source/cmTarget.h index b4c8a0f..f8bed4f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -797,11 +797,6 @@ private: LinkImplementationLibraries const* GetLinkImplementationLibrariesInternal(const std::string& config, cmTarget const* head) const; - void ComputeLinkImplementationLibraries(const std::string& config, - LinkImplementation& impl, - cmTarget const* head) const; - void ComputeLinkImplementationLanguages(const std::string& config, - LinkImplementation& impl) const; void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const; void ExpandLinkItems(std::string const& prop, std::string const& value, -- cgit v0.12 From 807e4ffeefb0e10ef0546e0eb7383f3d5533809b Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jul 2014 13:02:22 -0400 Subject: Genex: Track whether an expression depends on the 'head' target --- Source/cmGeneratorExpression.cxx | 3 +++ Source/cmGeneratorExpression.h | 5 +++++ Source/cmGeneratorExpressionEvaluator.cxx | 14 ++++++++++++++ Source/cmGeneratorExpressionEvaluator.h | 1 + 4 files changed, 23 insertions(+) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 2b4d955..7fc1464 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -97,6 +97,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( context.Quiet = quiet; context.HadError = false; context.HadContextSensitiveCondition = false; + context.HadHeadSensitiveCondition = false; context.HeadTarget = headTarget; context.EvaluateForBuildsystem = this->EvaluateForBuildsystem; context.CurrentTarget = currentTarget ? currentTarget : headTarget; @@ -124,6 +125,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( if (!context.HadError) { this->HadContextSensitiveCondition = context.HadContextSensitiveCondition; + this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition; } this->DependTargets = context.DependTargets; @@ -137,6 +139,7 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( const std::string& input) : Backtrace(backtrace), Input(input), HadContextSensitiveCondition(false), + HadHeadSensitiveCondition(false), EvaluateForBuildsystem(false) { cmGeneratorExpressionLexer l; diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 324d23c..b952520 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -111,6 +111,10 @@ public: { return this->HadContextSensitiveCondition; } + bool GetHadHeadSensitiveCondition() const + { + return this->HadHeadSensitiveCondition; + } void SetEvaluateForBuildsystem(bool eval) { @@ -141,6 +145,7 @@ private: MaxLanguageStandard; mutable std::string Output; mutable bool HadContextSensitiveCondition; + mutable bool HadHeadSensitiveCondition; bool EvaluateForBuildsystem; }; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 28879f1..7a53d65 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -840,6 +840,10 @@ getLinkedTargetsContent( { context->HadContextSensitiveCondition = true; } + if (cge->GetHadHeadSensitiveCondition()) + { + context->HadHeadSensitiveCondition = true; + } } linkedTargetsContent = cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); @@ -871,6 +875,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmTarget const* target = context->HeadTarget; std::string propertyName = *parameters.begin(); + if (parameters.size() == 1) + { + context->HadHeadSensitiveCondition = true; + } if (!target && parameters.size() == 1) { reportError(context, content->GetOriginalExpression(), @@ -1190,6 +1198,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode { context->HadContextSensitiveCondition = true; } + if (cge->GetHadHeadSensitiveCondition()) + { + context->HadHeadSensitiveCondition = true; + } if (!linkedTargetsContent.empty()) { result += (result.empty() ? "" : ";") + linkedTargetsContent; @@ -1313,6 +1325,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode "not be used with add_custom_command or add_custom_target."); return std::string(); } + context->HadHeadSensitiveCondition = true; typedef std::map > LangMap; static LangMap availableFeatures; @@ -1446,6 +1459,7 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode } context->HadContextSensitiveCondition = true; + context->HadHeadSensitiveCondition = true; for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i) { diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 0ffb860..8a529e8 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -41,6 +41,7 @@ struct cmGeneratorExpressionContext bool Quiet; bool HadError; bool HadContextSensitiveCondition; + bool HadHeadSensitiveCondition; bool EvaluateForBuildsystem; }; -- cgit v0.12 From 7b743a2e761783f930de41db3f7a706b065bbb2e Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jul 2014 13:04:04 -0400 Subject: cmTarget: Avoid re-computing head-independent link interfaces --- Source/cmTarget.cxx | 60 ++++++++++++++++++++++++++++++++++++++++++++++------- Source/cmTarget.h | 3 ++- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 353a3a6..ca24d2d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -114,10 +114,12 @@ public: { OptionalLinkInterface(): LibrariesDone(false), AllDone(false), - Exists(false), ExplicitLibraries(0) {} + Exists(false), HadHeadSensitiveCondition(false), + ExplicitLibraries(0) {} bool LibrariesDone; bool AllDone; bool Exists; + bool HadHeadSensitiveCondition; const char* ExplicitLibraries; }; void ComputeLinkInterface(cmTarget const* thisTarget, @@ -151,9 +153,11 @@ public: struct OptionalLinkImplementation: public cmTarget::LinkImplementation { OptionalLinkImplementation(): - LibrariesDone(false), LanguagesDone(false) {} + LibrariesDone(false), LanguagesDone(false), + HadHeadSensitiveCondition(false) {} bool LibrariesDone; bool LanguagesDone; + bool HadHeadSensitiveCondition; }; void ComputeLinkImplementationLibraries(cmTarget const* thisTarget, const std::string& config, @@ -3435,7 +3439,8 @@ void cmTarget::ExpandLinkItems(std::string const& prop, std::string const& config, cmTarget const* headTarget, bool usage_requirements_only, - std::vector& items) const + std::vector& items, + bool& hadHeadSensitiveCondition) const { cmGeneratorExpression ge; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0); @@ -3446,13 +3451,15 @@ void cmTarget::ExpandLinkItems(std::string const& prop, dagChecker.SetTransitivePropertiesOnly(); } std::vector libs; - cmSystemTools::ExpandListArgument(ge.Parse(value)->Evaluate( + cmsys::auto_ptr cge = ge.Parse(value); + cmSystemTools::ExpandListArgument(cge->Evaluate( this->Makefile, config, false, headTarget, this, &dagChecker), libs); this->LookupLinkItems(libs, items); + hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); } //---------------------------------------------------------------------------- @@ -5757,6 +5764,14 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( std::string CONFIG = cmSystemTools::UpperCase(config); cmTargetInternals::HeadToLinkInterfaceMap& hm = this->Internal->LinkInterfaceMap[CONFIG]; + + // If the link interface does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + cmTargetInternals::OptionalLinkInterface& iface = hm[head]; if(!iface.LibrariesDone) { @@ -5802,6 +5817,14 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config, (usage_requirements_only ? this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] : this->Internal->LinkInterfaceMap[CONFIG]); + + // If the link interface does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + cmTargetInternals::OptionalLinkInterface& iface = hm[head]; if(!iface.LibrariesDone) { @@ -5830,6 +5853,14 @@ cmTarget::GetImportLinkInterface(const std::string& config, (usage_requirements_only ? this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] : this->Internal->LinkInterfaceMap[CONFIG]); + + // If the link interface does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget]; if(!iface.AllDone) { @@ -5838,7 +5869,8 @@ cmTarget::GetImportLinkInterface(const std::string& config, cmSystemTools::ExpandListArgument(info->Languages, iface.Languages); this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, headTarget, usage_requirements_only, - iface.Libraries); + iface.Libraries, + iface.HadHeadSensitiveCondition); std::vector deps; cmSystemTools::ExpandListArgument(info->SharedDeps, deps); this->LookupLinkItems(deps, iface.SharedDeps); @@ -6022,7 +6054,8 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( // The interface libraries have been explicitly set. thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget, usage_requirements_only, - iface.Libraries); + iface.Libraries, + iface.HadHeadSensitiveCondition); } else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) @@ -6045,9 +6078,10 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp)) { + bool hadHeadSensitiveConditionDummy = false; thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config, headTarget, usage_requirements_only, - ifaceLibs); + ifaceLibs, hadHeadSensitiveConditionDummy); } if (ifaceLibs != iface.Libraries) { @@ -6271,6 +6305,14 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, std::string CONFIG = cmSystemTools::UpperCase(config); cmTargetInternals::HeadToLinkImplementationMap& hm = this->Internal->LinkImplMap[CONFIG]; + + // If the link implementation does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + cmTargetInternals::OptionalLinkImplementation& impl = hm[head]; if(!impl.LibrariesDone) { @@ -6305,6 +6347,10 @@ cmTargetInternals::ComputeLinkImplementationLibraries( std::string const evaluated = cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker); cmSystemTools::ExpandListArgument(evaluated, llibs); + if(cge->GetHadHeadSensitiveCondition()) + { + impl.HadHeadSensitiveCondition = true; + } for(std::vector::const_iterator li = llibs.begin(); li != llibs.end(); ++li) diff --git a/Source/cmTarget.h b/Source/cmTarget.h index f8bed4f..333e2ae 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -802,7 +802,8 @@ private: void ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, cmTarget const* headTarget, bool usage_requirements_only, - std::vector& items) const; + std::vector& items, + bool& hadHeadSensitiveCondition) const; void LookupLinkItems(std::vector const& names, std::vector& items) const; -- cgit v0.12