Commit 042ecf04 authored by Stephen Kelly's avatar Stephen Kelly

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.
parent bf5ece51
......@@ -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
{
......
......@@ -494,6 +494,9 @@ public:
void AddLinkDependentTargetsForProperties(
const std::map<cmStdString, cmStdString> &map);
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment