Procházet zdrojové kódy

Handle genexes when evaluating INTERFACE_INCLUDE_DIRECTORIES errors.

Stephen Kelly před 12 roky
rodič
revize
70ae6dfd92

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -36,3 +36,4 @@ All Policies
    /policy/CMP0024
    /policy/CMP0025
    /policy/CMP0026
+   /policy/CMP0027

+ 25 - 0
Help/policy/CMP0027.rst

@@ -0,0 +1,25 @@
+CMP0027
+-------
+
+Conditionally linked imported targets with missing include directories.
+
+CMake 2.8.11 introduced introduced the concept of
+INTERFACE_INCLUDE_DIRECTORIES, and a check at cmake time that the
+entries in the INTERFACE_INCLUDE_DIRECTORIES of an IMPORTED target
+actually exist.  CMake 2.8.11 also introduced generator expression
+support in the target_link_libraries command.  However, if an imported
+target is linked as a result of a generator expression evaluation, the
+entries in the INTERFACE_INCLUDE_DIRECTORIES of that target were not
+checked for existence as they should be.
+
+The OLD behavior of this policy is to report a warning if an entry in
+the INTERFACE_INCLUDE_DIRECTORIES of a generator-expression
+conditionally linked IMPORTED target does not exist.
+
+The NEW behavior of this policy is to report an error if an entry in
+the INTERFACE_INCLUDE_DIRECTORIES of a generator-expression
+conditionally linked IMPORTED target does not exist.
+
+This policy was introduced in CMake version 3.0.0.  CMake version
+|release| warns when the policy is not set and uses OLD behavior.  Use
+the cmake_policy command to set it to OLD or NEW explicitly.

+ 5 - 0
Source/cmPolicies.cxx

@@ -236,6 +236,11 @@ cmPolicies::cmPolicies()
     CMP0026, "CMP0026",
     "Disallow use of the LOCATION target property.",
     3,0,0,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0027, "CMP0027",
+    "Conditionally linked imported targets with missing include directories.",
+    3,0,0,0, cmPolicies::WARN);
 }
 
 cmPolicies::~cmPolicies()

+ 2 - 0
Source/cmPolicies.h

@@ -77,6 +77,8 @@ public:
     CMP0024, ///< Disallow including export() result.
     CMP0025, ///< Compiler id for Apple Clang is now AppleClang
     CMP0026, ///< Disallow use of the LOCATION target property.
+    CMP0027, ///< Conditionally linked imported targets with missing include
+    /// directories.
 
     /** \brief Always the last entry.
      *

+ 44 - 7
Source/cmTarget.cxx

@@ -1911,19 +1911,56 @@ static void processIncludeDirectories(cmTarget *tgt,
         }
       }
     std::string usedIncludes;
+    cmListFileBacktrace lfbt;
     for(std::vector<std::string>::iterator
           li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
       {
-      cmTarget *dependentTarget =
-                              mf->FindTargetToUse((*it)->TargetName.c_str());
+      std::string targetName = (*it)->TargetName;
+      std::string evaluatedTargetName;
+      {
+      cmGeneratorExpression ge(lfbt);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                        ge.Parse(targetName);
+      evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0);
+      }
+
+      cmTarget *dependentTarget = mf->FindTargetToUse(targetName.c_str());
 
       const bool fromImported = dependentTarget
                              && dependentTarget->IsImported();
 
-      if (fromImported && !cmSystemTools::FileExists(li->c_str()))
+      cmTarget *evaluatedDependentTarget =
+        (targetName != evaluatedTargetName)
+          ? mf->FindTargetToUse(evaluatedTargetName.c_str())
+          : 0;
+
+      targetName = evaluatedTargetName;
+
+      const bool fromEvaluatedImported = evaluatedDependentTarget
+                             && evaluatedDependentTarget->IsImported();
+
+      if ((fromImported || fromEvaluatedImported)
+          && !cmSystemTools::FileExists(li->c_str()))
         {
         cmOStringStream e;
-        e << "Imported target \"" << (*it)->TargetName << "\" includes "
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        if (fromEvaluatedImported)
+          {
+          switch(mf->GetPolicyStatus(cmPolicies::CMP0027))
+            {
+            case cmPolicies::WARN:
+              e << (mf->GetPolicies()
+                    ->GetPolicyWarning(cmPolicies::CMP0027)) << "\n";
+            case cmPolicies::OLD:
+              messageType = cmake::AUTHOR_WARNING;
+              break;
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::NEW:
+              break;
+            }
+          }
+        e << "Imported target \"" << targetName << "\" includes "
              "non-existent path\n  \"" << *li << "\"\nin its "
              "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
              "* The path was deleted, renamed, or moved to another "
@@ -1932,7 +1969,7 @@ static void processIncludeDirectories(cmTarget *tgt,
              "successfully.\n"
              "* The installation package was faulty and references files it "
              "does not provide.\n";
-        tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+        tgt->GetMakefile()->IssueMessage(messageType, e.str().c_str());
         return;
         }
 
@@ -1941,9 +1978,9 @@ static void processIncludeDirectories(cmTarget *tgt,
         cmOStringStream e;
         bool noMessage = false;
         cmake::MessageType messageType = cmake::FATAL_ERROR;
-        if (!(*it)->TargetName.empty())
+        if (!targetName.empty())
           {
-          e << "Target \"" << (*it)->TargetName << "\" contains relative "
+          e << "Target \"" << targetName << "\" contains relative "
             "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
             "  \"" << *li << "\"";
           }

+ 1 - 0
Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt

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

+ 13 - 0
Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt

@@ -0,0 +1,13 @@
+CMake Error in CMakeLists.txt:
+  Imported target "testTarget" includes non-existent path
+
+    "/does/not/exist"
+
+  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:
+
+  \* The path was deleted, renamed, or moved to another location.
+
+  \* An install or uninstall procedure did not complete successfully.
+
+  \* The installation package was faulty and references files it does not
+  provide.

+ 10 - 0
Tests/RunCMake/CMP0027/CMP0027-NEW.cmake

@@ -0,0 +1,10 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0027 NEW)
+
+add_library(testTarget UNKNOWN IMPORTED)
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget PRIVATE $<1:testTarget>)

+ 1 - 0
Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt

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

+ 13 - 0
Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt

@@ -0,0 +1,13 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Imported target "testTarget" includes non-existent path
+
+    "/does/not/exist"
+
+  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:
+
+  \* The path was deleted, renamed, or moved to another location.
+
+  \* An install or uninstall procedure did not complete successfully.
+
+  \* The installation package was faulty and references files it does not
+  provide.

+ 10 - 0
Tests/RunCMake/CMP0027/CMP0027-OLD.cmake

@@ -0,0 +1,10 @@
+
+enable_language(CXX)
+
+cmake_policy(SET CMP0027 OLD)
+
+add_library(testTarget UNKNOWN IMPORTED)
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget PRIVATE $<1:testTarget>)

+ 1 - 0
Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt

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

+ 18 - 0
Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt

@@ -0,0 +1,18 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0027 is not set: Conditionally linked imported targets with
+  missing include directories.  Run "cmake --help-policy CMP0027" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  Imported target "testTarget" includes non-existent path
+
+    "/does/not/exist"
+
+  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:
+
+  \* The path was deleted, renamed, or moved to another location.
+
+  \* An install or uninstall procedure did not complete successfully.
+
+  \* The installation package was faulty and references files it does not
+  provide.

+ 8 - 0
Tests/RunCMake/CMP0027/CMP0027-WARN.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(testTarget UNKNOWN IMPORTED)
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget PRIVATE $<1:testTarget>)

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

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)

+ 5 - 0
Tests/RunCMake/CMP0027/RunCMakeTest.cmake

@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0027-NEW)
+run_cmake(CMP0027-OLD)
+run_cmake(CMP0027-WARN)

+ 0 - 0
Tests/RunCMake/CMP0027/empty.cpp


+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -54,6 +54,7 @@ endif()
 add_RunCMake_test(CMP0019)
 add_RunCMake_test(CMP0022)
 add_RunCMake_test(CMP0026)
+add_RunCMake_test(CMP0027)
 add_RunCMake_test(CTest)
 if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
   add_RunCMake_test(CompilerChange)