From 7171fd0a903e71486e1d1cebc36aeaa2d2c71e8c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 5 Dec 2012 14:59:39 +0100 Subject: Add a way to check INTERFACE user property compatibility. --- Source/cmTarget.cxx | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Source/cmTarget.h | 2 ++ Source/cmake.cxx | 7 ++++++ Source/cmake.h | 2 ++ 4 files changed, 81 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9b50b8e..6f3f638 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -892,6 +892,19 @@ void cmTarget::DefineProperties(cmake *cm) "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 ("POST_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " @@ -5299,6 +5312,58 @@ std::string cmTarget::CheckCMP0004(std::string const& item) } //---------------------------------------------------------------------------- +void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, + const char* config) +{ + const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); + + std::set 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 props; + cmSystemTools::ExpandListArgument(prop, props); + + for(std::vector::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* cmTarget::GetLinkInformation(const char* config, cmTarget *head) { @@ -5319,6 +5384,11 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head) info = 0; } + if (info) + { + this->CheckPropertyCompatibility(info, config); + } + // Store the information for this configuration. cmTargetLinkInformationMap::value_type entry(key, info); i = this->LinkInformation.insert(entry).first; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index b4d053d..0963c5c 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -626,6 +626,8 @@ private: cmTarget *head); cmTargetLinkInformationMap LinkInformation; + void CheckPropertyCompatibility(cmComputeLinkInformation *info, + const char* config); bool ComputeLinkInterface(const char* config, LinkInterface& iface, cmTarget *head); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index a44c825..bbc7f1f 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -3552,6 +3552,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope, chained); } +bool cmake::GetIsPropertyDefined(const char *name, + cmProperty::ScopeType scope) +{ + return this->PropertyDefinitions[scope].find(name) != + this->PropertyDefinitions[scope].end(); +} + cmPropertyDefinition *cmake ::GetPropertyDefinition(const char *name, cmProperty::ScopeType scope) diff --git a/Source/cmake.h b/Source/cmake.h index e5aa076..f6fe0d6 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -341,6 +341,8 @@ class cmake bool chain = false, const char *variableGroup = 0); + bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope); + // get property definition cmPropertyDefinition *GetPropertyDefinition (const char *name, cmProperty::ScopeType scope); -- cgit v0.12