cmGeneratorTarget: Move link implementation from cmTarget.

This commit is contained in:
Stephen Kelly 2015-08-05 18:17:55 +02:00
parent a8429a402d
commit df42dbb355
6 changed files with 200 additions and 212 deletions

View File

@ -1122,7 +1122,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
else if(!interfacePropertyName.empty())
{
if(cmLinkImplementationLibraries const* impl =
target->GetLinkImplementationLibraries(context->Config))
gtgt->GetLinkImplementationLibraries(context->Config))
{
linkedTargetsContent =
getLinkedTargetsContent(impl->Libraries, target,

View File

@ -847,7 +847,7 @@ static void AddInterfaceEntries(
std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
{
if(cmLinkImplementationLibraries const* impl =
thisTarget->Target->GetLinkImplementationLibraries(config))
thisTarget->GetLinkImplementationLibraries(config))
{
for (std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin(), end = impl->Libraries.end();
@ -1901,7 +1901,7 @@ cmGeneratorTarget::GetLinkImplementationClosure(
std::set<cmTarget const*> emitted;
cmLinkImplementationLibraries const* impl
= this->Target->GetLinkImplementationLibraries(config);
= this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
@ -2501,7 +2501,7 @@ cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
if(this->Makefile->IsOn("APPLE"))
{
cmLinkImplementationLibraries const* impl =
this->Target->GetLinkImplementationLibraries(config);
this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it)
@ -4363,8 +4363,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
{
// The link implementation is the default link interface.
cmLinkImplementationLibraries const*
impl = this->Target->GetLinkImplementationLibrariesInternal(config,
headTarget);
impl = this->GetLinkImplementationLibrariesInternal(config, headTarget);
iface.ImplementationIsInterface = true;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
}
@ -4558,8 +4557,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
{
// The link implementation is the default link interface.
cmLinkImplementationLibraries const* impl =
this->Target->GetLinkImplementationLibrariesInternal(config,
headTarget);
this->GetLinkImplementationLibrariesInternal(config, headTarget);
iface.Libraries.insert(iface.Libraries.end(),
impl->Libraries.begin(), impl->Libraries.end());
if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@ -4674,12 +4672,12 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
return 0;
}
cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
std::string CONFIG = cmSystemTools::UpperCase(config);
cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this->Target];
if(!impl.LibrariesDone)
{
impl.LibrariesDone = true;
this->Target->ComputeLinkImplementationLibraries(config, impl,
this->Target);
this->ComputeLinkImplementationLibraries(config, impl, this->Target);
}
if(!impl.LanguagesDone)
{
@ -4819,9 +4817,161 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
return false;
}
if(cmLinkImplementationLibraries const* impl =
this->Target->GetLinkImplementationLibraries(config))
this->GetLinkImplementationLibraries(config))
{
return !impl->Libraries.empty();
}
return false;
}
//----------------------------------------------------------------------------
cmLinkImplementationLibraries const*
cmGeneratorTarget::GetLinkImplementationLibraries(
const std::string& config) const
{
return this->GetLinkImplementationLibrariesInternal(config, this->Target);
}
//----------------------------------------------------------------------------
cmLinkImplementationLibraries const*
cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
const std::string& config, cmTarget const* head) const
{
// There is no link implementation for imported targets.
if(this->IsImported())
{
return 0;
}
// Populate the link implementation libraries for this configuration.
std::string CONFIG = cmSystemTools::UpperCase(config);
HeadToLinkImplementationMap& hm =
this->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;
}
cmOptionalLinkImplementation& impl = hm[head];
if(!impl.LibrariesDone)
{
impl.LibrariesDone = true;
this->ComputeLinkImplementationLibraries(config, impl, head);
}
return &impl;
}
//----------------------------------------------------------------------------
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
const std::string& config,
cmOptionalLinkImplementation& impl,
cmTarget const* head) const
{
cmStringRange entryRange =
this->Target->GetLinkImplementationEntries();
cmBacktraceRange btRange =
this->Target->GetLinkImplementationBacktraces();
cmBacktraceRange::const_iterator btIt = btRange.begin();
// Collect libraries directly linked in this configuration.
for (cmStringRange::const_iterator le = entryRange.begin(),
end = entryRange.end(); le != end; ++le, ++btIt)
{
std::vector<std::string> llibs;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(),
"LINK_LIBRARIES", 0, 0);
cmGeneratorExpression ge(*btIt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(*le);
std::string const evaluated =
cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
cmSystemTools::ExpandListArgument(evaluated, llibs);
if(cge->GetHadHeadSensitiveCondition())
{
impl.HadHeadSensitiveCondition = true;
}
for(std::vector<std::string>::const_iterator li = llibs.begin();
li != llibs.end(); ++li)
{
// Skip entries that resolve to the target itself or are empty.
std::string name = this->Target->CheckCMP0004(*li);
if(name == this->GetName() || name.empty())
{
if(name == this->GetName())
{
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
std::ostringstream e;
switch(this->Target->GetPolicyStatusCMP0038())
{
case cmPolicies::WARN:
{
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
messageType = cmake::AUTHOR_WARNING;
}
break;
case cmPolicies::OLD:
noMessage = true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
}
if(!noMessage)
{
e << "Target \"" << this->GetName() << "\" links to itself.";
this->LocalGenerator->GetCMakeInstance()->IssueMessage(
messageType, e.str(), this->Target->GetBacktrace());
if (messageType == cmake::FATAL_ERROR)
{
return;
}
}
}
continue;
}
// The entry is meant for this configuration.
impl.Libraries.push_back(
cmLinkImplItem(name, this->Target->FindTargetToLink(name),
*btIt, evaluated != *le));
}
std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
for (std::set<std::string>::const_iterator it = seenProps.begin();
it != seenProps.end(); ++it)
{
if (!this->GetProperty(*it))
{
this->Target->LinkImplicitNullProperties.insert(*it);
}
}
cge->GetMaxLanguageStandard(this->Target,
this->MaxLanguageStandards);
}
cmTarget::LinkLibraryType linkType = this->Target->ComputeLinkType(config);
cmTarget::LinkLibraryVectorType const& oldllibs =
this->Target->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->Target->CheckCMP0004(li->first);
if(name == this->GetName() || name.empty())
{
continue;
}
// Support OLD behavior for CMP0003.
impl.WrongConfigLibraries.push_back(
cmLinkItem(name, this->Target->FindTargetToLink(name)));
}
}
}

View File

@ -207,6 +207,13 @@ public:
cmOptionalLinkImplementation& impl
) const;
cmLinkImplementationLibraries const*
GetLinkImplementationLibraries(const std::string& config) const;
void ComputeLinkImplementationLibraries(const std::string& config,
cmOptionalLinkImplementation& impl,
cmTarget const* head) const;
// Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change
// when source file properties are changed and we do not have enough
@ -462,6 +469,16 @@ private:
void GetSourceFiles(std::vector<std::string>& files,
const std::string& config) const;
struct HeadToLinkImplementationMap:
public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
typedef std::map<std::string,
HeadToLinkImplementationMap> LinkImplMapType;
mutable LinkImplMapType LinkImplMap;
cmLinkImplementationLibraries const*
GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const;
typedef std::pair<std::string, bool> OutputNameKey;
typedef std::map<OutputNameKey, std::string> OutputNameMapType;
mutable OutputNameMapType OutputNameMap;
@ -477,6 +494,12 @@ public:
std::vector<cmTarget const*> const&
GetLinkImplementationClosure(const std::string& config) const;
mutable std::map<std::string, std::string> MaxLanguageStandards;
std::map<std::string, std::string> const&
GetMaxLanguageStandards() const
{
return this->MaxLanguageStandards;
}
};
struct cmStrictTargetComparison {

View File

@ -1152,8 +1152,8 @@ void cmLocalGenerator::AddCompileOptions(
}
for(std::map<std::string, std::string>::const_iterator it
= target->GetMaxLanguageStandards().begin();
it != target->GetMaxLanguageStandards().end(); ++it)
= gtgt->GetMaxLanguageStandards().begin();
it != gtgt->GetMaxLanguageStandards().end(); ++it)
{
const char* standard = target->GetProperty(it->first + "_STANDARD");
if(!standard)

View File

@ -95,12 +95,6 @@ public:
typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
ImportInfoMapType ImportInfoMap;
struct HeadToLinkImplementationMap:
public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
typedef std::map<std::string,
HeadToLinkImplementationMap> LinkImplMapType;
LinkImplMapType LinkImplMap;
std::set<cmLinkItem> UtilityItems;
bool UtilityItemsDone;
@ -405,7 +399,6 @@ void cmTarget::FinishConfigure()
// on-demand during the configuration. This ensures that build
// system generation uses up-to-date information even if other cache
// invalidation code in this source file is buggy.
this->ClearLinkMaps();
#if defined(_WIN32) && !defined(__CYGWIN__)
// Do old-style link dependency analysis only for CM_USE_OLD_VS6.
@ -416,12 +409,6 @@ void cmTarget::FinishConfigure()
#endif
}
//----------------------------------------------------------------------------
void cmTarget::ClearLinkMaps()
{
this->Internal->LinkImplMap.clear();
}
//----------------------------------------------------------------------------
cmListFileBacktrace const& cmTarget::GetBacktrace() const
{
@ -884,7 +871,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
this->LinkLibrariesForVS6.push_back( tmp );
#endif
this->OriginalLinkLibraries.push_back(tmp);
this->ClearLinkMaps();
// Add the explicit dependency information for this target. This is
// simply a set of libraries separated by ";". There should always
@ -983,6 +969,16 @@ cmBacktraceRange cmTarget::GetSourceBacktraces() const
return cmMakeRange(this->Internal->SourceBacktraces);
}
cmStringRange cmTarget::GetLinkImplementationEntries() const
{
return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
}
cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
{
return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
//----------------------------------------------------------------------------
void
@ -1611,10 +1607,6 @@ void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
{
this->Internal->ImportInfoMap.clear();
}
if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
{
this->ClearLinkMaps();
}
}
//----------------------------------------------------------------------------
@ -3162,163 +3154,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
}
}
cmOptionalLinkImplementation&
cmTarget::GetLinkImplMap(std::string const& config) const
{
// Populate the link implementation for this configuration.
std::string CONFIG = cmSystemTools::UpperCase(config);
return Internal->LinkImplMap[CONFIG][this];
}
//----------------------------------------------------------------------------
cmLinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibraries(const std::string& config) const
{
return this->GetLinkImplementationLibrariesInternal(config, this);
}
//----------------------------------------------------------------------------
cmLinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const
{
// There is no link implementation for imported targets.
if(this->IsImported())
{
return 0;
}
// Populate the link implementation libraries for this configuration.
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;
}
cmOptionalLinkImplementation& impl = hm[head];
if(!impl.LibrariesDone)
{
impl.LibrariesDone = true;
this->ComputeLinkImplementationLibraries(config, impl, head);
}
return &impl;
}
//----------------------------------------------------------------------------
void cmTarget::ComputeLinkImplementationLibraries(
const std::string& config,
cmOptionalLinkImplementation& impl,
cmTarget const* head) const
{
std::vector<cmListFileBacktrace>::const_iterator btIt =
this->Internal->LinkImplementationPropertyBacktraces.begin();
// Collect libraries directly linked in this configuration.
for (std::vector<std::string>::const_iterator
le = this->Internal->LinkImplementationPropertyEntries.begin(),
end = this->Internal->LinkImplementationPropertyEntries.end();
le != end; ++le, ++btIt)
{
std::vector<std::string> llibs;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(),
"LINK_LIBRARIES", 0, 0);
cmGeneratorExpression ge(*btIt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(*le);
std::string const evaluated =
cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
cmSystemTools::ExpandListArgument(evaluated, llibs);
if(cge->GetHadHeadSensitiveCondition())
{
impl.HadHeadSensitiveCondition = true;
}
for(std::vector<std::string>::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())
{
if(name == this->GetName())
{
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
std::ostringstream e;
switch(this->GetPolicyStatusCMP0038())
{
case cmPolicies::WARN:
{
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
messageType = cmake::AUTHOR_WARNING;
}
break;
case cmPolicies::OLD:
noMessage = true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
}
if(!noMessage)
{
e << "Target \"" << this->GetName() << "\" links to itself.";
this->Makefile->GetCMakeInstance()->IssueMessage(
messageType, e.str(), this->GetBacktrace());
if (messageType == cmake::FATAL_ERROR)
{
return;
}
}
}
continue;
}
// The entry is meant for this configuration.
impl.Libraries.push_back(
cmLinkImplItem(name, this->FindTargetToLink(name),
*btIt, evaluated != *le));
}
std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
for (std::set<std::string>::const_iterator it = seenProps.begin();
it != seenProps.end(); ++it)
{
if (!this->GetProperty(*it))
{
this->LinkImplicitNullProperties.insert(*it);
}
}
cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
}
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
cmTarget::LinkLibraryVectorType const& oldllibs =
this->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())
{
continue;
}
// Support OLD behavior for CMP0003.
impl.WrongConfigLibraries.push_back(
cmLinkItem(name, this->FindTargetToLink(name)));
}
}
}
//----------------------------------------------------------------------------
cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
{

View File

@ -225,16 +225,6 @@ public:
void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
cmLinkImplementationLibraries const*
GetLinkImplementationLibraries(const std::string& config) const;
void ComputeLinkImplementationLibraries(const std::string& config,
cmOptionalLinkImplementation& impl,
cmTarget const* head) const;
cmOptionalLinkImplementation&
GetLinkImplMap(std::string const& config) const;
cmTarget const* FindTargetToLink(std::string const& name) const;
/** Strip off leading and trailing whitespace from an item named in
@ -365,12 +355,6 @@ public:
bool LinkLanguagePropagatesToDependents() const
{ return this->TargetTypeValue == STATIC_LIBRARY; }
std::map<std::string, std::string> const&
GetMaxLanguageStandards() const
{
return this->MaxLanguageStandards;
}
cmStringRange GetIncludeDirectoriesEntries() const;
cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
@ -385,6 +369,9 @@ public:
cmStringRange GetSourceEntries() const;
cmBacktraceRange GetSourceBacktraces() const;
cmStringRange GetLinkImplementationEntries() const;
cmBacktraceRange GetLinkImplementationBacktraces() const;
#if defined(_WIN32) && !defined(__CYGWIN__)
const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
@ -471,7 +458,6 @@ private:
std::set<std::string> Utilities;
mutable std::set<std::string> LinkImplicitNullProperties;
std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
mutable std::map<std::string, std::string> MaxLanguageStandards;
cmPolicies::PolicyMap PolicyMap;
std::string Name;
std::string InstallPath;
@ -529,14 +515,8 @@ private:
void ComputeImportInfo(std::string const& desired_config,
ImportInfo& info) const;
cmLinkImplementationLibraries const*
GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const;
std::string ProcessSourceItemCMP0049(const std::string& s);
void ClearLinkMaps();
void MaybeInvalidatePropertyCache(const std::string& prop);
// Internal representation details.