summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Maynard <rmaynard@nvidia.com>2023-07-17 21:44:26 (GMT)
committerBrad King <brad.king@kitware.com>2023-07-18 17:21:01 (GMT)
commit7351d590ee6a846ed0f2bd4793384a33bf49ea0d (patch)
tree35ade287824ea6c02e450f3e215eaa67364e8338
parent83574a47726b8824d58b65a262c289573fb69bb0 (diff)
downloadCMake-7351d590ee6a846ed0f2bd4793384a33bf49ea0d.zip
CMake-7351d590ee6a846ed0f2bd4793384a33bf49ea0d.tar.gz
CMake-7351d590ee6a846ed0f2bd4793384a33bf49ea0d.tar.bz2
cmTarget: Add a way to represent imported shared library stubs
Shared library stubs can be used for linking, but not at runtime. Their role is similar to import libraries on Windows, so represent their location with the `IMPORTED_IMPLIB` target property. Fixes: #24940
-rw-r--r--Help/prop_tgt/IMPORTED_IMPLIB.rst6
-rw-r--r--Help/release/dev/imported-implib-only.rst7
-rw-r--r--Source/cmComputeLinkInformation.cxx18
-rw-r--r--Source/cmGeneratorTarget.h1
-rw-r--r--Source/cmTarget.cxx26
-rw-r--r--Tests/Cuda/CMakeLists.txt1
-rw-r--r--Tests/Cuda/StubRPATH/CMakeLists.txt21
-rw-r--r--Tests/Cuda/StubRPATH/main.cxx17
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CMP0111/CMP0111-Common.cmake3
-rw-r--r--Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt6
-rw-r--r--Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt5
-rw-r--r--Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake2
-rw-r--r--Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake1
15 files changed, 102 insertions, 22 deletions
diff --git a/Help/prop_tgt/IMPORTED_IMPLIB.rst b/Help/prop_tgt/IMPORTED_IMPLIB.rst
index e67acba..27601d2 100644
--- a/Help/prop_tgt/IMPORTED_IMPLIB.rst
+++ b/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
diff --git a/Help/release/dev/imported-implib-only.rst b/Help/release/dev/imported-implib-only.rst
new file mode 100644
index 0000000..aa817b7
--- /dev/null
+++ b/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.
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 04e4fc7..f4bb8b1 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/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);
+ }
}
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 03452a1..a03513d 100644
--- a/Source/cmGeneratorTarget.h
+++ b/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,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 15f45f5..b81eec5 100644
--- a/Source/cmTarget.cxx
+++ b/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());
diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt
index 0041b07..c737bcc 100644
--- a/Tests/Cuda/CMakeLists.txt
+++ b/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)
diff --git a/Tests/Cuda/StubRPATH/CMakeLists.txt b/Tests/Cuda/StubRPATH/CMakeLists.txt
new file mode 100644
index 0000000..93643c5
--- /dev/null
+++ b/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)
diff --git a/Tests/Cuda/StubRPATH/main.cxx b/Tests/Cuda/StubRPATH/main.cxx
new file mode 100644
index 0000000..877856e
--- /dev/null
+++ b/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;
+}
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 39454ed..df7cda0 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -248,7 +248,7 @@ 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>
diff --git a/Tests/RunCMake/CMP0111/CMP0111-Common.cmake b/Tests/RunCMake/CMP0111/CMP0111-Common.cmake
index c31e4ba..ab9e405 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-Common.cmake
+++ b/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)
diff --git a/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt b/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt
index e5eb4bf..c6439e2 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt
+++ b/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.$
diff --git a/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt b/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
index 5286134..7a46c41 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
+++ b/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.$
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
index 4a0f068..65c708c 100644
--- a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
+++ b/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)
diff --git a/Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake b/Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake
new file mode 100644
index 0000000..04f9cfb
--- /dev/null
+++ b/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)
diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
index 7c5d77d..0e3877a 100644
--- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
+++ b/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)