mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 08:20:18 -06:00
Ninja: Ensure shared library version symlinks are created for dependents
When linking to a shared library target that has version symlinks, add an order-only dependency on the build statement that creates the links. This ensures that the links exist for use at runtime. Fixes: #19774
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <cm/memory>
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmCustomCommand.h" // IWYU pragma: keep
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
@@ -1049,6 +1050,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
// Gather order-only dependencies.
|
||||
this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
|
||||
|
||||
// Add order-only dependencies on versioning symlinks of shared libs we link.
|
||||
if (!this->GeneratorTarget->IsDLLPlatform()) {
|
||||
if (cmComputeLinkInformation* cli =
|
||||
this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
|
||||
for (auto const& item : cli->GetItems()) {
|
||||
if (item.Target &&
|
||||
item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
|
||||
!item.Target->IsFrameworkOnApple()) {
|
||||
std::string const& lib = this->ConvertToNinjaPath(
|
||||
item.Target->GetFullPath(this->GetConfigName()));
|
||||
if (std::find(linkBuild.ImplicitDeps.begin(),
|
||||
linkBuild.ImplicitDeps.end(),
|
||||
lib) == linkBuild.ImplicitDeps.end()) {
|
||||
linkBuild.OrderOnlyDeps.emplace_back(lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ninja should restat after linking if and only if there are byproducts.
|
||||
vars["RESTAT"] = byproducts.empty() ? "" : "1";
|
||||
|
||||
|
||||
17
Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c
Normal file
17
Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef REQUIRED
|
||||
# error "REQUIRED not defined"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# define IMPORT
|
||||
#endif
|
||||
|
||||
IMPORT int a(void);
|
||||
extern int required(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return required() + a();
|
||||
}
|
||||
@@ -1,7 +1,15 @@
|
||||
project(LinkObjLHSShared C)
|
||||
|
||||
# Create a versioned shared library that does not build as part of "all".
|
||||
add_library(OtherLib SHARED a.c)
|
||||
target_compile_definitions(OtherLib INTERFACE REQUIRED)
|
||||
target_compile_definitions(OtherLib INTERFACE REQUIRED PRIVATE COMPILE_FOR_SHARED_LIB)
|
||||
set_target_properties(OtherLib PROPERTIES SOVERSION 0 VERSION 0.0.0 EXCLUDE_FROM_ALL ON)
|
||||
|
||||
add_library(AnObjLib OBJECT requires.c)
|
||||
target_link_libraries(AnObjLib OtherLib)
|
||||
target_link_libraries(AnObjLib PUBLIC OtherLib)
|
||||
|
||||
add_executable(LinkObjLHSShared LinkObjLHSShared.c)
|
||||
target_link_libraries(LinkObjLHSShared AnObjLib)
|
||||
|
||||
# Verify that our dependency on OtherLib generated its versioning symlinks.
|
||||
add_custom_command(TARGET LinkObjLHSShared POST_BUILD COMMAND LinkObjLHSShared)
|
||||
|
||||
Reference in New Issue
Block a user