summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmGeneratorTarget.cxx236
-rw-r--r--Source/cmGeneratorTarget.h3
-rw-r--r--Source/cmTarget.cxx285
-rw-r--r--Source/cmTarget.h11
4 files changed, 268 insertions, 267 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 845c052..1f3effb 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1524,6 +1524,240 @@ bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
}
+template<typename PropertyType>
+PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ cmTarget::CompatibleType,
+ PropertyType *);
+
+template<>
+bool getLinkInterfaceDependentProperty(cmTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ cmTarget::CompatibleType, bool *)
+{
+ return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
+}
+
+template<>
+const char * getLinkInterfaceDependentProperty(cmTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ cmTarget::CompatibleType t,
+ const char **)
+{
+ switch(t)
+ {
+ case cmTarget::BoolType:
+ assert(0 && "String compatibility check function called for boolean");
+ return 0;
+ case cmTarget::StringType:
+ return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+ case cmTarget::NumberMinType:
+ return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
+ case cmTarget::NumberMaxType:
+ return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
+ }
+ assert(0 && "Unreachable!");
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+void checkPropertyConsistency(cmTarget const* depender,
+ cmTarget const* dependee,
+ const std::string& propName,
+ std::set<std::string> &emitted,
+ const std::string& config,
+ cmTarget::CompatibleType t,
+ PropertyType *)
+{
+ const char *prop = dependee->GetProperty(propName);
+ if (!prop)
+ {
+ return;
+ }
+
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(prop, props);
+ std::string pdir =
+ dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
+ pdir += "/Help/prop_tgt/";
+
+ for(std::vector<std::string>::iterator pi = props.begin();
+ pi != props.end(); ++pi)
+ {
+ std::string pname = cmSystemTools::HelpFileName(*pi);
+ std::string pfile = pdir + pname + ".rst";
+ if(cmSystemTools::FileExists(pfile.c_str(), true))
+ {
+ std::ostringstream e;
+ e << "Target \"" << dependee->GetName() << "\" has property \""
+ << *pi << "\" listed in its " << propName << " property. "
+ "This is not allowed. Only user-defined properties may appear "
+ "listed in the " << propName << " property.";
+ depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if(emitted.insert(*pi).second)
+ {
+ getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
+ t, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+ }
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2)
+{
+ std::set<std::string> intersect;
+ std::set_intersection(s1.begin(),s1.end(),
+ s2.begin(),s2.end(),
+ std::inserter(intersect,intersect.begin()));
+ if (!intersect.empty())
+ {
+ return *intersect.begin();
+ }
+ return "";
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2,
+ const std::set<std::string> &s3)
+{
+ std::string result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3);
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2,
+ const std::set<std::string> &s3,
+ const std::set<std::string> &s4)
+{
+ std::string result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s4);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3, s4);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::CheckPropertyCompatibility(
+ cmComputeLinkInformation *info, const std::string& config) const
+{
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ std::set<std::string> emittedBools;
+ static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
+ std::set<std::string> emittedStrings;
+ static std::string strString = "COMPATIBLE_INTERFACE_STRING";
+ std::set<std::string> emittedMinNumbers;
+ static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
+ std::set<std::string> emittedMaxNumbers;
+ static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin(); li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+
+ checkPropertyConsistency<bool>(this->Target, li->Target,
+ strBool,
+ emittedBools, config, cmTarget::BoolType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this->Target, li->Target,
+ strString,
+ emittedStrings, config,
+ cmTarget::StringType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this->Target, li->Target,
+ strNumMin,
+ emittedMinNumbers, config,
+ cmTarget::NumberMinType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this->Target, li->Target,
+ strNumMax,
+ emittedMaxNumbers, config,
+ cmTarget::NumberMaxType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+
+ std::string prop = intersect(emittedBools,
+ emittedStrings,
+ emittedMinNumbers,
+ emittedMaxNumbers);
+
+ if (!prop.empty())
+ {
+ // Use a sorted std::vector to keep the error message sorted.
+ std::vector<std::string> props;
+ std::set<std::string>::const_iterator i = emittedBools.find(prop);
+ if (i != emittedBools.end())
+ {
+ props.push_back(strBool);
+ }
+ i = emittedStrings.find(prop);
+ if (i != emittedStrings.end())
+ {
+ props.push_back(strString);
+ }
+ i = emittedMinNumbers.find(prop);
+ if (i != emittedMinNumbers.end())
+ {
+ props.push_back(strNumMin);
+ }
+ i = emittedMaxNumbers.find(prop);
+ if (i != emittedMaxNumbers.end())
+ {
+ props.push_back(strNumMax);
+ }
+ std::sort(props.begin(), props.end());
+
+ std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
+ propsString += " and the " + props.back();
+
+ std::ostringstream e;
+ e << "Property \"" << prop << "\" appears in both the "
+ << propsString <<
+ " property in the dependencies of target \"" << this->GetName() <<
+ "\". This is not allowed. A property may only require compatibility "
+ "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
+ "string interpretation, but not a mixture.";
+ this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+}
//----------------------------------------------------------------------------
cmComputeLinkInformation*
@@ -1550,7 +1784,7 @@ cmGeneratorTarget::GetLinkInformation(const std::string& config) const
if (info)
{
- this->Target->CheckPropertyCompatibility(info, config);
+ this->CheckPropertyCompatibility(info, config);
}
}
return i->second;
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e53f098..ae86e19 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -222,6 +222,9 @@ private:
cmTargetLinkInformationMap;
mutable cmTargetLinkInformationMap LinkInformation;
+ void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+ const std::string& config) const;
+
cmGeneratorTarget(cmGeneratorTarget const&);
void operator=(cmGeneratorTarget const&);
};
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d8904ea..b165545 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4554,23 +4554,16 @@ const char *getTypedProperty<const char *>(cmTarget const* tgt,
return tgt->GetProperty(prop);
}
-enum CompatibleType
-{
- BoolType,
- StringType,
- NumberMinType,
- NumberMaxType
-};
-
//----------------------------------------------------------------------------
template<typename PropertyType>
std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
PropertyType rhs,
- CompatibleType t);
+ cmTarget::CompatibleType t);
//----------------------------------------------------------------------------
template<>
-std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType)
+std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
+ cmTarget::CompatibleType)
{
return std::make_pair(lhs == rhs, lhs);
}
@@ -4585,8 +4578,8 @@ std::pair<bool, const char*> consistentStringProperty(const char *lhs,
//----------------------------------------------------------------------------
std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
- const char *rhs,
- CompatibleType t)
+ const char *rhs,
+ cmTarget::CompatibleType t)
{
char *pEnd;
@@ -4604,7 +4597,7 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
return std::pair<bool, const char*>(false, null_ptr);
}
- if (t == NumberMaxType)
+ if (t == cmTarget::NumberMaxType)
{
return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
}
@@ -4618,7 +4611,7 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
template<>
std::pair<bool, const char*> consistentProperty(const char *lhs,
const char *rhs,
- CompatibleType t)
+ cmTarget::CompatibleType t)
{
if (!lhs && !rhs)
{
@@ -4637,13 +4630,13 @@ std::pair<bool, const char*> consistentProperty(const char *lhs,
switch(t)
{
- case BoolType:
+ case cmTarget::BoolType:
assert(0 && "consistentProperty for strings called with BoolType");
return std::pair<bool, const char*>(false, null_ptr);
- case StringType:
+ case cmTarget::StringType:
return consistentStringProperty(lhs, rhs);
- case NumberMinType:
- case NumberMaxType:
+ case cmTarget::NumberMinType:
+ case cmTarget::NumberMaxType:
return consistentNumberProperty(lhs, rhs, t);
}
assert(0 && "Unreachable!");
@@ -4718,17 +4711,17 @@ cmTarget::ReportPropertyOrigin(const std::string &p,
}
//----------------------------------------------------------------------------
-std::string compatibilityType(CompatibleType t)
+std::string compatibilityType(cmTarget::CompatibleType t)
{
switch(t)
{
- case BoolType:
+ case cmTarget::BoolType:
return "Boolean compatibility";
- case StringType:
+ case cmTarget::StringType:
return "String compatibility";
- case NumberMaxType:
+ case cmTarget::NumberMaxType:
return "Numeric maximum compatibility";
- case NumberMinType:
+ case cmTarget::NumberMinType:
return "Numeric minimum compatibility";
}
assert(0 && "Unreachable!");
@@ -4736,15 +4729,15 @@ std::string compatibilityType(CompatibleType t)
}
//----------------------------------------------------------------------------
-std::string compatibilityAgree(CompatibleType t, bool dominant)
+std::string compatibilityAgree(cmTarget::CompatibleType t, bool dominant)
{
switch(t)
{
- case BoolType:
- case StringType:
+ case cmTarget::BoolType:
+ case cmTarget::StringType:
return dominant ? "(Disagree)\n" : "(Agree)\n";
- case NumberMaxType:
- case NumberMinType:
+ case cmTarget::NumberMaxType:
+ case cmTarget::NumberMinType:
return dominant ? "(Dominant)\n" : "(Ignored)\n";
}
assert(0 && "Unreachable!");
@@ -4757,7 +4750,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
const std::string &p,
const std::string& config,
const char *defaultValue,
- CompatibleType t,
+ cmTarget::CompatibleType t,
PropertyType *)
{
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
@@ -6224,240 +6217,6 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const
return lib;
}
-template<typename PropertyType>
-PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt,
- const std::string& prop,
- const std::string& config,
- CompatibleType,
- PropertyType *);
-
-template<>
-bool getLinkInterfaceDependentProperty(cmTarget const* tgt,
- const std::string& prop,
- const std::string& config,
- CompatibleType, bool *)
-{
- return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
-}
-
-template<>
-const char * getLinkInterfaceDependentProperty(cmTarget const* tgt,
- const std::string& prop,
- const std::string& config,
- CompatibleType t,
- const char **)
-{
- switch(t)
- {
- case BoolType:
- assert(0 && "String compatibility check function called for boolean");
- return 0;
- case StringType:
- return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
- case NumberMinType:
- return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
- case NumberMaxType:
- return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
- }
- assert(0 && "Unreachable!");
- return 0;
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-void checkPropertyConsistency(cmTarget const* depender,
- cmTarget const* dependee,
- const std::string& propName,
- std::set<std::string> &emitted,
- const std::string& config,
- CompatibleType t,
- PropertyType *)
-{
- const char *prop = dependee->GetProperty(propName);
- if (!prop)
- {
- return;
- }
-
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
- std::string pdir =
- dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
- pdir += "/Help/prop_tgt/";
-
- for(std::vector<std::string>::iterator pi = props.begin();
- pi != props.end(); ++pi)
- {
- std::string pname = cmSystemTools::HelpFileName(*pi);
- std::string pfile = pdir + pname + ".rst";
- if(cmSystemTools::FileExists(pfile.c_str(), true))
- {
- std::ostringstream e;
- e << "Target \"" << dependee->GetName() << "\" has property \""
- << *pi << "\" listed in its " << propName << " property. "
- "This is not allowed. Only user-defined properties may appear "
- "listed in the " << propName << " property.";
- depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
- if(emitted.insert(*pi).second)
- {
- getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
- t, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
- }
-}
-
-static std::string intersect(const std::set<std::string> &s1,
- const std::set<std::string> &s2)
-{
- std::set<std::string> intersect;
- std::set_intersection(s1.begin(),s1.end(),
- s2.begin(),s2.end(),
- std::inserter(intersect,intersect.begin()));
- if (!intersect.empty())
- {
- return *intersect.begin();
- }
- return "";
-}
-static std::string intersect(const std::set<std::string> &s1,
- const std::set<std::string> &s2,
- const std::set<std::string> &s3)
-{
- std::string result;
- result = intersect(s1, s2);
- if (!result.empty())
- return result;
- result = intersect(s1, s3);
- if (!result.empty())
- return result;
- return intersect(s2, s3);
-}
-static std::string intersect(const std::set<std::string> &s1,
- const std::set<std::string> &s2,
- const std::set<std::string> &s3,
- const std::set<std::string> &s4)
-{
- std::string result;
- result = intersect(s1, s2);
- if (!result.empty())
- return result;
- result = intersect(s1, s3);
- if (!result.empty())
- return result;
- result = intersect(s1, s4);
- if (!result.empty())
- return result;
- return intersect(s2, s3, s4);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
- const std::string& config) const
-{
- const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
-
- std::set<std::string> emittedBools;
- static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
- std::set<std::string> emittedStrings;
- static std::string strString = "COMPATIBLE_INTERFACE_STRING";
- std::set<std::string> emittedMinNumbers;
- static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
- std::set<std::string> emittedMaxNumbers;
- static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
-
- for(cmComputeLinkInformation::ItemVector::const_iterator li =
- deps.begin();
- li != deps.end(); ++li)
- {
- if (!li->Target)
- {
- continue;
- }
-
- checkPropertyConsistency<bool>(this, li->Target,
- strBool,
- emittedBools, config, BoolType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- strString,
- emittedStrings, config,
- StringType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- strNumMin,
- emittedMinNumbers, config,
- NumberMinType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- strNumMax,
- emittedMaxNumbers, config,
- NumberMaxType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
-
- std::string prop = intersect(emittedBools,
- emittedStrings,
- emittedMinNumbers,
- emittedMaxNumbers);
-
- if (!prop.empty())
- {
- // Use a sorted std::vector to keep the error message sorted.
- std::vector<std::string> props;
- std::set<std::string>::const_iterator i = emittedBools.find(prop);
- if (i != emittedBools.end())
- {
- props.push_back(strBool);
- }
- i = emittedStrings.find(prop);
- if (i != emittedStrings.end())
- {
- props.push_back(strString);
- }
- i = emittedMinNumbers.find(prop);
- if (i != emittedMinNumbers.end())
- {
- props.push_back(strNumMin);
- }
- i = emittedMaxNumbers.find(prop);
- if (i != emittedMaxNumbers.end())
- {
- props.push_back(strNumMax);
- }
- std::sort(props.begin(), props.end());
-
- std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
- propsString += " and the " + props.back();
-
- std::ostringstream e;
- e << "Property \"" << prop << "\" appears in both the "
- << propsString <<
- " property in the dependencies of target \"" << this->GetName() <<
- "\". This is not allowed. A property may only require compatibility "
- "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
- "string interpretation, but not a mixture.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
-}
-
//----------------------------------------------------------------------------
std::string cmTarget::GetFrameworkDirectory(const std::string& config,
bool rootDir) const
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e3410aa..8af74ef 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -590,6 +590,14 @@ public:
return this->LinkLibrariesForVS6;}
#endif
+ enum CompatibleType
+ {
+ BoolType,
+ StringType,
+ NumberMinType,
+ NumberMaxType
+ };
+
private:
bool HandleLocationPropertyPolicy(cmMakefile* context) const;
@@ -754,9 +762,6 @@ private:
struct CompileInfo;
CompileInfo const* GetCompileInfo(const std::string& config) const;
- void CheckPropertyCompatibility(cmComputeLinkInformation *info,
- const std::string& config) const;
-
LinkInterface const*
GetImportLinkInterface(const std::string& config, cmTarget const* head,
bool usage_requirements_only) const;