summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmExportFileGenerator.cxx14
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx44
-rw-r--r--Source/cmTarget.cxx209
-rw-r--r--Source/cmTarget.h8
4 files changed, 262 insertions, 13 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index b01e499..65f1cc6 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -411,6 +411,12 @@ void getCompatibleInterfaceProperties(cmTarget *target,
getPropertyContents(li->Target,
"COMPATIBLE_INTERFACE_STRING",
ifaceProperties);
+ getPropertyContents(li->Target,
+ "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ ifaceProperties);
+ getPropertyContents(li->Target,
+ "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ ifaceProperties);
}
}
@@ -423,11 +429,19 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
target, properties);
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
target, properties);
+ this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MIN",
+ target, properties);
+ this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MAX",
+ target, properties);
std::set<std::string> ifaceProperties;
getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
+ getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ ifaceProperties);
+ getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ ifaceProperties);
getCompatibleInterfaceProperties(target, ifaceProperties, 0);
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 33863f4..f92c18e 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -980,10 +980,54 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
context->Config);
return propContent ? propContent : "";
}
+ if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMinProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMaxProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
return linkedTargetsContent;
}
+ if (!target->IsImported()
+ && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries())
+ {
+ if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMinProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentNumberMaxProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+ }
for (size_t i = 1;
i < cmArraySize(targetPropertyTransitiveWhitelist);
++i)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 91a7be8..c42ba95 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4453,7 +4453,9 @@ const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
enum CompatibleType
{
BoolType,
- StringType
+ StringType,
+ NumberMinType,
+ NumberMaxType
};
//----------------------------------------------------------------------------
@@ -4474,6 +4476,38 @@ const char * consistentStringProperty(const char *lhs, const char *rhs)
return strcmp(lhs, rhs) == 0 ? lhs : 0;
}
+#if defined(_MSC_VER) && _MSC_VER <= 1200
+template<typename T> const T&
+cmMaximum(const T& l, const T& r) {return l > r ? l : r;}
+template<typename T> const T&
+cmMinimum(const T& l, const T& r) {return l < r ? l : r;}
+#else
+#define cmMinimum std::min
+#define cmMaximum std::max
+#endif
+
+//----------------------------------------------------------------------------
+const char * consistentNumberProperty(const char *lhs, const char *rhs,
+ CompatibleType t)
+{
+ double lnum;
+ double rnum;
+ if(sscanf(lhs, "%lg", &lnum) != 1 ||
+ sscanf(rhs, "%lg", &rnum) != 1)
+ {
+ return 0;
+ }
+
+ if (t == NumberMaxType)
+ {
+ return cmMaximum(lnum, rnum) == lnum ? lhs : rhs;
+ }
+ else
+ {
+ return cmMinimum(lnum, rnum) == lnum ? lhs : rhs;
+ }
+}
+
//----------------------------------------------------------------------------
template<>
const char* consistentProperty(const char *lhs, const char *rhs,
@@ -4498,6 +4532,9 @@ const char* consistentProperty(const char *lhs, const char *rhs,
return 0;
case StringType:
return consistentStringProperty(lhs, rhs);
+ case NumberMinType:
+ case NumberMaxType:
+ return consistentNumberProperty(lhs, rhs, t);
}
assert(!"Unreachable!");
return 0;
@@ -4686,6 +4723,30 @@ const char * cmTarget::GetLinkInterfaceDependentStringProperty(
}
//----------------------------------------------------------------------------
+const char * cmTarget::GetLinkInterfaceDependentNumberMinProperty(
+ const std::string &p,
+ const char *config)
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ NumberMinType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty(
+ const std::string &p,
+ const char *config)
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ NumberMaxType, 0);
+}
+
+//----------------------------------------------------------------------------
bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
const char *interfaceProperty,
const char *config)
@@ -4754,6 +4815,30 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
}
//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const char *config)
+{
+ if (this->TargetTypeValue == OBJECT_LIBRARY)
+ {
+ return false;
+ }
+ return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ config);
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const char *config)
+{
+ if (this->TargetTypeValue == OBJECT_LIBRARY)
+ {
+ return false;
+ }
+ return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ config);
+}
+
+//----------------------------------------------------------------------------
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
{
for(std::vector<cmSourceFile*>::const_iterator
@@ -5759,6 +5844,10 @@ const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
return 0;
case StringType:
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+ case NumberMinType:
+ return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
+ case NumberMaxType:
+ return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
}
assert(!"Unreachable!");
return 0;
@@ -5812,6 +5901,50 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
}
}
+static cmStdString intersect(const std::set<cmStdString> &s1,
+ const std::set<cmStdString> &s2)
+{
+ std::set<cmStdString> 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 cmStdString intersect(const std::set<cmStdString> &s1,
+ const std::set<cmStdString> &s2,
+ const std::set<cmStdString> &s3)
+{
+ cmStdString result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3);
+}
+static cmStdString intersect(const std::set<cmStdString> &s1,
+ const std::set<cmStdString> &s2,
+ const std::set<cmStdString> &s3,
+ const std::set<cmStdString> &s4)
+{
+ cmStdString 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 char* config)
@@ -5820,6 +5953,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
std::set<cmStdString> emittedBools;
std::set<cmStdString> emittedStrings;
+ std::set<cmStdString> emittedMinNumbers;
+ std::set<cmStdString> emittedMaxNumbers;
for(cmComputeLinkInformation::ItemVector::const_iterator li =
deps.begin();
@@ -5845,23 +5980,71 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
{
return;
}
+ checkPropertyConsistency<const char *>(this, li->Target,
+ "COMPATIBLE_INTERFACE_NUMBER_MIN",
+ emittedMinNumbers, config,
+ NumberMinType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ "COMPATIBLE_INTERFACE_NUMBER_MAX",
+ emittedMaxNumbers, config,
+ NumberMaxType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
}
- for(std::set<cmStdString>::const_iterator li = emittedBools.begin();
- li != emittedBools.end(); ++li)
+ std::string prop = intersect(emittedBools,
+ emittedStrings,
+ emittedMinNumbers,
+ emittedMaxNumbers);
+
+ if (!prop.empty())
{
- const std::set<cmStdString>::const_iterator si = emittedStrings.find(*li);
- if (si != emittedStrings.end())
+ std::set<std::string> props;
+ std::set<cmStdString>::const_iterator i = emittedBools.find(prop);
+ if (i != emittedBools.end())
{
- cmOStringStream e;
- e << "Property \"" << *li << "\" appears in both the "
- "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING "
- "property in the dependencies of target \"" << this->GetName() <<
- "\". This is not allowed. A property may only require compatibility "
- "in a boolean interpretation or a string interpretation, but not both.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- break;
+ props.insert("COMPATIBLE_INTERFACE_BOOL");
+ }
+ i = emittedStrings.find(prop);
+ if (i != emittedStrings.end())
+ {
+ props.insert("COMPATIBLE_INTERFACE_STRING");
}
+ i = emittedMinNumbers.find(prop);
+ if (i != emittedMinNumbers.end())
+ {
+ props.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
+ }
+ i = emittedMaxNumbers.find(prop);
+ if (i != emittedMaxNumbers.end())
+ {
+ props.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
+ }
+
+ std::string propsString = *props.begin();
+ props.erase(props.begin());
+ while (props.size() > 1)
+ {
+ propsString += ", " + *props.begin();
+ props.erase(props.begin());
+ }
+ if (props.size() == 1)
+ {
+ propsString += " and the " + *props.begin();
+ }
+ cmOStringStream 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 or a string interpretation, but not both.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e8f4e08..9d62f5f 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -536,12 +536,20 @@ public:
const char *config);
bool IsLinkInterfaceDependentStringProperty(const std::string &p,
const char *config);
+ bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const char *config);
+ bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const char *config);
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config);
const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
const char *config);
+ const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const char *config);
+ const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const char *config);
std::string GetDebugGeneratorExpressions(const std::string &value,
cmTarget::LinkLibraryType llt);