From b75ff51947d494995b32e405f994de2819536b79 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 6 Jul 2023 14:21:20 -0400 Subject: [PATCH 1/3] Testing: Map RelWithDebInfo config in GeneratorExpression test --- Tests/GeneratorExpression/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index ef115e60a0..38ae6d8ad2 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -214,6 +214,7 @@ 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(importedFallback_genex STATIC IMPORTED) set_property(TARGET importedFallback_genex PROPERTY IMPORTED_CONFIGURATIONS RELEASE) From 83574a47726b8824d58b65a262c289573fb69bb0 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 17 Jul 2023 17:39:03 -0400 Subject: [PATCH 2/3] GeneratorExpression: Expand testing of imported location resolution --- Tests/GeneratorExpression/CMakeLists.txt | 18 ++++++++++++++++++ Tests/GeneratorExpression/check-part3.cmake | 3 +++ 2 files changed, 21 insertions(+) diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 38ae6d8ad2..39454edd13 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -216,6 +216,21 @@ 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) set_property(TARGET importedFallback_genex PROPERTY IMPORTED_LOCATION_RELEASE release_loc) @@ -234,6 +249,9 @@ add_custom_target(check-part3 ALL -Dtest_imported_includes=$ -Dtest_imported_fallback=$,fallback_loc> -Dtest_imported_fallback2=$,$,$>>,$,special_imp>,$,fallback_loc>> + -Dtest_imported_fallback3=$,$,imp_loc>,$,fallback_loc>> + -Dtest_imported_fallback4=$,$,imp_loc>,$,fallback_loc>> + -Dtest_imported_fallback5=$,imp_loc> -Dtest_imported_fallback_genex=$,FOOBAR=1> -Dtest_alias_file_exe=$,$> -Dtest_alias_file_lib=$,$> diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake index 7bb0d85ad2..eda3bc10af 100644 --- a/Tests/GeneratorExpression/check-part3.cmake +++ b/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") From 7351d590ee6a846ed0f2bd4793384a33bf49ea0d Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 17 Jul 2023 17:44:26 -0400 Subject: [PATCH 3/3] 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 --- Help/prop_tgt/IMPORTED_IMPLIB.rst | 6 +++++ Help/release/dev/imported-implib-only.rst | 7 +++++ Source/cmComputeLinkInformation.cxx | 16 +++++++----- Source/cmGeneratorTarget.h | 1 + Source/cmTarget.cxx | 26 ++++++++++++++----- Tests/Cuda/CMakeLists.txt | 1 + Tests/Cuda/StubRPATH/CMakeLists.txt | 21 +++++++++++++++ Tests/Cuda/StubRPATH/main.cxx | 17 ++++++++++++ Tests/GeneratorExpression/CMakeLists.txt | 2 +- Tests/RunCMake/CMP0111/CMP0111-Common.cmake | 3 --- Tests/RunCMake/CMP0111/CMP0111-NEW-stderr.txt | 6 +++-- .../RunCMake/CMP0111/CMP0111-WARN-stderr.txt | 5 ++-- .../AliasTargets.cmake | 8 +++++- .../ImportedTargetStub.cmake | 2 ++ .../target_link_libraries/RunCMakeTest.cmake | 1 + 15 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 Help/release/dev/imported-implib-only.rst create mode 100644 Tests/Cuda/StubRPATH/CMakeLists.txt create mode 100644 Tests/Cuda/StubRPATH/main.cxx create mode 100644 Tests/RunCMake/target_link_libraries/ImportedTargetStub.cmake diff --git a/Help/prop_tgt/IMPORTED_IMPLIB.rst b/Help/prop_tgt/IMPORTED_IMPLIB.rst index e67acbaa54..27601d2efe 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 ```` 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 0000000000..aa817b7291 --- /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 04e4fc768f..f4bb8b1585 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(); + const char* soname = + (!info || info->SOName.empty()) ? nullptr : info->SOName.c_str(); - // Include this library in the runtime path ordering. - this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname); - if (this->LinkWithRuntimePath) { - this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname); + // 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 03452a1e91..a03513d3f7 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -1076,6 +1076,7 @@ private: std::string SharedDeps; }; + friend cmComputeLinkInformation; using ImportInfoMapType = std::map; mutable ImportInfoMapType ImportInfoMap; void ComputeImportInfo(std::string const& desired_config, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 15f45f5d22..b81eec5577 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 0041b074ad..c737bcc216 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 0000000000..93643c5c63 --- /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 0000000000..877856ea02 --- /dev/null +++ b/Tests/Cuda/StubRPATH/main.cxx @@ -0,0 +1,17 @@ + +#include + +#include + +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 39454edd13..df7cda0c4a 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -248,7 +248,7 @@ add_custom_target(check-part3 ALL -Dconfig=$ -Dtest_imported_includes=$ -Dtest_imported_fallback=$,fallback_loc> - -Dtest_imported_fallback2=$,$,$>>,$,special_imp>,$,fallback_loc>> + -Dtest_imported_fallback2=$,special_imp> -Dtest_imported_fallback3=$,$,imp_loc>,$,fallback_loc>> -Dtest_imported_fallback4=$,$,imp_loc>,$,fallback_loc>> -Dtest_imported_fallback5=$,imp_loc> diff --git a/Tests/RunCMake/CMP0111/CMP0111-Common.cmake b/Tests/RunCMake/CMP0111/CMP0111-Common.cmake index c31e4ba03b..ab9e405086 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 e5eb4bfbbf..c6439e27f6 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 52861349c8..7a46c41a12 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 4a0f068605..65c708c631 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 $) 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 0000000000..04f9cfb8f1 --- /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 7c5d77d74f..0e3877aa58 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)