mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-23 07:28:51 -06:00
Merge topic 'link-stubs-transitively'
2c6ec6de15Link to transitive dependencies on stub libraries only on some linkersdd4a6dff92Link explicitly to private transitive dependencies on stub libraries5f1bbdb3b3Tests: Enable RunCMake.RuntimePath test on more platforms Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !9050
This commit is contained in:
@@ -1100,7 +1100,10 @@ if(CUDAToolkit_FOUND)
|
||||
if(CUDA_${lib_name}_LIBRARY MATCHES "/stubs/" AND NOT WIN32)
|
||||
# Use a SHARED library with IMPORTED_IMPLIB, but not IMPORTED_LOCATION,
|
||||
# to indicate that the stub is for linkers but not dynamic loaders.
|
||||
# It will not contribute any RPATH entry.
|
||||
# It will not contribute any RPATH entry. When encountered as
|
||||
# a private transitive dependency of another shared library,
|
||||
# it will be passed explicitly to linkers so they can find it
|
||||
# even when the runtime library file does not exist on disk.
|
||||
set(CUDA_IMPORT_PROPERTY IMPORTED_IMPLIB)
|
||||
set(CUDA_IMPORT_TYPE SHARED)
|
||||
endif()
|
||||
|
||||
@@ -1331,7 +1331,17 @@ void cmComputeLinkInformation::AddSharedDepItem(LinkEntry const& entry)
|
||||
}
|
||||
|
||||
// If in linking mode, just link to the shared library.
|
||||
if (this->SharedDependencyMode == SharedDepModeLink) {
|
||||
if (this->SharedDependencyMode == SharedDepModeLink ||
|
||||
// For an imported shared library without a known runtime artifact,
|
||||
// such as a CUDA stub, a library file named with the real soname
|
||||
// may not be available at all, so '-rpath-link' cannot help linkers
|
||||
// find it to satisfy '--no-allow-shlib-undefined' recursively.
|
||||
// Pass this dependency to the linker explicitly just in case.
|
||||
// If the linker also uses '--as-needed' behavior, this will not
|
||||
// add an unnecessary direct dependency.
|
||||
(tgt && tgt->IsImported() &&
|
||||
!tgt->HasKnownRuntimeArtifactLocation(this->Config) &&
|
||||
this->Target->LinkerEnforcesNoAllowShLibUndefined(this->Config))) {
|
||||
this->AddItem(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5596,6 +5596,20 @@ std::string cmGeneratorTarget::GetLinkerTool(const std::string& lang,
|
||||
return linkerTool;
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::LinkerEnforcesNoAllowShLibUndefined(
|
||||
std::string const& config) const
|
||||
{
|
||||
// FIXME(#25486): Account for the LINKER_TYPE target property.
|
||||
// Also factor out the hard-coded list below into a platform
|
||||
// information table based on the linker id.
|
||||
std::string ll = this->GetLinkerLanguage(config);
|
||||
std::string linkerIdVar = cmStrCat("CMAKE_", ll, "_COMPILER_LINKER_ID");
|
||||
cmValue linkerId = this->Makefile->GetDefinition(linkerIdVar);
|
||||
// The GNU bfd-based linker may enforce '--no-allow-shlib-undefined'
|
||||
// recursively by default. The Solaris linker has similar behavior.
|
||||
return linkerId && (*linkerId == "GNU" || *linkerId == "Solaris");
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPDBOutputName(
|
||||
const std::string& config) const
|
||||
{
|
||||
|
||||
@@ -805,6 +805,9 @@ public:
|
||||
std::string GetLinkerTool(const std::string& lang,
|
||||
const std::string& config) const;
|
||||
|
||||
/** Is the linker known to enforce '--no-allow-shlib-undefined'? */
|
||||
bool LinkerEnforcesNoAllowShLibUndefined(std::string const& config) const;
|
||||
|
||||
/** Does this target have a GNU implib to convert to MS format? */
|
||||
bool HasImplibGNUtoMS(std::string const& config) const;
|
||||
|
||||
|
||||
@@ -434,8 +434,11 @@ endif()
|
||||
add_RunCMake_test(ObjectLibrary)
|
||||
add_RunCMake_test(ParseImplicitIncludeInfo)
|
||||
add_RunCMake_test(ParseImplicitLinkInfo)
|
||||
if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG AND CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
|
||||
add_RunCMake_test(RuntimePath)
|
||||
if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
|
||||
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}
|
||||
|
||||
@@ -21,12 +21,39 @@ if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(cfg_dir /Debug)
|
||||
endif()
|
||||
|
||||
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)
|
||||
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(Relative)
|
||||
|
||||
run_RuntimePath(Genex)
|
||||
run_cmake_command(GenexCheck
|
||||
${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/Genex-build -P ${RunCMake_SOURCE_DIR}/GenexCheck.cmake)
|
||||
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()
|
||||
|
||||
1
Tests/RunCMake/RuntimePath/Stub-fail-result.txt
Normal file
1
Tests/RunCMake/RuntimePath/Stub-fail-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
1
Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt
Normal file
1
Tests/RunCMake/RuntimePath/Stub-fail-stderr.txt
Normal file
@@ -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)
|
||||
4
Tests/RunCMake/RuntimePath/Stub.c
Normal file
4
Tests/RunCMake/RuntimePath/Stub.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int Stub(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
25
Tests/RunCMake/RuntimePath/Stub.cmake
Normal file
25
Tests/RunCMake/RuntimePath/Stub.cmake
Normal file
@@ -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)
|
||||
5
Tests/RunCMake/RuntimePath/StubExe.c
Normal file
5
Tests/RunCMake/RuntimePath/StubExe.c
Normal file
@@ -0,0 +1,5 @@
|
||||
extern int StubUse(void);
|
||||
int main(void)
|
||||
{
|
||||
return StubUse();
|
||||
}
|
||||
5
Tests/RunCMake/RuntimePath/StubUse.c
Normal file
5
Tests/RunCMake/RuntimePath/StubUse.c
Normal file
@@ -0,0 +1,5 @@
|
||||
extern int Stub(void);
|
||||
int StubUse(void)
|
||||
{
|
||||
return Stub();
|
||||
}
|
||||
Reference in New Issue
Block a user