Browse Source

cmTarget: Raise error if imported target location is not set

Previously we would synthesize <TARGET_NAME>-NOTFOUND as the location. This
would then end up on the link line and cause build failures.
Policy CMP0110 is added to control this behaviour.

Fixes #19080, #19943.
Raul Tambre 5 years ago
parent
commit
359c500a24
26 changed files with 143 additions and 12 deletions
  1. 1 0
      Help/manual/cmake-policies.7.rst
  2. 20 0
      Help/policy/CMP0111.rst
  3. 5 0
      Help/release/dev/imported-target-location-required.rst
  4. 5 1
      Source/cmPolicies.h
  5. 31 0
      Source/cmTarget.cxx
  6. 1 0
      Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake
  7. 9 0
      Tests/RunCMake/CMP0111/CMP0111-Common.cmake
  8. 1 0
      Tests/RunCMake/CMP0111/CMP0111-NEW-result.txt
  9. 7 0
      Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt
  10. 2 0
      Tests/RunCMake/CMP0111/CMP0111-NEW.cmake
  11. 2 0
      Tests/RunCMake/CMP0111/CMP0111-OLD.cmake
  12. 26 0
      Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
  13. 1 0
      Tests/RunCMake/CMP0111/CMP0111-WARN.cmake
  14. 3 0
      Tests/RunCMake/CMP0111/CMakeLists.txt
  15. 5 0
      Tests/RunCMake/CMP0111/RunCMakeTest.cmake
  16. 3 0
      Tests/RunCMake/CMP0111/main.cpp
  17. 1 0
      Tests/RunCMake/CMakeLists.txt
  18. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
  19. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
  20. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
  21. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
  22. 2 2
      Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
  23. 6 0
      Tests/RunCMake/FileAPI/imported/CMakeLists.txt
  24. 1 0
      Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
  25. 2 1
      Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake
  26. 1 0
      Tests/RunCMake/target_link_libraries/UNKNOWN-IMPORTED-GLOBAL.cmake

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

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.19
 .. toctree::
    :maxdepth: 1
 
+   CMP0111: An imported target with a missing location fails during generation. </policy/CMP0111>
    CMP0110: add_test() supports arbitrary characters in test names. </policy/CMP0110>
    CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
 

+ 20 - 0
Help/policy/CMP0111.rst

@@ -0,0 +1,20 @@
+CMP0111
+-------
+
+.. versionadded:: 3.19
+
+An imported target with a missing location fails during generation.
+
+Prior to this the location would be generated as ``<TARGET_NAME>-NOTFOUND``,
+which would result in build failures.
+
+The ``OLD`` behavior of this policy is to generate the location of an imported
+unknown, static or shared library target as ``<TARGET_NAME>-NOTFOUND`` if not
+set.
+The ``NEW`` behavior is to raise an error.
+
+This policy was introduced in CMake version 3.19.  CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt

+ 5 - 0
Help/release/dev/imported-target-location-required.rst

@@ -0,0 +1,5 @@
+imported-target-location-required
+---------------------------------
+
+* An imported target with a missing location now fails during generation if the
+  location is used.  See policy :policy:`CMP0111`.

+ 5 - 1
Source/cmPolicies.h

@@ -326,7 +326,11 @@ class cmMakefile;
          19, 0, cmPolicies::WARN)                                             \
   SELECT(POLICY, CMP0110,                                                     \
          "add_test() supports arbitrary characters in test names.", 3, 19, 0, \
-         cmPolicies::WARN)
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0111,                                                     \
+         "An imported target with a missing location fails during "           \
+         "generation.",                                                       \
+         3, 19, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \

+ 31 - 0
Source/cmTarget.cxx

@@ -2039,6 +2039,37 @@ std::string cmTarget::ImportedGetFullPath(
   }
 
   if (result.empty()) {
+    auto message = [&]() -> std::string {
+      std::string unset;
+      std::string configuration;
+
+      if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
+        unset = "IMPORTED_LOCATION";
+      } else if (artifact == cmStateEnums::ImportLibraryArtifact) {
+        unset = "IMPORTED_IMPLIB";
+      }
+
+      if (!config.empty()) {
+        configuration = cmStrCat(" configuration \"", config, "\"");
+      }
+
+      return cmStrCat(unset, " not set for imported target \"",
+                      this->GetName(), "\"", configuration, ".");
+    };
+
+    switch (this->GetPolicyStatus(cmPolicies::CMP0111)) {
+      case cmPolicies::WARN:
+        impl->Makefile->IssueMessage(
+          MessageType::AUTHOR_WARNING,
+          cmPolicies::GetPolicyWarning(cmPolicies::CMP0111) + "\n" +
+            message());
+        CM_FALLTHROUGH;
+      case cmPolicies::OLD:
+        break;
+      default:
+        impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, message());
+    }
+
     result = cmStrCat(this->GetName(), "-NOTFOUND");
   }
   return result;

+ 1 - 0
Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake

@@ -1,6 +1,7 @@
 
 enable_language(CXX)
 
+cmake_policy(SET CMP0111 OLD)
 add_library(someimportedlib SHARED IMPORTED)
 
 get_target_property(_loc someimportedlib LOCATION)

+ 9 - 0
Tests/RunCMake/CMP0111/CMP0111-Common.cmake

@@ -0,0 +1,9 @@
+# Prevent duplicate errors on some platforms.
+set(CMAKE_IMPORT_LIBRARY_SUFFIX "placeholder")
+
+add_library(unknown_lib UNKNOWN IMPORTED)
+add_library(static_lib STATIC IMPORTED)
+add_library(shared_lib SHARED IMPORTED)
+
+add_executable(executable main.cpp)
+target_link_libraries(executable unknown_lib static_lib shared_lib)

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

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

+ 7 - 0
Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt

@@ -0,0 +1,7 @@
+CMake Error in CMakeLists.txt:
+  IMPORTED_LOCATION not set for imported target "static_lib"( configuration
+  ".+")?.
++
+CMake Error in CMakeLists.txt:
+  IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
+  ".+")?.

+ 2 - 0
Tests/RunCMake/CMP0111/CMP0111-NEW.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0111 NEW)
+include(CMP0111-Common.cmake)

+ 2 - 0
Tests/RunCMake/CMP0111/CMP0111-OLD.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0111 OLD)
+include(CMP0111-Common.cmake)

+ 26 - 0
Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt

@@ -0,0 +1,26 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0111 is not set: An imported target with a missing location fails
+  during generation.  Run "cmake --help-policy CMP0111" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  IMPORTED_LOCATION not set for imported target "unknown_lib"( configuration
+  ".+")?.
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0111 is not set: An imported target with a missing location fails
+  during generation.  Run "cmake --help-policy CMP0111" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  IMPORTED_LOCATION not set for imported target "static_lib"( configuration
+  ".+")?.
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0111 is not set: An imported target with a missing location fails
+  during generation.  Run "cmake --help-policy CMP0111" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
+  ".+")?.
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 1 - 0
Tests/RunCMake/CMP0111/CMP0111-WARN.cmake

@@ -0,0 +1 @@
+include(CMP0111-Common.cmake)

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

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

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

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

+ 3 - 0
Tests/RunCMake/CMP0111/main.cpp

@@ -0,0 +1,3 @@
+int main()
+{
+}

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -124,6 +124,7 @@ if(CMake_TEST_CUDA)
     PROPERTY LABELS "CUDA")
 endif()
 add_RunCMake_test(CMP0106)
+add_RunCMake_test(CMP0111)
 
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json

@@ -14,7 +14,7 @@
             "backtrace": [
                 {
                     "file": "^imported/CMakeLists\\.txt$",
-                    "line": 5,
+                    "line": 6,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -49,7 +49,7 @@
     "backtrace": [
         {
             "file": "^imported/CMakeLists\\.txt$",
-            "line": 5,
+            "line": 6,
             "command": "add_executable",
             "hasParent": true
         },

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json

@@ -14,7 +14,7 @@
             "backtrace": [
                 {
                     "file": "^imported/CMakeLists\\.txt$",
-                    "line": 23,
+                    "line": 29,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -49,7 +49,7 @@
     "backtrace": [
         {
             "file": "^imported/CMakeLists\\.txt$",
-            "line": 23,
+            "line": 29,
             "command": "add_executable",
             "hasParent": true
         },

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json

@@ -14,7 +14,7 @@
             "backtrace": [
                 {
                     "file": "^imported/CMakeLists\\.txt$",
-                    "line": 18,
+                    "line": 24,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -49,7 +49,7 @@
     "backtrace": [
         {
             "file": "^imported/CMakeLists\\.txt$",
-            "line": 18,
+            "line": 24,
             "command": "add_executable",
             "hasParent": true
         },

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json

@@ -14,7 +14,7 @@
             "backtrace": [
                 {
                     "file": "^imported/CMakeLists\\.txt$",
-                    "line": 9,
+                    "line": 14,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -49,7 +49,7 @@
     "backtrace": [
         {
             "file": "^imported/CMakeLists\\.txt$",
-            "line": 9,
+            "line": 14,
             "command": "add_executable",
             "hasParent": true
         },

+ 2 - 2
Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json

@@ -14,7 +14,7 @@
             "backtrace": [
                 {
                     "file": "^imported/CMakeLists\\.txt$",
-                    "line": 13,
+                    "line": 19,
                     "command": "add_executable",
                     "hasParent": true
                 },
@@ -49,7 +49,7 @@
     "backtrace": [
         {
             "file": "^imported/CMakeLists\\.txt$",
-            "line": 13,
+            "line": 19,
             "command": "add_executable",
             "hasParent": true
         },

+ 6 - 0
Tests/RunCMake/FileAPI/imported/CMakeLists.txt

@@ -1,15 +1,21 @@
 project(Imported)
 
 add_library(imported_lib UNKNOWN IMPORTED)
+set_target_properties(imported_lib PROPERTIES IMPORTED_LOCATION "imported_unk${CMAKE_STATIC_LIBRARY_SUFFIX}")
 add_executable(imported_exe IMPORTED)
 add_executable(link_imported_exe ../empty.c)
 target_link_libraries(link_imported_exe PRIVATE imported_lib)
 
 add_library(imported_shared_lib SHARED IMPORTED)
+set_target_properties(imported_shared_lib PROPERTIES
+  IMPORTED_LOCATION "imported_shared${CMAKE_SHARED_LIBRARY_SUFFIX}"
+  IMPORTED_IMPLIB "imported_shared${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+)
 add_executable(link_imported_shared_exe ../empty.c)
 target_link_libraries(link_imported_shared_exe PRIVATE imported_shared_lib)
 
 add_library(imported_static_lib STATIC IMPORTED)
+set_target_properties(imported_static_lib PROPERTIES IMPORTED_LOCATION "imported_static${CMAKE_STATIC_LIBRARY_SUFFIX}")
 add_executable(link_imported_static_exe ../empty.c)
 target_link_libraries(link_imported_static_exe PRIVATE imported_static_lib)
 

+ 1 - 0
Tests/RunCMake/Graphviz/GraphvizTestProject.cmake

@@ -60,6 +60,7 @@ target_link_libraries(ConsoleApplication CoreLibrary)
 
 # No one will ever notice...
 add_library(CryptoCurrencyMiningLibrary UNKNOWN IMPORTED)
+set_target_properties(CryptoCurrencyMiningLibrary PROPERTIES IMPORTED_LOCATION "cryptomining${CMAKE_STATIC_LIBRARY_SUFFIX}")
 target_link_libraries(ConsoleApplication CryptoCurrencyMiningLibrary)
 
 add_custom_target(GenerateManPage COMMAND ${CMAKE_COMMAND} --version)

+ 2 - 1
Tests/RunCMake/target_link_libraries/SharedDepNotTarget.cmake

@@ -3,7 +3,8 @@ set(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
 set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
 add_library(imported SHARED IMPORTED)
 set_target_properties(imported PROPERTIES
-  IMPORTED_LOCATION "imported"
+  IMPORTED_LOCATION "imported${CMAKE_SHARED_LIBRARY_SUFFIX}"
+  IMPORTED_IMPLIB "imported${CMAKE_IMPORT_LIBRARY_SUFFIX}"
   IMPORTED_LINK_DEPENDENT_LIBRARIES "/path/to/libSharedDep.so"
   )
 add_executable(empty empty.c)

+ 1 - 0
Tests/RunCMake/target_link_libraries/UNKNOWN-IMPORTED-GLOBAL.cmake

@@ -1,4 +1,5 @@
 enable_language(C)
 add_library(UnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+set_target_properties(UnknownImportedGlobal PROPERTIES IMPORTED_LOCATION "unknown.${CMAKE_SHARED_LIBRARY_SUFFIX}")
 add_library(mylib empty.c)
 target_link_libraries(mylib UnknownImportedGlobal)