Browse Source

Make INTERFACE determined properties readable in generator expressions.

The properties are evaluated as link-dependent interface properties when
evaluating the generator expressions.
Stephen Kelly 12 years ago
parent
commit
e98799105b
27 changed files with 218 additions and 1 deletions
  1. 13 0
      Source/cmGeneratorExpressionDAGChecker.cxx
  2. 3 0
      Source/cmGeneratorExpressionDAGChecker.h
  3. 21 0
      Source/cmGeneratorExpressionEvaluator.cxx
  4. 47 0
      Source/cmTarget.cxx
  5. 2 0
      Source/cmTarget.h
  6. 1 0
      Tests/CMakeLists.txt
  7. 28 0
      Tests/CompatibleInterface/CMakeLists.txt
  8. 1 0
      Tests/CompatibleInterface/empty.cpp
  9. 17 0
      Tests/CompatibleInterface/main.cpp
  10. 6 1
      Tests/ExportImport/Import/A/CMakeLists.txt
  11. 4 0
      Tests/ExportImport/Import/A/deps_shared_iface.cpp
  12. 1 0
      Tests/RunCMake/CMakeLists.txt
  13. 3 0
      Tests/RunCMake/CompatibleInterface/CMakeLists.txt
  14. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt
  15. 5 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt
  16. 11 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake
  17. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt
  18. 3 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt
  19. 11 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake
  20. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt
  21. 3 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt
  22. 10 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake
  23. 1 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt
  24. 4 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt
  25. 9 0
      Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake
  26. 6 0
      Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
  27. 5 0
      Tests/RunCMake/CompatibleInterface/main.cpp

+ 13 - 0
Source/cmGeneratorExpressionDAGChecker.cxx

@@ -106,3 +106,16 @@ cmGeneratorExpressionDAGChecker::checkGraph() const
     }
   return DAG;
 }
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
+{
+  const cmGeneratorExpressionDAGChecker *top = this;
+  const cmGeneratorExpressionDAGChecker *parent = this->Parent;
+  while (parent)
+    {
+    parent = parent->Parent;
+    top = parent;
+    }
+  return top->Property == "LINK_LIBRARIES";
+}

+ 3 - 0
Source/cmGeneratorExpressionDAGChecker.h

@@ -35,6 +35,9 @@ struct cmGeneratorExpressionDAGChecker
 
   void reportError(cmGeneratorExpressionContext *context,
                    const std::string &expr);
+
+  bool EvaluatingLinkLibraries();
+
 private:
   Result checkGraph() const;
 

+ 21 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -442,6 +442,27 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     const char *prop = target->GetProperty(propertyName.c_str());
     if (!prop)
       {
+      if (target->IsImported())
+        {
+        return std::string();
+        }
+      if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
+        {
+        return std::string();
+        }
+      if (propertyName == "POSITION_INDEPENDENT_CODE")
+        {
+        return target->GetLinkInterfaceDependentBoolProperty(
+                    "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
+        }
+      if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
+                                                       context->Config))
+        {
+        return target->GetLinkInterfaceDependentBoolProperty(
+                                                propertyName,
+                                                context->Config) ? "1" : "0";
+        }
+
       return std::string();
       }
 

+ 47 - 0
Source/cmTarget.cxx

@@ -4612,6 +4612,53 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
   return propContent;
 }
 
+//----------------------------------------------------------------------------
+bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
+                             const char *interfaceProperty,
+                             const char *config)
+{
+  cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
+
+  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+      deps.begin();
+      li != deps.end(); ++li)
+    {
+    if (!li->Target)
+      {
+      continue;
+      }
+    const char *prop = li->Target->GetProperty(interfaceProperty);
+    if (!prop)
+      {
+      continue;
+      }
+
+    std::vector<std::string> props;
+    cmSystemTools::ExpandListArgument(prop, props);
+
+    for(std::vector<std::string>::iterator pi = props.begin();
+        pi != props.end(); ++pi)
+      {
+      if (*pi == p)
+        {
+        return true;
+        }
+      }
+    }
+
+  return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
+                                           const char *config)
+{
+  return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
+                                 config);
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
 {

+ 2 - 0
Source/cmTarget.h

@@ -495,6 +495,8 @@ public:
   void GetLinkDependentTargetsForProperty(const std::string &p,
                                        std::set<std::string> &targets);
   bool IsNullImpliedByLinkLibraries(const std::string &p);
+  bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+                                            const char *config);
 
   void AddLinkDependentTargetsForProperties(
           const std::map<cmStdString, cmStdString> &map);

+ 1 - 0
Tests/CMakeLists.txt

@@ -216,6 +216,7 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(PolicyScope PolicyScope)
   ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
   ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
+  ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
   ADD_TEST_MACRO(CrossCompile CrossCompile)

+ 28 - 0
Tests/CompatibleInterface/CMakeLists.txt

@@ -0,0 +1,28 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(CompatibleInterface)
+
+add_library(iface1 empty.cpp)
+set_property(TARGET iface1 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_BOOL
+    BOOL_PROP1
+    BOOL_PROP2
+    BOOL_PROP3
+)
+
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
+
+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)
+
+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>
+)

+ 1 - 0
Tests/CompatibleInterface/empty.cpp

@@ -0,0 +1 @@
+// no content

+ 17 - 0
Tests/CompatibleInterface/main.cpp

@@ -0,0 +1,17 @@
+
+#ifndef BOOL_PROP1
+#error Expected BOOL_PROP1
+#endif
+
+#ifndef BOOL_PROP2
+#error Expected BOOL_PROP2
+#endif
+
+#ifndef BOOL_PROP3
+#error Expected BOOL_PROP3
+#endif
+
+int main(int argc, char **argv)
+{
+  return 0;
+}

+ 6 - 1
Tests/ExportImport/Import/A/CMakeLists.txt

@@ -165,7 +165,11 @@ target_compile_definitions(deps_iface PRIVATE testLibDepends)
 add_executable(deps_shared_iface deps_shared_iface.cpp)
 target_link_libraries(deps_shared_iface testSharedLibDepends)
 target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
-target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends)
+target_compile_definitions(deps_shared_iface
+  PRIVATE
+    testSharedLibDepends
+    $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
+)
 
 if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
   include(CheckCXXCompilerFlag)
@@ -194,4 +198,5 @@ target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
 target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
 target_compile_definitions(deps_shared_iface2
   PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
+  $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
 )

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

@@ -8,6 +8,10 @@
 #endif
 #endif
 
+#ifndef PIC_PROPERTY_IS_ON
+#error Expected PIC_PROPERTY_IS_ON
+#endif
+
 #ifdef TEST_SUBDIR_LIB
 #include "subdir.h"
 #endif

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -53,6 +53,7 @@ add_RunCMake_test(ObjectLibrary)
 if(NOT WIN32)
   add_RunCMake_test(PositionIndependentCode)
 endif()
+add_RunCMake_test(CompatibleInterface)
 
 add_RunCMake_test(build_command)
 add_RunCMake_test(find_package)

+ 3 - 0
Tests/RunCMake/CompatibleInterface/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)

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

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

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

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

+ 11 - 0
Tests/RunCMake/CompatibleInterface/InterfaceBool-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_BOOL INCLUDE_DIRECTORIES)
+set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
+set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES OFF)
+target_link_libraries(user foo bar)

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

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

+ 3 - 0
Tests/RunCMake/CompatibleInterface/InterfaceBool-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/InterfaceBool-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_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP ON)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY SOMEPROP OFF)
+target_link_libraries(user foo bar)

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

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

+ 3 - 0
Tests/RunCMake/CompatibleInterface/InterfaceBool-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/InterfaceBool-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_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP OFF)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)

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

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

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

@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be FALSE 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/InterfaceBool-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_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)

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

@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(InterfaceBool-mismatch-depends)
+run_cmake(InterfaceBool-mismatch-depend-self)
+run_cmake(InterfaceBool-mismatched-use)
+run_cmake(InterfaceBool-builtin-prop)

+ 5 - 0
Tests/RunCMake/CompatibleInterface/main.cpp

@@ -0,0 +1,5 @@
+
+int main(int argc, char **argv)
+{
+  return 0;
+}