summaryrefslogtreecommitdiffstats
path: root/Tests/RunCMake
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-12-06 20:02:29 (GMT)
committerBrad King <brad.king@kitware.com>2024-01-04 16:59:26 (GMT)
commitdd4a6dff9246715b419a8daf4ced2d3c46a529df (patch)
treeb69ef3af6fdae649efa793e8dc00e70829a718b8 /Tests/RunCMake
parent5f1bbdb3b327ef5ff65ce331bf644d9b08d9c40f (diff)
downloadCMake-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.txt5
-rw-r--r--Tests/RunCMake/RuntimePath/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/RuntimePath/Stub-fail-result.txt1
-rw-r--r--Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt1
-rw-r--r--Tests/RunCMake/RuntimePath/Stub.c4
-rw-r--r--Tests/RunCMake/RuntimePath/Stub.cmake25
-rw-r--r--Tests/RunCMake/RuntimePath/StubExe.c5
-rw-r--r--Tests/RunCMake/RuntimePath/StubUse.c5
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();
+}