diff options
author | Brad King <brad.king@kitware.com> | 2023-12-06 20:02:29 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2024-01-04 16:59:26 (GMT) |
commit | dd4a6dff9246715b419a8daf4ced2d3c46a529df (patch) | |
tree | b69ef3af6fdae649efa793e8dc00e70829a718b8 /Tests/RunCMake | |
parent | 5f1bbdb3b327ef5ff65ce331bf644d9b08d9c40f (diff) | |
download | CMake-dd4a6dff9246715b419a8daf4ced2d3c46a529df.zip CMake-dd4a6dff9246715b419a8daf4ced2d3c46a529df.tar.gz CMake-dd4a6dff9246715b419a8daf4ced2d3c46a529df.tar.bz2 |
Link explicitly to private transitive dependencies on stub libraries
We represent stub libraries, e.g., for CUDA, using imported `SHARED`
library targets with only `IMPORTED_IMPLIB`, and no `IMPORTED_LOCATION`,
to indicate that the stub file is meant only for linkers and not dynamic
loaders. See commit 7351d590ee (cmTarget: Add a way to represent
imported shared library stubs, 2023-07-17, v3.28.0-rc1~344^2) and commit
fc6508921c (cmComputeLinkInformation: Restore soname lookup for
non-imported targets, 2023-12-05, v3.28.0~4^2).
If a shared library is linked to a stub, it has a `NEEDED` field
populated with the `SONAME` found in the stub. When a dependent target
links to such a shared library, some linkers want to find a library file
on disk and load it to see what symbols it provides. This is necessary
for linkers that enforce `--no-allow-shlib-undefined`. On hosts with
only the stub library installed, e.g., with only the CUDA toolkit
development package, the real runtime library corresponding to the
stub's `SONAME` may not even exist, so no `-rpath-link` flag can help
linkers find it. Pass the stub library to linkers explicitly so they
can find it without searching.
Diffstat (limited to 'Tests/RunCMake')
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/RunCMakeTest.cmake | 25 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/Stub-fail-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/Stub.c | 4 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/Stub.cmake | 25 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/StubExe.c | 5 | ||||
-rw-r--r-- | Tests/RunCMake/RuntimePath/StubUse.c | 5 |
8 files changed, 70 insertions, 1 deletions
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index e581042..19734c6 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -435,7 +435,10 @@ add_RunCMake_test(ObjectLibrary) add_RunCMake_test(ParseImplicitIncludeInfo) add_RunCMake_test(ParseImplicitLinkInfo) if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG) - add_RunCMake_test(RuntimePath -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT}) + add_RunCMake_test(RuntimePath + -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} + -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT} + ) endif() add_RunCMake_test(ScriptMode) add_RunCMake_test(Swift -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} diff --git a/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake b/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake index 531cd05..180a0fe 100644 --- a/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake +++ b/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake @@ -32,3 +32,28 @@ if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF") run_cmake_command(GenexCheck ${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/Genex-build -P ${RunCMake_SOURCE_DIR}/GenexCheck.cmake) endif() + +block() + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Stub-build) + if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(bin_dir "${RunCMake_TEST_BINARY_DIR}/Debug") + set(lib_dir "${RunCMake_TEST_BINARY_DIR}/lib/Debug") + else() + set(bin_dir "${RunCMake_TEST_BINARY_DIR}") + set(lib_dir "${RunCMake_TEST_BINARY_DIR}/lib") + endif() + run_cmake(Stub) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(Stub-build ${CMAKE_COMMAND} --build . --config Debug) + if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|SunOS)$|BSD") + set(ldpath LD_LIBRARY_PATH) + elseif(CMAKE_SYSTEM_NAME MATCHES "^(Darwin)$") + set(ldpath DYLD_LIBRARY_PATH) + elseif(CMAKE_SYSTEM_NAME MATCHES "^(AIX)$") + set(ldpath LIBPATH) + endif() + if(ldpath) + run_cmake_command(Stub-fail ${CMAKE_COMMAND} -E env LANG=C ${bin_dir}/StubExe) + run_cmake_command(Stub-pass ${CMAKE_COMMAND} -E env --modify ${ldpath}=path_list_prepend:${lib_dir} ${bin_dir}/StubExe) + endif() +endblock() diff --git a/Tests/RunCMake/RuntimePath/Stub-fail-result.txt b/Tests/RunCMake/RuntimePath/Stub-fail-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/RuntimePath/Stub-fail-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt b/Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt new file mode 100644 index 0000000..9c17414 --- /dev/null +++ b/Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt @@ -0,0 +1 @@ +(error while loading shared libraries: libStub\.so\.1|Library not loaded: '?@rpath/libStub\.1\.dylib'?|(Cannot|Could not) load module libStub\.so|fatal: libStub\.so\.1: open failed|Shared object "libStub\.so\.1" not found) diff --git a/Tests/RunCMake/RuntimePath/Stub.c b/Tests/RunCMake/RuntimePath/Stub.c new file mode 100644 index 0000000..2ff333a --- /dev/null +++ b/Tests/RunCMake/RuntimePath/Stub.c @@ -0,0 +1,4 @@ +int Stub(void) +{ + return 0; +} diff --git a/Tests/RunCMake/RuntimePath/Stub.cmake b/Tests/RunCMake/RuntimePath/Stub.cmake new file mode 100644 index 0000000..18e99c1 --- /dev/null +++ b/Tests/RunCMake/RuntimePath/Stub.cmake @@ -0,0 +1,25 @@ +enable_language(C) + +add_library(Stub SHARED Stub.c) +set_target_properties(Stub PROPERTIES + SOVERSION 1 + LIBRARY_OUTPUT_DIRECTORY lib + ) + +set(StubDir ${CMAKE_CURRENT_BINARY_DIR}/lib/stubs) +set(Stub "${StubDir}/${CMAKE_SHARED_LIBRARY_PREFIX}Stub${CMAKE_SHARED_LIBRARY_SUFFIX}") +add_custom_target(StubCopy + COMMAND ${CMAKE_COMMAND} -E make_directory "${StubDir}" + COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_SONAME_FILE:Stub>" "${Stub}" + BYPRODUCTS ${Stub} + ) +add_dependencies(StubCopy Stub) +add_library(Imp::Stub SHARED IMPORTED) +set_property(TARGET Imp::Stub PROPERTY IMPORTED_IMPLIB "${Stub}") +add_dependencies(Imp::Stub StubCopy) + +add_library(StubUse SHARED StubUse.c) +target_link_libraries(StubUse PRIVATE Imp::Stub) + +add_executable(StubExe StubExe.c) +target_link_libraries(StubExe PRIVATE StubUse) diff --git a/Tests/RunCMake/RuntimePath/StubExe.c b/Tests/RunCMake/RuntimePath/StubExe.c new file mode 100644 index 0000000..14b3fe4 --- /dev/null +++ b/Tests/RunCMake/RuntimePath/StubExe.c @@ -0,0 +1,5 @@ +extern int StubUse(void); +int main(void) +{ + return StubUse(); +} diff --git a/Tests/RunCMake/RuntimePath/StubUse.c b/Tests/RunCMake/RuntimePath/StubUse.c new file mode 100644 index 0000000..ffdaf6d --- /dev/null +++ b/Tests/RunCMake/RuntimePath/StubUse.c @@ -0,0 +1,5 @@ +extern int Stub(void); +int StubUse(void) +{ + return Stub(); +} |