|
|
@@ -72,6 +72,11 @@ struct cmTarget::ImportInfo
|
|
|
cmTarget::LinkInterface LinkInterface;
|
|
|
};
|
|
|
|
|
|
+struct TargetConfigPair : public std::pair<cmTarget*, std::string> {
|
|
|
+ TargetConfigPair(cmTarget* tgt, const std::string &config)
|
|
|
+ : std::pair<cmTarget*, std::string>(tgt, config) {}
|
|
|
+};
|
|
|
+
|
|
|
//----------------------------------------------------------------------------
|
|
|
class cmTargetInternals
|
|
|
{
|
|
|
@@ -100,20 +105,24 @@ public:
|
|
|
OptionalLinkInterface(): Exists(false) {}
|
|
|
bool Exists;
|
|
|
};
|
|
|
- typedef std::map<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
|
|
|
+ typedef std::map<TargetConfigPair, OptionalLinkInterface>
|
|
|
+ LinkInterfaceMapType;
|
|
|
LinkInterfaceMapType LinkInterfaceMap;
|
|
|
|
|
|
typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
|
|
|
OutputInfoMapType OutputInfoMap;
|
|
|
|
|
|
- typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
|
|
|
+ typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
|
|
|
+ ImportInfoMapType;
|
|
|
ImportInfoMapType ImportInfoMap;
|
|
|
|
|
|
// Cache link implementation computation from each configuration.
|
|
|
- typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
|
|
|
+ typedef std::map<TargetConfigPair,
|
|
|
+ cmTarget::LinkImplementation> LinkImplMapType;
|
|
|
LinkImplMapType LinkImplMap;
|
|
|
|
|
|
- typedef std::map<cmStdString, cmTarget::LinkClosure> LinkClosureMapType;
|
|
|
+ typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
|
|
|
+ LinkClosureMapType;
|
|
|
LinkClosureMapType LinkClosureMap;
|
|
|
|
|
|
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
|
|
|
@@ -3024,8 +3033,11 @@ class cmTargetCollectLinkLanguages
|
|
|
{
|
|
|
public:
|
|
|
cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
|
|
|
- std::set<cmStdString>& languages):
|
|
|
- Config(config), Languages(languages) { this->Visited.insert(target); }
|
|
|
+ std::set<cmStdString>& languages,
|
|
|
+ cmTarget* head):
|
|
|
+ Config(config), Languages(languages), HeadTarget(head)
|
|
|
+ { this->Visited.insert(target); }
|
|
|
+
|
|
|
void Visit(cmTarget* target)
|
|
|
{
|
|
|
if(!target || !this->Visited.insert(target).second)
|
|
|
@@ -3034,7 +3046,7 @@ public:
|
|
|
}
|
|
|
|
|
|
cmTarget::LinkInterface const* iface =
|
|
|
- target->GetLinkInterface(this->Config);
|
|
|
+ target->GetLinkInterface(this->Config, this->HeadTarget);
|
|
|
if(!iface) { return; }
|
|
|
|
|
|
for(std::vector<std::string>::const_iterator
|
|
|
@@ -3053,26 +3065,30 @@ public:
|
|
|
private:
|
|
|
const char* Config;
|
|
|
std::set<cmStdString>& Languages;
|
|
|
+ cmTarget* HeadTarget;
|
|
|
std::set<cmTarget*> Visited;
|
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-const char* cmTarget::GetLinkerLanguage(const char* config)
|
|
|
+const char* cmTarget::GetLinkerLanguage(const char* config, cmTarget *head)
|
|
|
{
|
|
|
- const char* lang = this->GetLinkClosure(config)->LinkerLanguage.c_str();
|
|
|
+ cmTarget *headTarget = head ? head : this;
|
|
|
+ const char* lang = this->GetLinkClosure(config, headTarget)
|
|
|
+ ->LinkerLanguage.c_str();
|
|
|
return *lang? lang : 0;
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config)
|
|
|
+cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config,
|
|
|
+ cmTarget *head)
|
|
|
{
|
|
|
- std::string key = cmSystemTools::UpperCase(config? config : "");
|
|
|
+ TargetConfigPair key(head, cmSystemTools::UpperCase(config ? config : ""));
|
|
|
cmTargetInternals::LinkClosureMapType::iterator
|
|
|
i = this->Internal->LinkClosureMap.find(key);
|
|
|
if(i == this->Internal->LinkClosureMap.end())
|
|
|
{
|
|
|
LinkClosure lc;
|
|
|
- this->ComputeLinkClosure(config, lc);
|
|
|
+ this->ComputeLinkClosure(config, lc, head);
|
|
|
cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
|
|
|
i = this->Internal->LinkClosureMap.insert(entry).first;
|
|
|
}
|
|
|
@@ -3133,11 +3149,12 @@ public:
|
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
|
|
|
+void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc,
|
|
|
+ cmTarget *head)
|
|
|
{
|
|
|
// Get languages built in this target.
|
|
|
std::set<cmStdString> languages;
|
|
|
- LinkImplementation const* impl = this->GetLinkImplementation(config);
|
|
|
+ LinkImplementation const* impl = this->GetLinkImplementation(config, head);
|
|
|
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
|
|
|
li != impl->Languages.end(); ++li)
|
|
|
{
|
|
|
@@ -3145,7 +3162,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
|
|
|
}
|
|
|
|
|
|
// Add interface languages from linked targets.
|
|
|
- cmTargetCollectLinkLanguages cll(this, config, languages);
|
|
|
+ cmTargetCollectLinkLanguages cll(this, config, languages, head);
|
|
|
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
|
|
|
li != impl->Libraries.end(); ++li)
|
|
|
{
|
|
|
@@ -3284,7 +3301,8 @@ bool cmTarget::HasSOName(const char* config)
|
|
|
return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
|
|
|
this->GetType() == cmTarget::MODULE_LIBRARY) &&
|
|
|
!this->GetPropertyAsBool("NO_SONAME") &&
|
|
|
- this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
|
|
|
+ this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
|
|
|
+ this)));
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
@@ -3293,7 +3311,7 @@ std::string cmTarget::GetSOName(const char* config)
|
|
|
if(this->IsImported())
|
|
|
{
|
|
|
// Lookup the imported soname.
|
|
|
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
|
|
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
|
|
|
{
|
|
|
if(info->NoSOName)
|
|
|
{
|
|
|
@@ -3330,7 +3348,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config)
|
|
|
{
|
|
|
if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
|
|
|
{
|
|
|
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
|
|
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
|
|
|
{
|
|
|
return info->NoSOName;
|
|
|
}
|
|
|
@@ -3444,7 +3462,7 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
|
|
|
std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
|
|
|
{
|
|
|
std::string result;
|
|
|
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
|
|
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
|
|
|
{
|
|
|
result = implib? info->ImportLibrary : info->Location;
|
|
|
}
|
|
|
@@ -3529,7 +3547,7 @@ void cmTarget::GetFullNameInternal(const char* config,
|
|
|
const char* suffixVar = this->GetSuffixVariableInternal(implib);
|
|
|
|
|
|
// Check for language-specific default prefix and suffix.
|
|
|
- if(const char* ll = this->GetLinkerLanguage(config))
|
|
|
+ if(const char* ll = this->GetLinkerLanguage(config, this))
|
|
|
{
|
|
|
if(!targetSuffix && suffixVar && *suffixVar)
|
|
|
{
|
|
|
@@ -3900,7 +3918,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
|
|
|
}
|
|
|
|
|
|
// Check for rpath support on this platform.
|
|
|
- if(const char* ll = this->GetLinkerLanguage(config))
|
|
|
+ if(const char* ll = this->GetLinkerLanguage(config, this))
|
|
|
{
|
|
|
std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
|
|
|
flagVar += ll;
|
|
|
@@ -4322,7 +4340,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
|
|
|
|
|
|
// Enable if the rpath flag uses a separator and the target uses ELF
|
|
|
// binaries.
|
|
|
- if(const char* ll = this->GetLinkerLanguage(config))
|
|
|
+ if(const char* ll = this->GetLinkerLanguage(config, this))
|
|
|
{
|
|
|
std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
|
|
|
sepVar += ll;
|
|
|
@@ -4346,7 +4364,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
cmTarget::ImportInfo const*
|
|
|
-cmTarget::GetImportInfo(const char* config)
|
|
|
+cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
|
|
|
{
|
|
|
// There is no imported information for non-imported targets.
|
|
|
if(!this->IsImported())
|
|
|
@@ -4365,14 +4383,16 @@ cmTarget::GetImportInfo(const char* config)
|
|
|
{
|
|
|
config_upper = "NOCONFIG";
|
|
|
}
|
|
|
+ TargetConfigPair key(headTarget, config_upper);
|
|
|
typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
|
|
|
+
|
|
|
ImportInfoMapType::const_iterator i =
|
|
|
- this->Internal->ImportInfoMap.find(config_upper);
|
|
|
+ this->Internal->ImportInfoMap.find(key);
|
|
|
if(i == this->Internal->ImportInfoMap.end())
|
|
|
{
|
|
|
ImportInfo info;
|
|
|
- this->ComputeImportInfo(config_upper, info);
|
|
|
- ImportInfoMapType::value_type entry(config_upper, info);
|
|
|
+ this->ComputeImportInfo(config_upper, info, headTarget);
|
|
|
+ ImportInfoMapType::value_type entry(key, info);
|
|
|
i = this->Internal->ImportInfoMap.insert(entry).first;
|
|
|
}
|
|
|
|
|
|
@@ -4511,8 +4531,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
void cmTarget::ComputeImportInfo(std::string const& desired_config,
|
|
|
- ImportInfo& info)
|
|
|
+ ImportInfo& info,
|
|
|
+ cmTarget *headTarget)
|
|
|
{
|
|
|
+ (void)headTarget;
|
|
|
// This method finds information about an imported target from its
|
|
|
// properties. The "IMPORTED_" namespace is reserved for properties
|
|
|
// defined by the project exporting the target.
|
|
|
@@ -4669,12 +4691,13 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
|
|
|
+cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
|
|
|
+ cmTarget *head)
|
|
|
{
|
|
|
// Imported targets have their own link interface.
|
|
|
if(this->IsImported())
|
|
|
{
|
|
|
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
|
|
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
|
|
|
{
|
|
|
return &info->LinkInterface;
|
|
|
}
|
|
|
@@ -4690,14 +4713,15 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
|
|
|
}
|
|
|
|
|
|
// Lookup any existing link interface for this configuration.
|
|
|
- std::string key = cmSystemTools::UpperCase(config? config : "");
|
|
|
+ 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.Exists = this->ComputeLinkInterface(config, iface);
|
|
|
+ iface.Exists = this->ComputeLinkInterface(config, iface, head);
|
|
|
|
|
|
// Store the information for this configuration.
|
|
|
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
|
|
@@ -4708,7 +4732,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
|
|
+bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|
|
+ cmTarget *headTarget)
|
|
|
{
|
|
|
// Construct the property name suffix for this configuration.
|
|
|
std::string suffix = "_";
|
|
|
@@ -4765,7 +4790,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
|
|
{
|
|
|
emitted.insert(*li);
|
|
|
}
|
|
|
- LinkImplementation const* impl = this->GetLinkImplementation(config);
|
|
|
+ LinkImplementation const* impl = this->GetLinkImplementation(config,
|
|
|
+ headTarget);
|
|
|
for(std::vector<std::string>::const_iterator
|
|
|
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
|
|
|
{
|
|
|
@@ -4793,7 +4819,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
|
|
else
|
|
|
{
|
|
|
// The link implementation is the default link interface.
|
|
|
- LinkImplementation const* impl = this->GetLinkImplementation(config);
|
|
|
+ LinkImplementation const* impl = this->GetLinkImplementation(config,
|
|
|
+ headTarget);
|
|
|
iface.Libraries = impl->Libraries;
|
|
|
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
|
|
|
if(this->GetType() == cmTarget::STATIC_LIBRARY)
|
|
|
@@ -4825,7 +4852,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
cmTarget::LinkImplementation const*
|
|
|
-cmTarget::GetLinkImplementation(const char* config)
|
|
|
+cmTarget::GetLinkImplementation(const char* config, cmTarget *head)
|
|
|
{
|
|
|
// There is no link implementation for imported targets.
|
|
|
if(this->IsImported())
|
|
|
@@ -4834,14 +4861,15 @@ cmTarget::GetLinkImplementation(const char* config)
|
|
|
}
|
|
|
|
|
|
// Lookup any existing link implementation for this configuration.
|
|
|
- std::string key = cmSystemTools::UpperCase(config? config : "");
|
|
|
+ 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);
|
|
|
+ this->ComputeLinkImplementation(config, impl, head);
|
|
|
|
|
|
// Store the information for this configuration.
|
|
|
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
|
|
@@ -4853,8 +4881,10 @@ cmTarget::GetLinkImplementation(const char* config)
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
void cmTarget::ComputeLinkImplementation(const char* config,
|
|
|
- LinkImplementation& impl)
|
|
|
+ LinkImplementation& impl,
|
|
|
+ cmTarget *head)
|
|
|
{
|
|
|
+ (void)head;
|
|
|
// Compute which library configuration to link.
|
|
|
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
|
|
|
|
|
|
@@ -4977,16 +5007,19 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
cmComputeLinkInformation*
|
|
|
-cmTarget::GetLinkInformation(const char* config)
|
|
|
+cmTarget::GetLinkInformation(const char* config, cmTarget *head)
|
|
|
{
|
|
|
+ cmTarget *headTarget = head ? head : this;
|
|
|
// Lookup any existing information for this configuration.
|
|
|
- std::map<cmStdString, cmComputeLinkInformation*>::iterator
|
|
|
- i = this->LinkInformation.find(config?config:"");
|
|
|
+ TargetConfigPair key(headTarget,
|
|
|
+ cmSystemTools::UpperCase(config?config:""));
|
|
|
+ cmTargetLinkInformationMap::iterator
|
|
|
+ i = this->LinkInformation.find(key);
|
|
|
if(i == this->LinkInformation.end())
|
|
|
{
|
|
|
// Compute information for this configuration.
|
|
|
cmComputeLinkInformation* info =
|
|
|
- new cmComputeLinkInformation(this, config);
|
|
|
+ new cmComputeLinkInformation(this, config, headTarget);
|
|
|
if(!info || !info->Compute())
|
|
|
{
|
|
|
delete info;
|
|
|
@@ -4994,8 +5027,7 @@ cmTarget::GetLinkInformation(const char* config)
|
|
|
}
|
|
|
|
|
|
// Store the information for this configuration.
|
|
|
- std::map<cmStdString, cmComputeLinkInformation*>::value_type
|
|
|
- entry(config?config:"", info);
|
|
|
+ cmTargetLinkInformationMap::value_type entry(key, info);
|
|
|
i = this->LinkInformation.insert(entry).first;
|
|
|
}
|
|
|
return i->second;
|