浏览代码

cmTarget: Fix debug report for interface-set compatibility types.

If the dependent target sets the property to boolean false, ensure
that that appears in the debug report.  Previously, the report
output contained whether the property was consistent among dependencies,
displaying 'TRUE', instead of the content of the property, which may
be 'FALSE'.

Return a std::pair from the consistentProperty method.  This makes
it possible to make the return value for string types easier to
reason about.  The return value of consistentProperty was previously
set to an empty static string to emulate a 'true' value for the caller
in commit 816b4a8a (cmTarget: Make consistentProperty
return consistent content., 2013-10-22).  The pair makes the
consistency result properly typed.
Stephen Kelly 12 年之前
父节点
当前提交
01c545c596

+ 61 - 30
Source/cmTarget.cxx

@@ -4259,20 +4259,23 @@ enum CompatibleType
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 template<typename PropertyType>
 template<typename PropertyType>
-PropertyType consistentProperty(PropertyType lhs, PropertyType rhs,
-                                CompatibleType t);
+std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
+                                                 PropertyType rhs,
+                                                 CompatibleType t);
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 template<>
 template<>
-bool consistentProperty(bool lhs, bool rhs, CompatibleType)
+std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType)
 {
 {
-  return lhs == rhs;
+  return std::make_pair(lhs == rhs, lhs);
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-const char * consistentStringProperty(const char *lhs, const char *rhs)
+std::pair<bool, const char*> consistentStringProperty(const char *lhs,
+                                                      const char *rhs)
 {
 {
-  return strcmp(lhs, rhs) == 0 ? lhs : 0;
+  const bool b = strcmp(lhs, rhs) == 0;
+  return std::make_pair(b, b ? lhs : 0);
 }
 }
 
 
 #if defined(_MSC_VER) && _MSC_VER <= 1200
 #if defined(_MSC_VER) && _MSC_VER <= 1200
@@ -4286,49 +4289,69 @@ cmMinimum(const T& l, const T& r) {return l < r ? l : r;}
 #endif
 #endif
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-const char * consistentNumberProperty(const char *lhs, const char *rhs,
-                               CompatibleType t)
+std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
+                                                      const char *rhs,
+                                                      CompatibleType t)
 {
 {
+
+#if defined(_MSC_VER)
+  static const char* const null_ptr = 0;
+#else
+# define null_ptr 0
+#endif
+
   double lnum;
   double lnum;
   double rnum;
   double rnum;
   if(sscanf(lhs, "%lg", &lnum) != 1 ||
   if(sscanf(lhs, "%lg", &lnum) != 1 ||
       sscanf(rhs, "%lg", &rnum) != 1)
       sscanf(rhs, "%lg", &rnum) != 1)
     {
     {
-    return 0;
+    return std::pair<bool, const char*>(false, null_ptr);
     }
     }
 
 
+#if !defined(_MSC_VER)
+#undef null_ptr
+#endif
+
   if (t == NumberMaxType)
   if (t == NumberMaxType)
     {
     {
-    return cmMaximum(lnum, rnum) == lnum ? lhs : rhs;
+    return std::make_pair(true, cmMaximum(lnum, rnum) == lnum ? lhs : rhs);
     }
     }
   else
   else
     {
     {
-    return cmMinimum(lnum, rnum) == lnum ? lhs : rhs;
+    return std::make_pair(true, cmMinimum(lnum, rnum) == lnum ? lhs : rhs);
     }
     }
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 template<>
 template<>
-const char* consistentProperty(const char *lhs, const char *rhs,
-                               CompatibleType t)
+std::pair<bool, const char*> consistentProperty(const char *lhs,
+                                                const char *rhs,
+                                                CompatibleType t)
 {
 {
   if (!lhs && !rhs)
   if (!lhs && !rhs)
     {
     {
-    return "";
+    return std::make_pair(true, lhs);
     }
     }
   if (!lhs)
   if (!lhs)
     {
     {
-    return rhs ? rhs : "";
+    return std::make_pair(true, rhs);
     }
     }
   if (!rhs)
   if (!rhs)
     {
     {
-    return lhs ? lhs : "";
+    return std::make_pair(true, lhs);
     }
     }
+
+#if defined(_MSC_VER)
+  static const char* const null_ptr = 0;
+#else
+# define null_ptr 0
+#endif
+
   switch(t)
   switch(t)
   {
   {
   case BoolType:
   case BoolType:
     assert(!"consistentProperty for strings called with BoolType");
     assert(!"consistentProperty for strings called with BoolType");
-    return 0;
+    return std::pair<bool, const char*>(false, null_ptr);
   case StringType:
   case StringType:
     return consistentStringProperty(lhs, rhs);
     return consistentStringProperty(lhs, rhs);
   case NumberMinType:
   case NumberMinType:
@@ -4336,7 +4359,12 @@ const char* consistentProperty(const char *lhs, const char *rhs,
     return consistentNumberProperty(lhs, rhs, t);
     return consistentNumberProperty(lhs, rhs, t);
   }
   }
   assert(!"Unreachable!");
   assert(!"Unreachable!");
-  return 0;
+  return std::pair<bool, const char*>(false, null_ptr);
+
+#if !defined(_MSC_VER)
+#undef null_ptr
+#endif
+
 }
 }
 
 
 template<typename PropertyType>
 template<typename PropertyType>
@@ -4521,11 +4549,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
       {
       {
       if (ifaceIsSet)
       if (ifaceIsSet)
         {
         {
-        PropertyType consistent = consistentProperty(propContent,
+        std::pair<bool, PropertyType> consistent =
+                                  consistentProperty(propContent,
                                                      ifacePropContent, t);
                                                      ifacePropContent, t);
         report += reportEntry;
         report += reportEntry;
-        report += compatibilityAgree(t, propContent != consistent);
-        if (!consistent)
+        report += compatibilityAgree(t, propContent != consistent.second);
+        if (!consistent.first)
           {
           {
           cmOStringStream e;
           cmOStringStream e;
           e << "Property " << p << " on target \""
           e << "Property " << p << " on target \""
@@ -4537,7 +4566,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
           }
           }
         else
         else
           {
           {
-          propContent = consistent;
+          propContent = consistent.second;
           continue;
           continue;
           }
           }
         }
         }
@@ -4559,11 +4588,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
 
 
       if (ifaceIsSet)
       if (ifaceIsSet)
         {
         {
-        PropertyType consistent = consistentProperty(propContent,
+        std::pair<bool, PropertyType> consistent =
+                                  consistentProperty(propContent,
                                                      ifacePropContent, t);
                                                      ifacePropContent, t);
         report += reportEntry;
         report += reportEntry;
-        report += compatibilityAgree(t, propContent != consistent);
-        if (!consistent)
+        report += compatibilityAgree(t, propContent != consistent.second);
+        if (!consistent.first)
           {
           {
           cmOStringStream e;
           cmOStringStream e;
           e << "Property " << p << " on target \""
           e << "Property " << p << " on target \""
@@ -4576,7 +4606,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
           }
           }
         else
         else
           {
           {
-          propContent = consistent;
+          propContent = consistent.second;
           continue;
           continue;
           }
           }
         }
         }
@@ -4592,11 +4622,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
         {
         {
         if (propInitialized)
         if (propInitialized)
           {
           {
-          PropertyType consistent = consistentProperty(propContent,
+          std::pair<bool, PropertyType> consistent =
+                                    consistentProperty(propContent,
                                                        ifacePropContent, t);
                                                        ifacePropContent, t);
           report += reportEntry;
           report += reportEntry;
-          report += compatibilityAgree(t, propContent != consistent);
-          if (!consistent)
+          report += compatibilityAgree(t, propContent != consistent.second);
+          if (!consistent.first)
             {
             {
             cmOStringStream e;
             cmOStringStream e;
             e << "The INTERFACE_" << p << " property of \""
             e << "The INTERFACE_" << p << " property of \""
@@ -4608,7 +4639,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
             }
             }
           else
           else
             {
             {
-            propContent = consistent;
+            propContent = consistent.second;
             continue;
             continue;
             }
             }
           }
           }

+ 8 - 0
Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt

@@ -31,6 +31,14 @@ CMake Debug Log:
    \* Target "CompatibleInterface" property not set.
    \* Target "CompatibleInterface" property not set.
    \* Target "iface1" property value "FALSE" \(Interface set\)
    \* Target "iface1" property value "FALSE" \(Interface set\)
 +
 +
+CMake Debug Log:
+  Boolean compatibility of property "BOOL_PROP6" for target
+  "CompatibleInterface" \(result: "FALSE"\):
+
+   \* Target "CompatibleInterface" property not set.
+   \* Target "iface1" property value "FALSE" \(Interface set\)
+   \* Target "iface2" property value "FALSE" \(Agree\)
++
 CMake Debug Log:
 CMake Debug Log:
   String compatibility of property "STRING_PROP1" for target
   String compatibility of property "STRING_PROP1" for target
   "CompatibleInterface" \(result: "prop1"\):
   "CompatibleInterface" \(result: "prop1"\):

+ 7 - 2
Tests/RunCMake/CompatibleInterface/DebugProperties.cmake

@@ -14,6 +14,7 @@ set_property(TARGET iface1 APPEND PROPERTY
     BOOL_PROP3
     BOOL_PROP3
     BOOL_PROP4
     BOOL_PROP4
     BOOL_PROP5
     BOOL_PROP5
+    BOOL_PROP6
 )
 )
 set_property(TARGET iface1 APPEND PROPERTY
 set_property(TARGET iface1 APPEND PROPERTY
   COMPATIBLE_INTERFACE_STRING
   COMPATIBLE_INTERFACE_STRING
@@ -33,7 +34,7 @@ set_property(TARGET iface1 APPEND PROPERTY
 )
 )
 
 
 set(CMAKE_DEBUG_TARGET_PROPERTIES
 set(CMAKE_DEBUG_TARGET_PROPERTIES
-  BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 BOOL_PROP5
+  BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 BOOL_PROP5 BOOL_PROP6
   STRING_PROP1 STRING_PROP2 STRING_PROP3
   STRING_PROP1 STRING_PROP2 STRING_PROP3
   NUMBER_MIN_PROP1 NUMBER_MIN_PROP2
   NUMBER_MIN_PROP1 NUMBER_MIN_PROP2
   NUMBER_MAX_PROP1 NUMBER_MAX_PROP2
   NUMBER_MAX_PROP1 NUMBER_MAX_PROP2
@@ -42,6 +43,7 @@ set(CMAKE_DEBUG_TARGET_PROPERTIES
 set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
 set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
 set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
 set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
 set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP5 OFF)
 set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP5 OFF)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP6 OFF)
 set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
 set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
 set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
 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_PROP1 100)
@@ -49,8 +51,11 @@ 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_PROP1 100)
 set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
 set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
 
 
+add_library(iface2 INTERFACE)
+set_property(TARGET iface2 PROPERTY INTERFACE_BOOL_PROP6 OFF)
+
 add_executable(CompatibleInterface empty.cpp)
 add_executable(CompatibleInterface empty.cpp)
-target_link_libraries(CompatibleInterface iface1)
+target_link_libraries(CompatibleInterface iface1 iface2)
 
 
 set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
 set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
 set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
 set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)