Merge topic 'compatible-interface-numbers'
ff6c401
cmTarget: Add interface for compatible numeric propertiese4e20c1
cmTarget: Add enumeration for consistency to expect from properties.9877769
cmTarget: Assign consistent content back to the property being evaluated.816b4a8
cmTarget: Make consistentProperty return consistent content.030800a
cmTarget: Add a template to create correct implied content.
This commit is contained in:
commit
4025013dd7
|
@ -76,6 +76,8 @@ Properties on Targets
|
|||
/prop_tgt/BUNDLE_EXTENSION
|
||||
/prop_tgt/BUNDLE
|
||||
/prop_tgt/COMPATIBLE_INTERFACE_BOOL
|
||||
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX
|
||||
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN
|
||||
/prop_tgt/COMPATIBLE_INTERFACE_STRING
|
||||
/prop_tgt/COMPILE_DEFINITIONS_CONFIG
|
||||
/prop_tgt/COMPILE_DEFINITIONS
|
||||
|
|
|
@ -14,4 +14,6 @@ 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. Note that
|
||||
for each dependee, the set of properties from this property must not
|
||||
intersect with the set of properties from the
|
||||
COMPATIBLE_INTERFACE_STRING property.
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_STRING`,
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN` or
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` property.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
COMPATIBLE_INTERFACE_NUMBER_MAX
|
||||
-------------------------------
|
||||
|
||||
Properties whose maximum value from the link interface will be used.
|
||||
|
||||
The COMPATIBLE_INTERFACE_NUMBER_MAX property may contain a list of
|
||||
properties for this target whose maximum value may be read at generate time
|
||||
when evaluated in the INTERFACE of all linked dependees. For example, if a
|
||||
property "FOO" appears in the list, then for each dependee, the
|
||||
"INTERFACE_FOO" property content in all of its dependencies will be compared
|
||||
with each other and with the "FOO" property in the depender. When reading
|
||||
the FOO property at generate time, the maximum value will be returned.
|
||||
If the property is not set, then it is ignored. Note that for each
|
||||
dependee, the set of properties from this property must not intersect
|
||||
with the set of properties from the :prop_tgt:`COMPATIBLE_INTERFACE_BOOL`,
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_STRING` or
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN` property.
|
|
@ -0,0 +1,17 @@
|
|||
COMPATIBLE_INTERFACE_NUMBER_MIN
|
||||
-------------------------------
|
||||
|
||||
Properties whose maximum value from the link interface will be used.
|
||||
|
||||
The COMPATIBLE_INTERFACE_NUMBER_MIN property may contain a list of
|
||||
properties for this target whose minimum value may be read at generate time
|
||||
when evaluated in the INTERFACE of all linked dependees. For example, if a
|
||||
property "FOO" appears in the list, then for each dependee, the
|
||||
"INTERFACE_FOO" property content in all of its dependencies will be compared
|
||||
with each other and with the "FOO" property in the depender. When reading
|
||||
the FOO property at generate time, the minimum value will be returned.
|
||||
If the property is not set, then it is ignored. Note that for each
|
||||
dependee, the set of properties from this property must not intersect
|
||||
with the set of properties from the :prop_tgt:`COMPATIBLE_INTERFACE_BOOL`,
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_STRING` or
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` property.
|
|
@ -11,5 +11,6 @@ property "FOO" appears in the list, then for each dependee, the
|
|||
equal with each other, and with the "FOO" property in the depender.
|
||||
If the property is not set, then it is ignored. Note that for each
|
||||
dependee, the set of properties from this property must not intersect
|
||||
with the set of properties from the COMPATIBLE_INTERFACE_BOOL
|
||||
property.
|
||||
with the set of properties from the :prop_tgt:`COMPATIBLE_INTERFACE_BOOL`,
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN` or
|
||||
:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` property.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -4455,26 +4455,107 @@ const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
|
|||
return tgt->GetProperty(prop);
|
||||
}
|
||||
|
||||
enum CompatibleType
|
||||
{
|
||||
BoolType,
|
||||
StringType,
|
||||
NumberMinType,
|
||||
NumberMaxType
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
bool consistentProperty(PropertyType lhs, PropertyType rhs);
|
||||
PropertyType consistentProperty(PropertyType lhs, PropertyType rhs,
|
||||
CompatibleType t);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool consistentProperty(bool lhs, bool rhs)
|
||||
bool consistentProperty(bool lhs, bool rhs, CompatibleType)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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<>
|
||||
bool consistentProperty(const char *lhs, const char *rhs)
|
||||
const char* consistentProperty(const char *lhs, const char *rhs,
|
||||
CompatibleType t)
|
||||
{
|
||||
if (!lhs && !rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (!lhs)
|
||||
{
|
||||
return rhs ? rhs : "";
|
||||
}
|
||||
if (!rhs)
|
||||
{
|
||||
return lhs ? lhs : "";
|
||||
}
|
||||
switch(t)
|
||||
{
|
||||
case BoolType:
|
||||
assert(!"consistentProperty for strings called with BoolType");
|
||||
return 0;
|
||||
case StringType:
|
||||
return consistentStringProperty(lhs, rhs);
|
||||
case NumberMinType:
|
||||
case NumberMaxType:
|
||||
return consistentNumberProperty(lhs, rhs, t);
|
||||
}
|
||||
assert(!"Unreachable!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename PropertyType>
|
||||
PropertyType impliedValue(PropertyType);
|
||||
template<>
|
||||
bool impliedValue<bool>(bool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
template<>
|
||||
const char* impliedValue<const char*>(const char*)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -4483,6 +4564,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
const std::string &p,
|
||||
const char *config,
|
||||
const char *defaultValue,
|
||||
CompatibleType t,
|
||||
PropertyType *)
|
||||
{
|
||||
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
|
||||
|
@ -4528,7 +4610,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
{
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
PropertyType consistent = consistentProperty(propContent,
|
||||
ifacePropContent, t);
|
||||
if (!consistent)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Property " << p << " on target \""
|
||||
|
@ -4541,6 +4625,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
else
|
||||
{
|
||||
// Agree
|
||||
propContent = consistent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -4552,9 +4637,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
}
|
||||
else if (impliedByUse)
|
||||
{
|
||||
propContent = impliedValue<PropertyType>(propContent);
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
PropertyType consistent = consistentProperty(propContent,
|
||||
ifacePropContent, t);
|
||||
if (!consistent)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Property " << p << " on target \""
|
||||
|
@ -4568,6 +4656,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
else
|
||||
{
|
||||
// Agree
|
||||
propContent = consistent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -4583,7 +4672,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
{
|
||||
if (propInitialized)
|
||||
{
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
PropertyType consistent = consistentProperty(propContent,
|
||||
ifacePropContent, t);
|
||||
if (!consistent)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "The INTERFACE_" << p << " property of \""
|
||||
|
@ -4596,6 +4687,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
|||
else
|
||||
{
|
||||
// Agree.
|
||||
propContent = consistent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -4620,7 +4712,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
const char *config)
|
||||
{
|
||||
return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
|
||||
0);
|
||||
BoolType, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -4631,7 +4723,32 @@ const char * cmTarget::GetLinkInterfaceDependentStringProperty(
|
|||
return checkInterfacePropertyCompatibility<const char *>(this,
|
||||
p,
|
||||
config,
|
||||
"empty", 0);
|
||||
"empty",
|
||||
StringType, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -4702,6 +4819,30 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
|
|||
config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
|
@ -5680,23 +5821,39 @@ template<typename PropertyType>
|
|||
PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
CompatibleType,
|
||||
PropertyType *);
|
||||
|
||||
template<>
|
||||
bool getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config, bool *)
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
CompatibleType, bool *)
|
||||
{
|
||||
return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
|
||||
}
|
||||
|
||||
template<>
|
||||
const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
const char **)
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
CompatibleType t,
|
||||
const char **)
|
||||
{
|
||||
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
|
||||
switch(t)
|
||||
{
|
||||
case BoolType:
|
||||
assert(!"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(!"Unreachable!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -5705,6 +5862,7 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
|
|||
const char *propName,
|
||||
std::set<cmStdString> &emitted,
|
||||
const char *config,
|
||||
CompatibleType t,
|
||||
PropertyType *)
|
||||
{
|
||||
const char *prop = dependee->GetProperty(propName);
|
||||
|
@ -5737,7 +5895,7 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
|
|||
if(emitted.insert(*pi).second)
|
||||
{
|
||||
getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
|
||||
0);
|
||||
t, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
|
@ -5746,6 +5904,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)
|
||||
|
@ -5754,6 +5956,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();
|
||||
|
@ -5766,35 +5970,84 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
|||
|
||||
checkPropertyConsistency<bool>(this, li->Target,
|
||||
"COMPATIBLE_INTERFACE_BOOL",
|
||||
emittedBools, config, 0);
|
||||
emittedBools, config, BoolType, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
checkPropertyConsistency<const char *>(this, li->Target,
|
||||
"COMPATIBLE_INTERFACE_STRING",
|
||||
emittedStrings, config, 0);
|
||||
emittedStrings, config,
|
||||
StringType, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -20,11 +20,25 @@ set_property(TARGET iface1 APPEND PROPERTY
|
|||
STRING_PROP2
|
||||
STRING_PROP3
|
||||
)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_NUMBER_MIN
|
||||
NUMBER_MIN_PROP1
|
||||
NUMBER_MIN_PROP2
|
||||
)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_NUMBER_MAX
|
||||
NUMBER_MAX_PROP1
|
||||
NUMBER_MAX_PROP2
|
||||
)
|
||||
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
|
||||
|
||||
add_executable(CompatibleInterface main.cpp)
|
||||
target_link_libraries(CompatibleInterface iface1)
|
||||
|
@ -33,6 +47,10 @@ set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
|
|||
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
|
||||
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
|
||||
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
|
||||
set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50)
|
||||
set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250)
|
||||
set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50)
|
||||
set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250)
|
||||
|
||||
target_compile_definitions(CompatibleInterface
|
||||
PRIVATE
|
||||
|
@ -42,6 +60,10 @@ target_compile_definitions(CompatibleInterface
|
|||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP1>,50>:NUMBER_MIN_PROP1=50>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250>
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,19 @@
|
|||
#error Expected STRING_PROP3
|
||||
#endif
|
||||
|
||||
template<bool test>
|
||||
struct CMakeStaticAssert;
|
||||
|
||||
template<>
|
||||
struct CMakeStaticAssert<true> {};
|
||||
|
||||
enum {
|
||||
NumericMaxTest1 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP1 == 100>),
|
||||
NumericMaxTest2 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP2 == 250>),
|
||||
NumericMinTest1 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP1 == 50>),
|
||||
NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>)
|
||||
};
|
||||
|
||||
#include "iface2.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
Loading…
Reference in New Issue