summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx109
1 files changed, 100 insertions, 9 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0a192e6..ea031cd 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -96,8 +96,11 @@ public:
// Cache link interface computation from each configuration.
struct OptionalLinkInterface: public cmTarget::LinkInterface
{
- OptionalLinkInterface(): Exists(false) {}
+ OptionalLinkInterface():
+ Exists(false), Complete(false), ExplicitLibraries(0) {}
bool Exists;
+ bool Complete;
+ const char* ExplicitLibraries;
};
void ComputeLinkInterface(cmTarget const* thisTarget,
const char* config, OptionalLinkInterface& iface,
@@ -5207,17 +5210,70 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
{
// Compute the link interface for this configuration.
cmTargetInternals::OptionalLinkInterface iface;
- const char* explicitLibraries =
+ iface.ExplicitLibraries =
this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
- this->Internal->ComputeLinkInterface(this, config, iface,
- head, explicitLibraries);
+ if (iface.Exists)
+ {
+ this->Internal->ComputeLinkInterface(this, config, iface,
+ head, iface.ExplicitLibraries);
+ }
+
+ // Store the information for this configuration.
+ cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
+ i = this->Internal->LinkInterfaceMap.insert(entry).first;
+ }
+ else if(!i->second.Complete && i->second.Exists)
+ {
+ this->Internal->ComputeLinkInterface(this, config, i->second, head,
+ i->second.ExplicitLibraries);
+ }
+
+ return i->second.Exists ? &i->second : 0;
+}
+
+//----------------------------------------------------------------------------
+cmTarget::LinkInterface const*
+cmTarget::GetLinkInterfaceLibraries(const char* config,
+ cmTarget const* head) const
+{
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
+ {
+ return &info->LinkInterface;
+ }
+ return 0;
+ }
+
+ // Link interfaces are not supported for executables that do not
+ // export symbols.
+ if(this->GetType() == cmTarget::EXECUTABLE &&
+ !this->IsExecutableWithExports())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link interface for this configuration.
+ TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
+ cmTargetInternals::LinkInterfaceMapType::iterator
+ i = this->Internal->LinkInterfaceMap.find(key);
+ if(i == this->Internal->LinkInterfaceMap.end())
+ {
+ // Compute the link interface for this configuration.
+ cmTargetInternals::OptionalLinkInterface iface;
+ iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config,
+ iface,
+ head,
+ iface.Exists);
// Store the information for this configuration.
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
i = this->Internal->LinkInterfaceMap.insert(entry).first;
}
- return i->second.Exists? &i->second : 0;
+ return i->second.Exists ? &i->second : 0;
}
//----------------------------------------------------------------------------
@@ -5225,8 +5281,8 @@ void cmTarget::GetTransitivePropertyTargets(const char* config,
cmTarget const* headTarget,
std::vector<cmTarget*> &tgts) const
{
- cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
- headTarget);
+ cmTarget::LinkInterface const* iface
+ = this->GetLinkInterfaceLibraries(config, headTarget);
if (!iface)
{
return;
@@ -5387,8 +5443,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
// to the link implementation.
{
// The link implementation is the default link interface.
- LinkImplementation const* impl = this->GetLinkImplementation(config,
- headTarget);
+ LinkImplementation const* impl =
+ this->GetLinkImplementationLibraries(config, headTarget);
iface.Libraries = impl->Libraries;
if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
!this->Internal->PolicyWarnedCMP0022)
@@ -5554,6 +5610,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
sscanf(reps, "%u", &iface.Multiplicity);
}
}
+ iface.Complete = true;
}
//----------------------------------------------------------------------------
@@ -5582,6 +5639,40 @@ cmTarget::GetLinkImplementation(const char* config, cmTarget const* head) const
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
i = this->Internal->LinkImplMap.insert(entry).first;
}
+ else if (i->second.Languages.empty())
+ {
+ this->ComputeLinkImplementationLanguages(i->second);
+ }
+
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+cmTarget::LinkImplementation const*
+cmTarget::GetLinkImplementationLibraries(const char* config,
+ cmTarget const* head) const
+{
+ // There is no link implementation for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link implementation for this configuration.
+ TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
+ cmTargetInternals::LinkImplMapType::iterator
+ i = this->Internal->LinkImplMap.find(key);
+ if(i == this->Internal->LinkImplMap.end())
+ {
+ // Compute the link implementation for this configuration.
+ LinkImplementation impl;
+ this->ComputeLinkImplementation(config, impl, head);
+
+ // Store the information for this configuration.
+ cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
+ i = this->Internal->LinkImplMap.insert(entry).first;
+ }
return &i->second;
}