[Cmake-commits] CMake branch, next, updated. v2.8.12-4318-gbc1f2e1

Stephen Kelly steveire at gmail.com
Wed Oct 23 08:03:42 EDT 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  bc1f2e13f7aa2190a7f8d63ae3327474d947efd2 (commit)
       via  e878a12faca20d032d3514e69e0866fb8d73f3c6 (commit)
       via  e7620f640c9a487bd59d108b850f42cb70c58101 (commit)
       via  d6c05295e7a0d17d26773b92e48031514b87a631 (commit)
       via  679623beb546c610f68f4582221b6d3c33da2185 (commit)
       via  7aada6b8fbe3895f35ff2bac9ead2cba711dd2ec (commit)
      from  e5be35f906c7af3806e2002c1e05c3fa0e20e1e9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bc1f2e13f7aa2190a7f8d63ae3327474d947efd2
commit bc1f2e13f7aa2190a7f8d63ae3327474d947efd2
Merge: e5be35f e878a12
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Oct 23 08:03:38 2013 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Wed Oct 23 08:03:38 2013 -0400

    Merge topic 'compatible-interface-numbers' into next
    
    e878a12 cmTarget: Add interface for compatible numeric properties
    e7620f6 cmTarget: Add enumeration for consistency to expect from properties.
    d6c0529 cmTarget: Assign consistent content back to the property being evaluated.
    679623b cmTarget: Make consistentProperty return consistent content.
    7aada6b cmTarget: Add a template to create correct implied content.

diff --cc Source/cmGeneratorExpressionEvaluator.cxx
index 33863f4,10aed62..f92c18e
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@@ -984,8 -1015,33 +1004,32 @@@ static const struct TargetPropertyNode 
        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 < (sizeof(targetPropertyTransitiveWhitelist) /
 -              sizeof(*targetPropertyTransitiveWhitelist));
 +         i < cmArraySize(targetPropertyTransitiveWhitelist);
           ++i)
        {
        if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e878a12faca20d032d3514e69e0866fb8d73f3c6
commit e878a12faca20d032d3514e69e0866fb8d73f3c6
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 19:51:36 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Oct 23 13:58:56 2013 +0200

    cmTarget: Add interface for compatible numeric properties
    
    When using the boost MPL library, one can set a define to increase
    the limit of how many variadic elements should be supported. The
    default for BOOST_MPL_LIMIT_VECTOR_SIZE is 20:
    
     http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/limit-vector-size.html
    
    If the foo library requires that to be set to 30, and the independent
    bar library requires it to be set to 40, consumers of both need to set
    it to 40.
    
     add_library(foo INTERFACE)
     set_property(TARGET foo PROPERTY INTERFACE_boost_mpl_vector_size 30)
     set_property(TARGET foo PROPERTY COMPATIBLE_INTERFACE_NUMBER_MAX boost_mpl_vector_size)
     target_compile_definitions(foo INTERFACE BOOST_MPL_LIMIT_VECTOR_SIZE=$<TARGET_PROPERTY:boost_mpl_vector_size>)
    
     add_library(bar INTERFACE)
     set_property(TARGET bar PROPERTY INTERFACE_boost_mpl_vector_size 40)
     # Technically the next two lines are redundant, but as foo and bar are
     # independent, they both set these interfaces.
     set_property(TARGET bar PROPERTY COMPATIBLE_INTERFACE_NUMBER_MAX boost_mpl_vector_size)
     target_compile_definitions(bar INTERFACE BOOST_MPL_LIMIT_VECTOR_SIZE=$<TARGET_PROPERTY:boost_mpl_vector_size>)
    
     add_executable(user)
     target_link_libraries(user foo bar)
    
    Because the TARGET_PROPERTY reads the boost_mpl_vector_size property
    from the HEAD of the dependency graph (the user target), and because
    that property appears in the COMPATIBLE_INTERFACE_NUMBER_MAX of
    the dependencies of the user target, the maximum value for it is
    chosen for the compile definition, ie, 40.
    
    There are also use-cases for choosing the minimum value of a number.
    In Qt, deprecated API can be disabled by version. Setting the
    definition QT_DISABLE_DEPRECATED_BEFORE=0 disables no deprecated
    API. Setting it to 0x501000 disables API which was deprecated before
    Qt 5.1 etc.
    
    If two dependencies require the use of API which was deprecated in
    different Qt versions, then COMPATIBLE_INTERFACE_NUMBER_MIN can be
    used to ensure that both can compile.

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index bb3acff..658da20 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -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
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst
index 7f95ef0..05e6137 100644
--- a/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst
@@ -14,4 +14,5 @@ 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.
+COMPATIBLE_INTERFACE_STRING, COMPATIBLE_INTERFACE_NUMBER_MIN or
+COMPATIBLE_INTERFACE_NUMBER_MAX property.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst
new file mode 100644
index 0000000..19baf33
--- /dev/null
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst
@@ -0,0 +1,16 @@
+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 COMPATIBLE_INTERFACE_BOOL,
+COMPATIBLE_INTERFACE_STRING or COMPATIBLE_INTERFACE_NUMBER_MIN property.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst
new file mode 100644
index 0000000..70ece03
--- /dev/null
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst
@@ -0,0 +1,16 @@
+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 COMPATIBLE_INTERFACE_BOOL,
+COMPATIBLE_INTERFACE_STRING or COMPATIBLE_INTERFACE_NUMBER_MAX property.
diff --git a/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst b/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst
index a461f76..5d10c1e 100644
--- a/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst
+++ b/Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst
@@ -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 dependee.
 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
+with the set of properties from the COMPATIBLE_INTERFACE_BOOL,
+COMPATIBLE_INTERFACE_NUMBER_MIN or COMPATIBLE_INTERFACE_NUMBER_MAX
 property.
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 dfd995e..10aed62 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -991,10 +991,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 < (sizeof(targetPropertyTransitiveWhitelist) /
               sizeof(*targetPropertyTransitiveWhitelist));
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 05592fb..ed36733 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
 };
 
 //----------------------------------------------------------------------------
@@ -4475,6 +4477,29 @@ const char * consistentStringProperty(const char *lhs, const char *rhs)
 }
 
 //----------------------------------------------------------------------------
+const char * consistentNumberProperty(const char *lhs, const char *rhs,
+                               CompatibleType t)
+{
+  double lnum;
+  double rnum;
+  bool result;
+  if(sscanf(lhs, "%lg", &lnum) != 1 ||
+      sscanf(rhs, "%lg", &rnum) != 1)
+    {
+    return 0;
+    }
+
+  if (t == NumberMaxType)
+    {
+    return std::max(lnum, rnum) == lnum ? lhs : rhs;
+    }
+  else
+    {
+    return std::min(lnum, rnum) == lnum ? lhs : rhs;
+    }
+}
+
+//----------------------------------------------------------------------------
 template<>
 const char* consistentProperty(const char *lhs, const char *rhs,
                                CompatibleType t)
@@ -4498,6 +4523,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 +4714,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 +4806,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
@@ -5734,6 +5810,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;
@@ -5787,6 +5867,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)
@@ -5795,6 +5919,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();
@@ -5820,23 +5946,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);
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
index 5ee9fd7..8186c61 100644
--- a/Tests/CompatibleInterface/CMakeLists.txt
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -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>
 )
 
 
diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp
index f5e6e38..fa299e9 100644
--- a/Tests/CompatibleInterface/main.cpp
+++ b/Tests/CompatibleInterface/main.cpp
@@ -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)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e7620f640c9a487bd59d108b850f42cb70c58101
commit e7620f640c9a487bd59d108b850f42cb70c58101
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 19:23:06 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Oct 23 13:58:11 2013 +0200

    cmTarget: Add enumeration for consistency to expect from properties.
    
    The type of consistency to be expected will be extended to cover
    numeric minimum and maximum.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index eb7158f..05592fb 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4450,20 +4450,34 @@ const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
   return tgt->GetProperty(prop);
 }
 
+enum CompatibleType
+{
+  BoolType,
+  StringType
+};
+
 //----------------------------------------------------------------------------
 template<typename PropertyType>
-PropertyType 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;
+}
+
+//----------------------------------------------------------------------------
 template<>
-const char* consistentProperty(const char *lhs, const char *rhs)
+const char* consistentProperty(const char *lhs, const char *rhs,
+                               CompatibleType t)
 {
   if (!lhs && !rhs)
     {
@@ -4477,7 +4491,16 @@ const char* consistentProperty(const char *lhs, const char *rhs)
     {
     return lhs ? lhs : "";
     }
-  return strcmp(lhs, rhs) == 0 ? lhs : 0;
+  switch(t)
+  {
+  case BoolType:
+    assert(!"consistentProperty for strings called with BoolType");
+    return 0;
+  case StringType:
+    return consistentStringProperty(lhs, rhs);
+  }
+  assert(!"Unreachable!");
+  return 0;
 }
 
 template<typename PropertyType>
@@ -4499,6 +4522,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(),
@@ -4545,7 +4569,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
       if (ifaceIsSet)
         {
         PropertyType consistent = consistentProperty(propContent,
-                                                     ifacePropContent);
+                                                     ifacePropContent, t);
         if (!consistent)
           {
           cmOStringStream e;
@@ -4575,7 +4599,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
       if (ifaceIsSet)
         {
         PropertyType consistent = consistentProperty(propContent,
-                                                     ifacePropContent);
+                                                     ifacePropContent, t);
         if (!consistent)
           {
           cmOStringStream e;
@@ -4607,7 +4631,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
         if (propInitialized)
           {
           PropertyType consistent = consistentProperty(propContent,
-                                                       ifacePropContent);
+                                                       ifacePropContent, t);
           if (!consistent)
             {
             cmOStringStream e;
@@ -4646,7 +4670,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
                                                      const char *config)
 {
   return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
-                                                   0);
+                                                   BoolType, 0);
 }
 
 //----------------------------------------------------------------------------
@@ -4657,7 +4681,8 @@ const char * cmTarget::GetLinkInterfaceDependentStringProperty(
   return checkInterfacePropertyCompatibility<const char *>(this,
                                                            p,
                                                            config,
-                                                           "empty", 0);
+                                                           "empty",
+                                                           StringType, 0);
 }
 
 //----------------------------------------------------------------------------
@@ -5683,23 +5708,35 @@ 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);
+  }
+  assert(!"Unreachable!");
+  return 0;
 }
 
 //----------------------------------------------------------------------------
@@ -5708,6 +5745,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);
@@ -5740,7 +5778,7 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
     if(emitted.insert(*pi).second)
       {
       getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
-                                                      0);
+                                                      t, 0);
       if (cmSystemTools::GetErrorOccuredFlag())
         {
         return;
@@ -5769,14 +5807,15 @@ 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;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d6c05295e7a0d17d26773b92e48031514b87a631
commit d6c05295e7a0d17d26773b92e48031514b87a631
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 19:12:51 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Oct 23 13:34:07 2013 +0200

    cmTarget: Assign consistent content back to the property being evaluated.
    
    Currently, 'consistent' means the same or not set. Soon though,
    it will be possible to choose a minimum number from an interface
    for example.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 374d868..eb7158f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4544,7 +4544,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
       {
       if (ifaceIsSet)
         {
-        if (!consistentProperty(propContent, ifacePropContent))
+        PropertyType consistent = consistentProperty(propContent,
+                                                     ifacePropContent);
+        if (!consistent)
           {
           cmOStringStream e;
           e << "Property " << p << " on target \""
@@ -4557,6 +4559,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
         else
           {
           // Agree
+          propContent = consistent;
           continue;
           }
         }
@@ -4571,7 +4574,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
       propContent = impliedValue<PropertyType>();
       if (ifaceIsSet)
         {
-        if (!consistentProperty(propContent, ifacePropContent))
+        PropertyType consistent = consistentProperty(propContent,
+                                                     ifacePropContent);
+        if (!consistent)
           {
           cmOStringStream e;
           e << "Property " << p << " on target \""
@@ -4585,6 +4590,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
         else
           {
           // Agree
+          propContent = consistent;
           continue;
           }
         }
@@ -4600,7 +4606,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
         {
         if (propInitialized)
           {
-          if (!consistentProperty(propContent, ifacePropContent))
+          PropertyType consistent = consistentProperty(propContent,
+                                                       ifacePropContent);
+          if (!consistent)
             {
             cmOStringStream e;
             e << "The INTERFACE_" << p << " property of \""
@@ -4613,6 +4621,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
           else
             {
             // Agree.
+            propContent = consistent;
             continue;
             }
           }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=679623beb546c610f68f4582221b6d3c33da2185
commit 679623beb546c610f68f4582221b6d3c33da2185
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 18:51:51 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Oct 23 13:34:07 2013 +0200

    cmTarget: Make consistentProperty return consistent content.
    
    Upcoming features will make use of that.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 39de32f..374d868 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4452,7 +4452,7 @@ const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
 
 //----------------------------------------------------------------------------
 template<typename PropertyType>
-bool consistentProperty(PropertyType lhs, PropertyType rhs);
+PropertyType consistentProperty(PropertyType lhs, PropertyType rhs);
 
 //----------------------------------------------------------------------------
 template<>
@@ -4463,13 +4463,21 @@ bool consistentProperty(bool lhs, bool rhs)
 
 //----------------------------------------------------------------------------
 template<>
-bool consistentProperty(const char *lhs, const char *rhs)
+const char* consistentProperty(const char *lhs, const char *rhs)
 {
   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 : "";
+    }
+  return strcmp(lhs, rhs) == 0 ? lhs : 0;
 }
 
 template<typename PropertyType>

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7aada6b8fbe3895f35ff2bac9ead2cba711dd2ec
commit 7aada6b8fbe3895f35ff2bac9ead2cba711dd2ec
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 19:29:57 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Oct 23 13:34:07 2013 +0200

    cmTarget: Add a template to create correct implied content.
    
    Otherwise, in the string case, we would get a null pointer instead
    of the implied empty string. That will become relevant when the
    comparison result is used.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 126cdbd..39de32f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4472,6 +4472,19 @@ bool consistentProperty(const char *lhs, const char *rhs)
   return strcmp(lhs, rhs) == 0;
 }
 
+template<typename PropertyType>
+PropertyType impliedValue();
+template<>
+bool impliedValue<bool>()
+{
+  return false;
+}
+template<>
+const char* impliedValue<const char*>()
+{
+  return "";
+}
+
 //----------------------------------------------------------------------------
 template<typename PropertyType>
 PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
@@ -4547,6 +4560,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
       }
     else if (impliedByUse)
       {
+      propContent = impliedValue<PropertyType>();
       if (ifaceIsSet)
         {
         if (!consistentProperty(propContent, ifacePropContent))

-----------------------------------------------------------------------

Summary of changes:
 Help/manual/cmake-properties.7.rst                |    2 +
 Help/prop_tgt/COMPATIBLE_INTERFACE_BOOL.rst       |    3 +-
 Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst |   16 +
 Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst |   16 +
 Help/prop_tgt/COMPATIBLE_INTERFACE_STRING.rst     |    3 +-
 Source/cmExportFileGenerator.cxx                  |   14 +
 Source/cmGeneratorExpressionEvaluator.cxx         |   44 +++
 Source/cmTarget.cxx                               |  310 ++++++++++++++++++---
 Source/cmTarget.h                                 |    8 +
 Tests/CompatibleInterface/CMakeLists.txt          |   22 ++
 Tests/CompatibleInterface/main.cpp                |   13 +
 11 files changed, 416 insertions(+), 35 deletions(-)
 create mode 100644 Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX.rst
 create mode 100644 Help/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN.rst


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list