Files
CMake/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
Brad King dd4a6dff92 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.
2024-01-04 11:59:26 -05:00

60 lines
2.1 KiB
CMake

include(RunCMake)
function(run_RuntimePath name)
# Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
set(RunCMake_TEST_NO_CLEAN 1)
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(RunCMake_TEST_OPTIONS -Dcfg_dir= -DCMAKE_BUILD_TYPE=Debug)
else()
set(RunCMake_TEST_OPTIONS -Dcfg_dir=/$<CONFIG>)
endif()
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(${name})
run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
endfunction()
set(cfg_dir)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(cfg_dir /Debug)
endif()
if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
run_RuntimePath(SymlinkImplicit)
run_cmake_command(SymlinkImplicitCheck
${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/SymlinkImplicit-build -Dcfg_dir=${cfg_dir} -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
run_RuntimePath(Relative)
run_RuntimePath(Genex)
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()