Browse Source

Merge topic 'imported-implib-only'

7351d590ee cmTarget: Add a way to represent imported shared library stubs
83574a4772 GeneratorExpression: Expand testing of imported location resolution
b75ff51947 Testing: Map RelWithDebInfo config in GeneratorExpression test

Acked-by: Kitware Robot <[email protected]>
Acked-by: Jason Juang <[email protected]>
Merge-request: !8582
Brad King 2 years ago
parent
commit
b0054dd65c

+ 6 - 0
Help/prop_tgt/IMPORTED_IMPLIB.rst

@@ -11,6 +11,12 @@ This property may be set:
 * On macOS, to an import file (e.g. ``.tbd``) created for shared libraries (see
   the :prop_tgt:`ENABLE_EXPORTS` target property). For frameworks this is the
   location of the ``.tbd`` file symlink just inside the framework folder.
+* .. versionadded:: 3.28
+    On non-DLL platforms, to the location of a shared library.
+    When set without also specifying an :prop_tgt:`IMPORTED_LOCATION`,
+    the library is considered to be a stub, and its location will not
+    be added as a runtime search path to dependents that link it.
+
 
 The ``IMPORTED_IMPLIB`` target property may be overridden for a
 given configuration ``<CONFIG>`` by the configuration-specific

+ 7 - 0
Help/release/dev/imported-implib-only.rst

@@ -0,0 +1,7 @@
+imported-implib-only
+--------------------
+
+* On imported shared libraries, the :prop_tgt:`IMPORTED_IMPLIB` target
+  property may now be used without :prop_tgt:`IMPORTED_LOCATION`.
+  This can be used to represent a stub library whose location should not
+  be added as a runtime search path to dependents that link it.

+ 11 - 7
Source/cmComputeLinkInformation.cxx

@@ -2241,16 +2241,20 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo(
   if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
     return;
   }
+  auto const* info = target->GetImportInfo(this->Config);
 
   // Try to get the soname of the library.  Only files with this name
   // could possibly conflict.
-  std::string soName = target->GetSOName(this->Config);
-  const char* soname = soName.empty() ? nullptr : soName.c_str();
-
-  // Include this library in the runtime path ordering.
-  this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
-  if (this->LinkWithRuntimePath) {
-    this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
+  const char* soname =
+    (!info || info->SOName.empty()) ? nullptr : info->SOName.c_str();
+
+  // If this shared library has a known runtime artifact (IMPORTED_LOCATION),
+  // include its location in the runtime path ordering.
+  if (!info || !info->Location.empty()) {
+    this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
+    if (this->LinkWithRuntimePath) {
+      this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
+    }
   }
 }
 

+ 1 - 0
Source/cmGeneratorTarget.h

@@ -1076,6 +1076,7 @@ private:
     std::string SharedDeps;
   };
 
+  friend cmComputeLinkInformation;
   using ImportInfoMapType = std::map<std::string, ImportInfo>;
   mutable ImportInfoMapType ImportInfoMap;
   void ComputeImportInfo(std::string const& desired_config,

+ 20 - 6
Source/cmTarget.cxx

@@ -2779,6 +2779,8 @@ std::string cmTarget::ImportedGetFullPath(
       case cmStateEnums::RuntimeBinaryArtifact:
         if (loc) {
           result = *loc;
+        } else if (imp) {
+          result = *imp;
         } else {
           std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
           if (cmValue config_location = this->GetProperty(impProp)) {
@@ -2787,6 +2789,16 @@ std::string cmTarget::ImportedGetFullPath(
                        this->GetProperty("IMPORTED_LOCATION")) {
             result = *location;
           }
+          if (result.empty() &&
+              (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+               this->IsExecutableWithExports())) {
+            impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
+            if (cmValue config_implib = this->GetProperty(impProp)) {
+              result = *config_implib;
+            } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) {
+              result = *implib;
+            }
+          }
         }
         break;
 
@@ -2812,7 +2824,10 @@ std::string cmTarget::ImportedGetFullPath(
         std::string unset;
         std::string configuration;
 
-        if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
+        if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
+            artifact == cmStateEnums::RuntimeBinaryArtifact) {
+          unset = "IMPORTED_LOCATION or IMPORTED_IMPLIB";
+        } else if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
           unset = "IMPORTED_LOCATION";
         } else if (artifact == cmStateEnums::ImportLibraryArtifact) {
           unset = "IMPORTED_IMPLIB";
@@ -2985,11 +3000,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
   }
 
   // If we needed to find one of the mapped configurations but did not
-  // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
-  // library or an executable with exports.
-  bool allowImp = (this->IsDLLPlatform() &&
-                   (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
-                    this->IsExecutableWithExports())) ||
+  // There may be only IMPORTED_IMPLIB for a shared library or an executable
+  // with exports.
+  bool allowImp = (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+                   this->IsExecutableWithExports()) ||
     (this->IsAIX() && this->IsExecutableWithExports()) ||
     (this->GetMakefile()->PlatformSupportsAppleTextStubs() &&
      this->IsSharedLibraryWithExports());

+ 1 - 0
Tests/Cuda/CMakeLists.txt

@@ -13,6 +13,7 @@ add_cuda_test_macro(Cuda.MixedStandardLevels4 MixedStandardLevels4)
 add_cuda_test_macro(Cuda.MixedStandardLevels5 MixedStandardLevels5)
 add_cuda_test_macro(Cuda.NotEnabled CudaNotEnabled)
 add_cuda_test_macro(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly)
+add_cuda_test_macro(Cuda.StubRPATH StubRPATH)
 add_cuda_test_macro(Cuda.Toolkit Toolkit)
 add_cuda_test_macro(Cuda.IncludePathNoToolkit IncludePathNoToolkit)
 add_cuda_test_macro(Cuda.SharedRuntimePlusToolkit SharedRuntimePlusToolkit)

+ 21 - 0
Tests/Cuda/StubRPATH/CMakeLists.txt

@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.18)
+project(StubRPATH CXX)
+
+#Verify that linking to a stub library doesn't cause an `-rpath` entry
+
+# Needed for `CUDAToolkit_LIBRARY_SEARCH_DIRS`
+find_package(CUDAToolkit REQUIRED)
+
+find_library(CUDA_DRIVER_STUB_LIBRARY
+  NAMES cuda
+  HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
+        ENV CUDA_PATH
+  PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
+)
+add_library(imported_stub IMPORTED SHARED)
+set_target_properties(imported_stub PROPERTIES IMPORTED_IMPLIB "${CUDA_DRIVER_STUB_LIBRARY}")
+set_target_properties(imported_stub PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CUDAToolkit_INCLUDE_DIRS}")
+
+set(CMAKE_CXX_STANDARD 11)
+add_executable(StubRPATH main.cxx)
+target_link_libraries(StubRPATH PRIVATE imported_stub)

+ 17 - 0
Tests/Cuda/StubRPATH/main.cxx

@@ -0,0 +1,17 @@
+
+#include <iostream>
+
+#include <cuda.h>
+
+int main(int argc, char** argv)
+{
+  int nDevices = 0;
+  cuInit(0);
+  auto err = cuDeviceGetCount(&nDevices);
+  if (err != CUDA_SUCCESS) {
+    std::cerr << "Failed to retrieve the number of CUDA enabled devices "
+              << err << std::endl;
+    return 1;
+  }
+  return 0;
+}

+ 20 - 1
Tests/GeneratorExpression/CMakeLists.txt

@@ -214,6 +214,22 @@ set_property(TARGET importedFallback2 PROPERTY IMPORTED_IMPLIB_SPECIAL special_i
 set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_NOCONFIG SPECIAL "")
 set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_DEBUG SPECIAL "")
 set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_RELEASE SPECIAL "")
+set_property(TARGET importedFallback2 PROPERTY MAP_IMPORTED_CONFIG_RELWITHDEBINFO SPECIAL "")
+
+add_library(importedFallback3 SHARED IMPORTED)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_LOCATION_DEBUG debug_loc)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_LOCATION_RELEASE release_loc)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_LOCATION fallback_loc)
+set_property(TARGET importedFallback3 PROPERTY IMPORTED_IMPLIB imp_loc)
+set_property(TARGET importedFallback3 PROPERTY MAP_IMPORTED_CONFIG_DEBUG "" DEBUG)
+set_property(TARGET importedFallback3 PROPERTY MAP_IMPORTED_CONFIG_RELEASE "")
+
+add_library(importedFallback4 SHARED IMPORTED)
+set_property(TARGET importedFallback4 PROPERTY IMPORTED_LOCATION fallback_loc)
+set_property(TARGET importedFallback4 PROPERTY IMPORTED_IMPLIB imp_loc)
+
+add_library(importedFallback5 SHARED IMPORTED)
+set_property(TARGET importedFallback5 PROPERTY IMPORTED_IMPLIB imp_loc)
 
 add_library(importedFallback_genex STATIC IMPORTED)
 set_property(TARGET importedFallback_genex PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
@@ -232,7 +248,10 @@ add_custom_target(check-part3 ALL
     -Dconfig=$<CONFIGURATION>
     -Dtest_imported_includes=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
     -Dtest_imported_fallback=$<STREQUAL:$<TARGET_FILE_NAME:importedFallback>,fallback_loc>
-    -Dtest_imported_fallback2=$<IF:$<OR:$<PLATFORM_ID:Windows,CYGWIN,MSYS>,$<AND:$<PLATFORM_ID:Darwin>,$<BOOL:${CMAKE_TAPI}>>>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback2>,special_imp>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback2>,fallback_loc>>
+    -Dtest_imported_fallback2=$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback2>,special_imp>
+    -Dtest_imported_fallback3=$<IF:$<PLATFORM_ID:Windows,CYGWIN,MSYS>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback3>,imp_loc>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback3>,fallback_loc>>
+    -Dtest_imported_fallback4=$<IF:$<PLATFORM_ID:Windows,CYGWIN,MSYS>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback4>,imp_loc>,$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback4>,fallback_loc>>
+    -Dtest_imported_fallback5=$<STREQUAL:$<TARGET_LINKER_FILE_NAME:importedFallback5>,imp_loc>
     -Dtest_imported_fallback_genex=$<STREQUAL:$<TARGET_PROPERTY:importedFallback_genex,INTERFACE_COMPILE_DEFINITIONS>,FOOBAR=1>
     -Dtest_alias_file_exe=$<STREQUAL:$<TARGET_FILE:Alias::SomeExe>,$<TARGET_FILE:someexe>>
     -Dtest_alias_file_lib=$<STREQUAL:$<TARGET_FILE:Alias::SomeLib>,$<TARGET_FILE:empty1>>

+ 3 - 0
Tests/GeneratorExpression/check-part3.cmake

@@ -20,6 +20,9 @@ endif()
 
 check(test_imported_fallback "1")
 check(test_imported_fallback2 "1")
+check(test_imported_fallback3 "1")
+check(test_imported_fallback4 "1")
+check(test_imported_fallback5 "1")
 check(test_imported_fallback_genex "1")
 
 check(test_alias_file_exe "1")

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

@@ -1,6 +1,3 @@
-# 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)

+ 4 - 2
Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt

@@ -1,4 +1,6 @@
 ^(CMake Error in CMakeLists.txt:
-  IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
+  IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static)_lib"( configuration
   "[^"]+")?.
-+)+CMake Generate step failed.  Build files cannot be regenerated correctly.$
+)+
+.*(IMPORTED_LOCATION or )?IMPORTED_IMPLIB not set for imported target.*"shared_lib".*
+CMake Generate step failed.  Build files cannot be regenerated correctly.$

+ 3 - 2
Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt

@@ -4,7 +4,7 @@
   details.  Use the cmake_policy command to set the policy and suppress this
   warning.
 
-  IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
+  IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static)_lib"( configuration
   "[^"]+")?.
 This warning is for project developers.  Use -Wno-dev to suppress it.
 +)+CMake Warning \(dev\) in CMakeLists.txt:
@@ -13,6 +13,7 @@ This warning is for project developers.  Use -Wno-dev to suppress it.
   details.  Use the cmake_policy command to set the policy and suppress this
   warning.
 
-  IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static|shared)_lib"( configuration
+  IMPORTED_(LOCATION|IMPLIB) not set for imported target "(unknown|static)_lib"( configuration
   "[^"]+")?.
+.*(IMPORTED_LOCATION or )?IMPORTED_IMPLIB not set for imported target.*"shared_lib".*
 This warning is for project developers.  Use -Wno-dev to suppress it.$

+ 7 - 1
Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake

@@ -14,8 +14,14 @@ set_property(TARGET import-local PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMA
 set_property(TARGET import-local PROPERTY IMPORTED_IMPLIB "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_IMPORT_LIBRARY_SUFFIX}")
 add_library(alias::local ALIAS import-local)
 
+if(NOT DEFINED CMAKE_IMPORT_LIBRARY_SUFFIX)
+  add_library(import-local-stub SHARED IMPORTED)
+  set_property(TARGET import-local-stub PROPERTY IMPORTED_IMPLIB "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_SHARED_LIBRARY_SUFFIX}")
+  add_library(alias::local-stub ALIAS import-local-stub)
+endif()
+
 add_library (lib-local SHARED lib.c)
-target_link_libraries (lib-local PRIVATE alias::local)
+target_link_libraries (lib-local PRIVATE alias::local $<TARGET_NAME_IF_EXISTS:alias::local-stub>)
 
 add_executable (main-local main.c)
 target_link_libraries (main-local PRIVATE alias::local)

+ 2 - 0
Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake

@@ -0,0 +1,2 @@
+add_library(SharedStubImportedGlobal SHARED IMPORTED GLOBAL)
+set_target_properties(SharedStubImportedGlobal PROPERTIES IMPORTED_IMPLIB z)

+ 1 - 0
Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake

@@ -23,6 +23,7 @@ run_cmake(CMP0079-link-NEW-bogus)
 run_cmake(CMP0108-OLD-self-link)
 run_cmake(CMP0108-NEW-self-link)
 run_cmake(ImportedTarget)
+run_cmake(ImportedTargetStub)
 run_cmake(ImportedTargetFailure)
 run_cmake(MixedSignature)
 run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)