Add a way to check INTERFACE user property compatibility.

This commit is contained in:
Stephen Kelly 2012-12-05 14:59:39 +01:00 committed by Brad King
parent c0c8ef85fc
commit 7171fd0a90
4 changed files with 81 additions and 0 deletions

View File

@ -891,6 +891,19 @@ void cmTarget::DefineProperties(cmake *cm)
"must ensure that the targets that they link to have a consistent " "must ensure that the targets that they link to have a consistent "
"requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property."); "requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
cm->DefineProperty
("COMPATIBLE_INTERFACE_BOOL", cmProperty::TARGET,
"Properties which must be compatible with their link interface",
"The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
"for this target which must be consistent when evaluated as a boolean "
"in the INTERFACE of all linked dependencies. For example, if a "
"property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
"property content in all dependencies must be consistent with each "
"other, and with the \"FOO\" property in this target. "
"Consistency in this sense has the meaning that if the property is set,"
"then it must have the same boolean value as all others, and if the "
"property is not set, then it is ignored.");
cm->DefineProperty cm->DefineProperty
("POST_INSTALL_SCRIPT", cmProperty::TARGET, ("POST_INSTALL_SCRIPT", cmProperty::TARGET,
"Deprecated install support.", "Deprecated install support.",
@ -5298,6 +5311,58 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
return lib; return lib;
} }
//----------------------------------------------------------------------------
void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
const char* config)
{
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
std::set<cmStdString> emitted;
for(cmComputeLinkInformation::ItemVector::const_iterator li =
deps.begin();
li != deps.end(); ++li)
{
if (!li->Target)
{
continue;
}
const char *prop = li->Target->GetProperty("COMPATIBLE_INTERFACE_BOOL");
if (!prop)
{
continue;
}
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(prop, props);
for(std::vector<std::string>::iterator pi = props.begin();
pi != props.end(); ++pi)
{
if (this->Makefile->GetCMakeInstance()
->GetIsPropertyDefined(pi->c_str(),
cmProperty::TARGET))
{
cmOStringStream e;
e << "Target \"" << li->Target->GetName() << "\" has property \""
<< *pi << "\" listed in its COMPATIBLE_INTERFACE_BOOL property. "
"This is not allowed. Only user-defined properties may appear "
"listed in the COMPATIBLE_INTERFACE_BOOL property.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
if(emitted.insert(*pi).second)
{
this->GetLinkInterfaceDependentBoolProperty(*pi, config);
if (cmSystemTools::GetErrorOccuredFlag())
{
return;
}
}
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmComputeLinkInformation* cmComputeLinkInformation*
cmTarget::GetLinkInformation(const char* config, cmTarget *head) cmTarget::GetLinkInformation(const char* config, cmTarget *head)
@ -5319,6 +5384,11 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
info = 0; info = 0;
} }
if (info)
{
this->CheckPropertyCompatibility(info, config);
}
// Store the information for this configuration. // Store the information for this configuration.
cmTargetLinkInformationMap::value_type entry(key, info); cmTargetLinkInformationMap::value_type entry(key, info);
i = this->LinkInformation.insert(entry).first; i = this->LinkInformation.insert(entry).first;

View File

@ -626,6 +626,8 @@ private:
cmTarget *head); cmTarget *head);
cmTargetLinkInformationMap LinkInformation; cmTargetLinkInformationMap LinkInformation;
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
const char* config);
bool ComputeLinkInterface(const char* config, LinkInterface& iface, bool ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget *head); cmTarget *head);

View File

@ -3552,6 +3552,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
chained); chained);
} }
bool cmake::GetIsPropertyDefined(const char *name,
cmProperty::ScopeType scope)
{
return this->PropertyDefinitions[scope].find(name) !=
this->PropertyDefinitions[scope].end();
}
cmPropertyDefinition *cmake cmPropertyDefinition *cmake
::GetPropertyDefinition(const char *name, ::GetPropertyDefinition(const char *name,
cmProperty::ScopeType scope) cmProperty::ScopeType scope)

View File

@ -341,6 +341,8 @@ class cmake
bool chain = false, bool chain = false,
const char *variableGroup = 0); const char *variableGroup = 0);
bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
// get property definition // get property definition
cmPropertyDefinition *GetPropertyDefinition cmPropertyDefinition *GetPropertyDefinition
(const char *name, cmProperty::ScopeType scope); (const char *name, cmProperty::ScopeType scope);