Merge topic 'compatible-interface-numbers'

ff6c401 cmTarget: Add interface for compatible numeric properties
e4e20c1 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:
Brad King 2013-10-26 10:28:30 -04:00 committed by CMake Topic Stage
commit 4025013dd7
11 changed files with 429 additions and 36 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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)

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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>
)

View File

@ -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)