Просмотр исходного кода

Merge topic 'link_deduplication_imported_targets'

502610733f Ensure imported targets in sibling dirs are deduplicated

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !9821
Brad King 1 год назад
Родитель
Сommit
fbb9b19eec

+ 18 - 1
Source/cmComputeLinkDepends.cxx

@@ -33,6 +33,7 @@
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmValue.h"
 #include "cmake.h"
@@ -540,7 +541,22 @@ private:
   {
     for (auto index : libEntries) {
       LinkEntry const& entry = this->Entries[index];
-      if (this->IncludeEntry(entry) || this->Emitted.insert(index).second) {
+      if (this->IncludeEntry(entry)) {
+        this->FinalEntries.emplace_back(entry);
+        continue;
+      }
+      if (entry.Target && entry.Target->IsImported()) {
+        // Different imported targets can point to the same library so check
+        // also library paths
+        if (this->Emitted.insert(index).second &&
+            this->ImportedEmitted
+              .insert(cmSystemTools::GetRealPath(entry.Item.Value))
+              .second) {
+          this->FinalEntries.emplace_back(entry);
+        }
+        continue;
+      }
+      if (this->Emitted.insert(index).second) {
         this->FinalEntries.emplace_back(entry);
       }
     }
@@ -553,6 +569,7 @@ private:
   EntryVector& Entries;
   EntryVector& FinalEntries;
   std::set<size_t> Emitted;
+  std::set<std::string> ImportedEmitted;
   const std::map<size_t, std::vector<size_t>>* Groups = nullptr;
 };
 }

+ 21 - 0
Tests/RunCMake/CMP0156/CMP0156-Common-Imported.cmake

@@ -0,0 +1,21 @@
+
+enable_language(C)
+
+add_library(lib1 STATIC lib1.c)
+set_property(TARGET lib1 PROPERTY ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>")
+
+# This function simulates a find_package call for the third-party lib
+# by making an imported target with non-global scope.
+function(find_package_lib1)
+  add_library(lib1::lib1 STATIC IMPORTED)
+
+  set_target_properties(lib1::lib1 PROPERTIES
+    IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/Release/${CMAKE_STATIC_LIBRARY_PREFIX}lib1${CMAKE_STATIC_LIBRARY_SUFFIX}"
+  )
+
+  add_dependencies(lib1::lib1 lib1)
+endfunction()
+
+# ------------------------------------------------------------------------------
+add_subdirectory(subdir1)
+add_subdirectory(subdir2)

+ 5 - 0
Tests/RunCMake/CMP0156/CMP0156-NEW-AppleClang-Imported.cmake

@@ -0,0 +1,5 @@
+
+cmake_policy(SET CMP0156 NEW)
+set(APPLE_TEST TRUE)
+
+include (CMP0156-Common-Imported.cmake)

+ 4 - 0
Tests/RunCMake/CMP0156/CMP0156-NEW-Imported.cmake

@@ -0,0 +1,4 @@
+
+cmake_policy(SET CMP0156 NEW)
+
+include (CMP0156-Common-Imported.cmake)

+ 14 - 1
Tests/RunCMake/CMP0156/RunCMakeTest.cmake

@@ -3,10 +3,14 @@ include(RunCMake)
 # CMP0156 control how libraries are specified for the link step
 # a sensible configuration is how circular dependency is handled
 
+if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(OPTIONS -DCMAKE_BUILD_TYPE=Release)
+endif()
+
 macro(run_cmake_and_build test)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   set(RunCMake_TEST_OUTPUT_MERGE TRUE)
-  run_cmake(${test})
+  run_cmake_with_options(${test} ${OPTIONS})
   set(RunCMake_TEST_NO_CLEAN TRUE)
   run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release)
   unset(RunCMake_TEST_NO_CLEAN)
@@ -24,3 +28,12 @@ if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
   run_cmake_and_build(CMP0156-OLD-AppleClang)
   run_cmake_and_build(CMP0156-NEW-AppleClang)
 endif()
+
+
+run_cmake_and_build(CMP0156-NEW-Imported)
+
+if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
+    AND CMAKE_C_COMPILER_VERSION GREATER_EQUAL "15.0")
+  # special case for Apple: with CMP0156=OLD, linker will warning on duplicate libraries
+  run_cmake_and_build(CMP0156-NEW-AppleClang-Imported)
+endif()

+ 5 - 0
Tests/RunCMake/CMP0156/subdir1/CMakeLists.txt

@@ -0,0 +1,5 @@
+
+find_package_lib1()
+
+add_library(lib2 STATIC ../lib2.c)
+target_link_libraries(lib2 PUBLIC lib1::lib1)

+ 14 - 0
Tests/RunCMake/CMP0156/subdir2/CMakeLists.txt

@@ -0,0 +1,14 @@
+
+find_package_lib1()
+
+# -----------------------------------
+# This target depends on the third-party lib1 both
+# directly and transitively.
+add_executable(main ../main.c)
+target_link_libraries(main PRIVATE lib1::lib1 lib2)
+
+if (APPLE_TEST)
+  target_link_options(main PRIVATE "LINKER:-fatal_warnings")
+else()
+  target_link_options(main PRIVATE "$<$<AND:$<NOT:$<TARGET_POLICY:CMP0156>>,$<C_COMPILER_ID:AppleClang>,$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,15.0>>:LINKER:-no_warn_duplicate_libraries>")
+endif()