Bladeren bron

Add the COMPATIBLE_INTERFACE_STRING property.

Stephen Kelly 12 jaren geleden
bovenliggende
commit
2fb2c32f9b
22 gewijzigde bestanden met toevoegingen van 186 en 1 verwijderingen
  1. 6 0
      Source/cmExportFileGenerator.cxx
  2. 7 0
      Source/cmGeneratorExpressionEvaluator.cxx
  3. 65 0
      Source/cmTarget.cxx
  4. 5 0
      Source/cmTarget.h
  5. 13 0
      Tests/CompatibleInterface/CMakeLists.txt
  6. 12 0
      Tests/CompatibleInterface/main.cpp
  7. 8 1
      Tests/ExportImport/Export/CMakeLists.txt
  8. 2 0
      Tests/ExportImport/Import/A/CMakeLists.txt
  9. 4 0
      Tests/ExportImport/Import/A/deps_shared_iface.cpp
  10. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt
  11. 5 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt
  12. 11 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
  13. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt
  14. 3 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt
  15. 11 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake
  16. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt
  17. 3 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt
  18. 10 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake
  19. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt
  20. 4 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt
  21. 9 0
      Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake
  22. 4 0
      Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake

+ 6 - 0
Source/cmExportFileGenerator.cxx

@@ -217,6 +217,9 @@ void getCompatibleInterfaceProperties(cmTarget *target,
     getPropertyContents(li->Target,
                         "COMPATIBLE_INTERFACE_BOOL",
                         ifaceProperties);
+    getPropertyContents(li->Target,
+                        "COMPATIBLE_INTERFACE_STRING",
+                        ifaceProperties);
     }
 }
 
@@ -227,10 +230,13 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
 {
   this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
                                 target, properties);
+  this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
+                                target, properties);
 
   std::set<std::string> ifaceProperties;
 
   getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
+  getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
 
   getCompatibleInterfaceProperties(target, ifaceProperties, 0);
 

+ 7 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -462,6 +462,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                                                 propertyName,
                                                 context->Config) ? "1" : "0";
         }
+      if (target->IsLinkInterfaceDependentStringProperty(propertyName,
+                                                         context->Config))
+        {
+        return target->GetLinkInterfaceDependentStringProperty(
+                                                propertyName,
+                                                context->Config);
+        }
 
       return std::string();
       }

+ 65 - 0
Source/cmTarget.cxx

@@ -907,6 +907,17 @@ void cmTarget::DefineProperties(cmake *cm)
      "then it must have the same boolean value as all others, and if the "
      "property is not set, then it is ignored.");
 
+  cm->DefineProperty
+    ("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
+     "Properties which must be string-compatible with their link interface",
+     "The COMPATIBLE_INTERFACE_STRING property may contain a list of "
+     "properties for this target which must be the same when evaluated as "
+     "a string in the INTERFACE of all linked dependencies.  For example, "
+     "if a property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
+     "property content in all dependencies must be equal with each "
+     "other, and with the \"FOO\" property in this target.  If the "
+     "property is not set, then it is ignored.");
+
   cm->DefineProperty
     ("POST_INSTALL_SCRIPT", cmProperty::TARGET,
      "Deprecated install support.",
@@ -4511,6 +4522,14 @@ bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
   return tgt->GetPropertyAsBool(prop);
 }
 
+//----------------------------------------------------------------------------
+template<>
+const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
+                                          const char **)
+{
+  return tgt->GetProperty(prop);
+}
+
 //----------------------------------------------------------------------------
 template<typename PropertyType>
 bool consistentProperty(PropertyType lhs, PropertyType rhs);
@@ -4522,6 +4541,17 @@ bool consistentProperty(bool lhs, bool rhs)
   return lhs == rhs;
 }
 
+//----------------------------------------------------------------------------
+template<>
+bool consistentProperty(const char *lhs, const char *rhs)
+{
+  if (!lhs && !rhs)
+    return true;
+  if (!lhs || !rhs)
+    return false;
+  return strcmp(lhs, rhs) == 0;
+}
+
 //----------------------------------------------------------------------------
 template<typename PropertyType>
 PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
@@ -4667,6 +4697,17 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
                                                    0);
 }
 
+//----------------------------------------------------------------------------
+const char * cmTarget::GetLinkInterfaceDependentStringProperty(
+                                                      const std::string &p,
+                                                      const char *config)
+{
+  return checkInterfacePropertyCompatibility<const char *>(this,
+                                                           p,
+                                                           config,
+                                                           "empty", 0);
+}
+
 //----------------------------------------------------------------------------
 bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
                              const char *interfaceProperty,
@@ -4714,6 +4755,14 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
                                  config);
 }
 
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
+                                    const char *config)
+{
+  return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
+                                 config);
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
 {
@@ -5468,6 +5517,15 @@ bool getLinkInterfaceDependentProperty(cmTarget *tgt,
   return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
 }
 
+template<>
+const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
+                                                 const std::string prop,
+                                                 const char *config,
+                                                 const char **)
+{
+  return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+}
+
 //----------------------------------------------------------------------------
 template<typename PropertyType>
 void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
@@ -5536,6 +5594,13 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
       {
       return;
       }
+    checkPropertyConsistency<const char *>(this, li->Target,
+                                           "COMPATIBLE_INTERFACE_STRING",
+                                           emitted, config, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
     }
 }
 

+ 5 - 0
Source/cmTarget.h

@@ -501,12 +501,17 @@ public:
   bool IsNullImpliedByLinkLibraries(const std::string &p);
   bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
                                             const char *config);
+  bool IsLinkInterfaceDependentStringProperty(const std::string &p,
+                                              const char *config);
 
   void AddLinkDependentTargetsForProperties(
           const std::map<cmStdString, cmStdString> &map);
 
   bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
                                              const char *config);
+
+  const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
+                                                      const char *config);
 private:
   /**
    * A list of direct dependencies. Use in conjunction with DependencyMap.

+ 13 - 0
Tests/CompatibleInterface/CMakeLists.txt

@@ -14,21 +14,34 @@ set_property(TARGET iface1 APPEND PROPERTY
     BOOL_PROP3
     BOOL_PROP4
 )
+set_property(TARGET iface1 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_STRING
+    STRING_PROP1
+    STRING_PROP2
+    STRING_PROP3
+)
 
 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)
 
 add_executable(CompatibleInterface main.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)
 
 target_compile_definitions(CompatibleInterface
   PRIVATE
     $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
     $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
     $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
+    $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
+    $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
+    $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
 )
 
 

+ 12 - 0
Tests/CompatibleInterface/main.cpp

@@ -11,6 +11,18 @@
 #error Expected BOOL_PROP3
 #endif
 
+#ifndef STRING_PROP1
+#error Expected STRING_PROP1
+#endif
+
+#ifndef STRING_PROP2
+#error Expected STRING_PROP2
+#endif
+
+#ifndef STRING_PROP3
+#error Expected STRING_PROP3
+#endif
+
 #include "iface2.h"
 
 int main(int argc, char **argv)

+ 8 - 1
Tests/ExportImport/Export/CMakeLists.txt

@@ -181,7 +181,14 @@ set_property(TARGET testSharedLibRequired
   PROPERTY
     INTERFACE_CUSTOM_PROP ON
 )
-
+set_property(TARGET testSharedLibRequired
+  APPEND PROPERTY
+    COMPATIBLE_INTERFACE_STRING CUSTOM_STRING
+)
+set_property(TARGET testSharedLibRequired
+  PROPERTY
+    INTERFACE_CUSTOM_STRING testcontent
+)
 
 add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
 set_property(TARGET testSharedLibDepends APPEND PROPERTY

+ 2 - 0
Tests/ExportImport/Import/A/CMakeLists.txt

@@ -170,6 +170,7 @@ target_compile_definitions(deps_shared_iface
     testSharedLibDepends
     $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
     $<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
+    $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
 )
 
 if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
@@ -201,4 +202,5 @@ target_compile_definitions(deps_shared_iface2
   PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
   $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
   $<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
+  $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
 )

+ 4 - 0
Tests/ExportImport/Import/A/deps_shared_iface.cpp

@@ -16,6 +16,10 @@
 #error Expected CUSTOM_PROPERTY_IS_ON
 #endif
 
+#ifndef CUSTOM_STRING_IS_MATCH
+#error Expected CUSTOM_STRING_IS_MATCH
+#endif
+
 #ifdef TEST_SUBDIR_LIB
 #include "subdir.h"
 #endif

+ 1 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt

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

+ 5 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
+  COMPATIBLE_INTERFACE_STRING property.  This is not allowed.  Only
+  user-defined properties may appear listed in the
+  COMPATIBLE_INTERFACE_STRING property.

+ 11 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake

@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
+set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES foo_inc)
+set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES bar_inc)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
+target_link_libraries(user foo bar)

+ 1 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt

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

+ 3 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error: Property SOMEPROP on target "user" does
+not match the INTERFACE_SOMEPROP property requirement
+of dependency "foo".

+ 11 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake

@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP prop)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY SOMEPROP different)
+target_link_libraries(user foo bar)

+ 1 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt

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

+ 3 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_SOMEPROP property of "bar" does
+not agree with the value of SOMEPROP already determined
+for "user".

+ 10 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake

@@ -0,0 +1,10 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP foo)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP bar)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)

+ 1 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt

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

+ 4 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be empty because it was used to determine the link libraries
+already. The INTERFACE_SOMEPROP property on
+dependency "foo" is in conflict.

+ 9 - 0
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake

@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)

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

@@ -4,3 +4,7 @@ run_cmake(InterfaceBool-mismatch-depends)
 run_cmake(InterfaceBool-mismatch-depend-self)
 run_cmake(InterfaceBool-mismatched-use)
 run_cmake(InterfaceBool-builtin-prop)
+run_cmake(InterfaceString-mismatch-depends)
+run_cmake(InterfaceString-mismatch-depend-self)
+run_cmake(InterfaceString-mismatched-use)
+run_cmake(InterfaceString-builtin-prop)