Add API to calculate link-interface-dependent bool properties or error.
This new method checks that the property FOO on a target is consistent with the INTERFACE_FOO properties of its dependees. If they are not the consistent, an error is reported. 'Consistent' means that iff the property is set, it must have the same boolean value as all other related properties.
This commit is contained in:
parent
bf5ece51c3
commit
042ecf0471
|
@ -4416,6 +4416,134 @@ void cmTarget::AddLinkDependentTargetsForProperties(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
|
const char *config)
|
||||||
|
{
|
||||||
|
bool propContent = this->GetPropertyAsBool(p.c_str());
|
||||||
|
const bool explicitlySet = this->GetProperties()
|
||||||
|
.find(p.c_str())
|
||||||
|
!= this->GetProperties().end();
|
||||||
|
std::set<std::string> dependentTargets;
|
||||||
|
this->GetLinkDependentTargetsForProperty(p,
|
||||||
|
dependentTargets);
|
||||||
|
const bool impliedByUse =
|
||||||
|
this->IsNullImpliedByLinkLibraries(p);
|
||||||
|
assert((impliedByUse ^ explicitlySet)
|
||||||
|
|| (!impliedByUse && !explicitlySet));
|
||||||
|
|
||||||
|
cmComputeLinkInformation *info = this->GetLinkInformation(config);
|
||||||
|
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||||
|
bool propInitialized = explicitlySet;
|
||||||
|
|
||||||
|
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||||
|
deps.begin();
|
||||||
|
li != deps.end(); ++li)
|
||||||
|
{
|
||||||
|
// An error should be reported if one dependency
|
||||||
|
// has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
|
||||||
|
// has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
|
||||||
|
// target itself has a POSITION_INDEPENDENT_CODE which disagrees
|
||||||
|
// with a dependency.
|
||||||
|
|
||||||
|
if (!li->Target)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool ifaceIsSet = li->Target->GetProperties()
|
||||||
|
.find("INTERFACE_" + p)
|
||||||
|
!= li->Target->GetProperties().end();
|
||||||
|
const bool ifacePropContent = li->Target->GetPropertyAsBool(
|
||||||
|
("INTERFACE_" + p).c_str());
|
||||||
|
if (explicitlySet)
|
||||||
|
{
|
||||||
|
if (ifaceIsSet)
|
||||||
|
{
|
||||||
|
if (propContent != ifacePropContent)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Property " << p << " on target \""
|
||||||
|
<< this->GetName() << "\" does\nnot match the "
|
||||||
|
"INTERFACE_" << p << " property requirement\nof "
|
||||||
|
"dependency \"" << li->Target->GetName() << "\".\n";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agree
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Explicitly set on target and not set in iface. Can't disagree.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (impliedByUse)
|
||||||
|
{
|
||||||
|
if (ifaceIsSet)
|
||||||
|
{
|
||||||
|
if (propContent != ifacePropContent)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Property " << p << " on target \""
|
||||||
|
<< this->GetName() << "\" is\nimplied to be FALSE because it "
|
||||||
|
"was used to determine the link libraries\nalready. The "
|
||||||
|
"INTERFACE_" << p << " property on\ndependency \""
|
||||||
|
<< li->Target->GetName() << "\" is in conflict.\n";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agree
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Implicitly set on target and not set in iface. Can't disagree.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ifaceIsSet)
|
||||||
|
{
|
||||||
|
if (propInitialized)
|
||||||
|
{
|
||||||
|
if (propContent != ifacePropContent)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "The INTERFACE_" << p << " property of \""
|
||||||
|
<< li->Target->GetName() << "\" does\nnot agree with the value "
|
||||||
|
"of " << p << " already determined\nfor \""
|
||||||
|
<< this->GetName() << "\".\n";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agree.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
propContent = ifacePropContent;
|
||||||
|
propInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not set. Nothing to agree on.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return propContent;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -494,6 +494,9 @@ public:
|
||||||
|
|
||||||
void AddLinkDependentTargetsForProperties(
|
void AddLinkDependentTargetsForProperties(
|
||||||
const std::map<cmStdString, cmStdString> &map);
|
const std::map<cmStdString, cmStdString> &map);
|
||||||
|
|
||||||
|
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
|
const char *config);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||||
|
|
Loading…
Reference in New Issue