瀏覽代碼

cmTarget: Report origin of COMPATIBLE_INTERFACE properties.

Stephen Kelly 12 年之前
父節點
當前提交
2e60b5fcf7

+ 134 - 3
Source/cmTarget.cxx

@@ -4423,6 +4423,95 @@ const char* impliedValue<const char*>(const char*)
   return "";
 }
 
+
+template<typename PropertyType>
+std::string valueAsString(PropertyType);
+template<>
+std::string valueAsString<bool>(bool value)
+{
+  return value ? "TRUE" : "FALSE";
+}
+template<>
+std::string valueAsString<const char*>(const char* value)
+{
+  return value ? value : "(unset)";
+}
+
+//----------------------------------------------------------------------------
+void
+cmTarget::ReportPropertyOrigin(const std::string &p,
+                               const std::string &result,
+                               const std::string &report,
+                               const std::string &compatibilityType) const
+{
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+          this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 p)
+                        != debugProperties.end();
+
+  if (this->Makefile->IsGeneratingBuildSystem())
+    {
+    this->DebugCompatiblePropertiesDone[p] = true;
+    }
+  if (!debugOrigin)
+    {
+    return;
+    }
+
+  std::string areport = compatibilityType;
+  areport += std::string(" of property \"") + p + "\" for target \"";
+  areport += std::string(this->GetName());
+  areport += "\" (result: \"";
+  areport += result;
+  areport += "\"):\n" + report;
+
+  cmListFileBacktrace lfbt;
+  this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport, lfbt);
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityType(CompatibleType t)
+{
+  switch(t)
+    {
+    case BoolType:
+      return "Boolean compatibility";
+    case StringType:
+      return "String compatibility";
+    case NumberMaxType:
+      return "Numeric maximum compatibility";
+    case NumberMinType:
+      return "Numeric minimum compatibility";
+    }
+  assert(!"Unreachable!");
+  return "";
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityAgree(CompatibleType t, bool dominant)
+{
+  switch(t)
+    {
+    case BoolType:
+    case StringType:
+      return "(Agree)\n";
+    case NumberMaxType:
+    case NumberMinType:
+      return dominant ? "(Dominant)\n" : "(Ignored)\n";
+    }
+  assert(!"Unreachable!");
+  return "";
+}
+
 //----------------------------------------------------------------------------
 template<typename PropertyType>
 PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
@@ -4450,6 +4539,23 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
   const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
   bool propInitialized = explicitlySet;
 
+  std::string report = " * Target \"";
+  report += tgt->GetName();
+  if (explicitlySet)
+    {
+    report += "\" has property content \"";
+    report += valueAsString<PropertyType>(propContent);
+    report += "\"\n";
+    }
+  else if (impliedByUse)
+    {
+    report += "\" property is implied by use.\n";
+    }
+  else
+    {
+    report += "\" property not set.\n";
+    }
+
   for(cmComputeLinkInformation::ItemVector::const_iterator li =
       deps.begin();
       li != deps.end(); ++li)
@@ -4471,6 +4577,17 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
     PropertyType ifacePropContent =
                     getTypedProperty<PropertyType>(li->Target,
                               ("INTERFACE_" + p).c_str(), 0);
+
+    std::string reportEntry;
+    if (ifacePropContent)
+      {
+      reportEntry += " * Target \"";
+      reportEntry += li->Target->GetName();
+      reportEntry += "\" property value \"";
+      reportEntry += valueAsString<PropertyType>(ifacePropContent);
+      reportEntry += "\" ";
+      }
+
     if (explicitlySet)
       {
       if (ifaceIsSet)
@@ -4489,7 +4606,8 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
           }
         else
           {
-          // Agree
+          report += reportEntry;
+          report += compatibilityAgree(t, propContent != consistent);
           propContent = consistent;
           continue;
           }
@@ -4503,6 +4621,13 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
     else if (impliedByUse)
       {
       propContent = impliedValue<PropertyType>(propContent);
+
+      reportEntry += " * Target \"";
+      reportEntry += li->Target->GetName();
+      reportEntry += "\" property value \"";
+      reportEntry += valueAsString<PropertyType>(propContent);
+      reportEntry += "\" ";
+
       if (ifaceIsSet)
         {
         PropertyType consistent = consistentProperty(propContent,
@@ -4520,7 +4645,8 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
           }
         else
           {
-          // Agree
+          report += reportEntry;
+          report += compatibilityAgree(t, propContent != consistent);
           propContent = consistent;
           continue;
           }
@@ -4551,13 +4677,15 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
             }
           else
             {
-            // Agree.
+            report += reportEntry;
+            report += compatibilityAgree(t, propContent != consistent);
             propContent = consistent;
             continue;
             }
           }
         else
           {
+          report += reportEntry + "(Interface set)\n";
           propContent = ifacePropContent;
           propInitialized = true;
           }
@@ -4569,6 +4697,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
         }
       }
     }
+
+  tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
+                            report, compatibilityType(t));
   return propContent;
 }
 

+ 6 - 0
Source/cmTarget.h

@@ -569,6 +569,11 @@ public:
   bool LinkLanguagePropagatesToDependents() const
   { return this->TargetTypeValue == STATIC_LIBRARY; }
 
+  void ReportPropertyOrigin(const std::string &p,
+                            const std::string &result,
+                            const std::string &report,
+                            const std::string &compatibilityType) const;
+
 private:
   bool HandleLocationPropertyPolicy() const;
 
@@ -691,6 +696,7 @@ private:
   bool IsApple;
   bool IsImportedTarget;
   mutable bool DebugIncludesDone;
+  mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugAutoUicOptionsDone;
   mutable bool DebugCompileDefinitionsDone;

+ 7 - 0
Tests/CompatibleInterface/CMakeLists.txt

@@ -31,6 +31,13 @@ set_property(TARGET iface1 APPEND PROPERTY
     NUMBER_MAX_PROP2
 )
 
+set(CMAKE_DEBUG_TARGET_PROPERTIES
+  BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4
+  STRING_PROP1 STRING_PROP2 STRING_PROP3
+  NUMBER_MIN_PROP1 NUMBER_MIN_PROP2
+  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)

+ 1 - 0
Tests/RunCMake/CompatibleInterface/DebugProperties-result.txt

@@ -0,0 +1 @@
+0

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

@@ -0,0 +1,73 @@
+CMake Debug Log:
+  Boolean compatibility of property "BOOL_PROP1" for target
+  "CompatibleInterface" \(result: "TRUE"\):
+
+   \* Target "CompatibleInterface" property not set.
+   \* Target "iface1" property value "TRUE" \(Interface set\)
++
+CMake Debug Log:
+  Boolean compatibility of property "BOOL_PROP2" for target
+  "CompatibleInterface" \(result: "TRUE"\):
+
+   \* Target "CompatibleInterface" has property content "TRUE"
+   \* Target "iface1" property value "TRUE" \(Agree\)
++
+CMake Debug Log:
+  Boolean compatibility of property "BOOL_PROP3" for target
+  "CompatibleInterface" \(result: "TRUE"\):
+
+   \* Target "CompatibleInterface" has property content "TRUE"
++
+CMake Debug Log:
+  Boolean compatibility of property "BOOL_PROP4" for target
+  "CompatibleInterface" \(result: "FALSE"\):
+
+   \* Target "CompatibleInterface" property not set.
++
+CMake Debug Log:
+  String compatibility of property "STRING_PROP1" for target
+  "CompatibleInterface" \(result: "prop1"\):
+
+   \* Target "CompatibleInterface" property not set.
+   \* Target "iface1" property value "prop1" \(Interface set\)
++
+CMake Debug Log:
+  String compatibility of property "STRING_PROP2" for target
+  "CompatibleInterface" \(result: "prop2"\):
+
+   \* Target "CompatibleInterface" has property content "prop2"
+   \* Target "iface1" property value "prop2" \(Agree\)
++
+CMake Debug Log:
+  String compatibility of property "STRING_PROP3" for target
+  "CompatibleInterface" \(result: "prop3"\):
+
+   \* Target "CompatibleInterface" has property content "prop3"
++
+CMake Debug Log:
+  Numeric minimum compatibility of property "NUMBER_MIN_PROP1" for target
+  "CompatibleInterface" \(result: "50"\):
+
+   \* Target "CompatibleInterface" has property content "50"
+   \* Target "iface1" property value "100" \(Ignored\)
++
+CMake Debug Log:
+  Numeric minimum compatibility of property "NUMBER_MIN_PROP2" for target
+  "CompatibleInterface" \(result: "200"\):
+
+   \* Target "CompatibleInterface" has property content "250"
+   \* Target "iface1" property value "200" \(Dominant\)
++
+CMake Debug Log:
+  Numeric maximum compatibility of property "NUMBER_MAX_PROP1" for target
+  "CompatibleInterface" \(result: "100"\):
+
+   \* Target "CompatibleInterface" has property content "50"
+   \* Target "iface1" property value "100" \(Dominant\)
++
+CMake Debug Log:
+  Numeric maximum compatibility of property "NUMBER_MAX_PROP2" for target
+  "CompatibleInterface" \(result: "250"\):
+
+   \* Target "CompatibleInterface" has property content "250"
+   \* Target "iface1" property value "200" \(Ignored\)

+ 60 - 0
Tests/RunCMake/CompatibleInterface/DebugProperties.cmake

@@ -0,0 +1,60 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(CompatibleInterface)
+
+include(GenerateExportHeader)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(iface1 INTERFACE)
+set_property(TARGET iface1 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_BOOL
+    BOOL_PROP1
+    BOOL_PROP2
+    BOOL_PROP3
+    BOOL_PROP4
+)
+set_property(TARGET iface1 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_STRING
+    STRING_PROP1
+    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(CMAKE_DEBUG_TARGET_PROPERTIES
+  BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4
+  STRING_PROP1 STRING_PROP2 STRING_PROP3
+  NUMBER_MIN_PROP1 NUMBER_MIN_PROP2
+  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 empty.cpp)
+target_link_libraries(CompatibleInterface iface1)
+
+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)

+ 1 - 0
Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake

@@ -9,3 +9,4 @@ run_cmake(InterfaceString-mismatch-depend-self)
 run_cmake(InterfaceString-mismatched-use)
 run_cmake(InterfaceString-builtin-prop)
 run_cmake(InterfaceString-Bool-Conflict)
+run_cmake(DebugProperties)

+ 1 - 0
Tests/RunCMake/PositionIndependentCode/Debug-result.txt

@@ -0,0 +1 @@
+0

+ 6 - 0
Tests/RunCMake/PositionIndependentCode/Debug-stderr.txt

@@ -0,0 +1,6 @@
+CMake Debug Log:
+  Boolean compatibility of property "POSITION_INDEPENDENT_CODE" for target
+  "foo" \(result: "TRUE"\):
+
+   \* Target "foo" has property content "TRUE"
+   \* Target "iface" property value "TRUE" \(Agree\)

+ 8 - 0
Tests/RunCMake/PositionIndependentCode/Debug.cmake

@@ -0,0 +1,8 @@
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES POSITION_INDEPENDENT_CODE)
+add_library(foo main.cpp)
+target_link_libraries(foo iface)
+set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)

+ 1 - 0
Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake

@@ -6,3 +6,4 @@ run_cmake(Conflict3)
 run_cmake(Conflict4)
 run_cmake(Conflict5)
 run_cmake(Conflict6)
+run_cmake(Debug)