diff options
author | Brad King <brad.king@kitware.com> | 2019-10-01 17:31:41 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2019-10-01 18:34:03 (GMT) |
commit | 4891f0f9662d6e2b355717aa1f7250f3462229bb (patch) | |
tree | 6052be050944f9f7ac133a397d5d159e09556361 | |
parent | 62d65286e71c58c88646f2f851edf7669fd40a41 (diff) | |
download | CMake-4891f0f9662d6e2b355717aa1f7250f3462229bb.zip CMake-4891f0f9662d6e2b355717aa1f7250f3462229bb.tar.gz CMake-4891f0f9662d6e2b355717aa1f7250f3462229bb.tar.bz2 |
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
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 21 | ||||
-rw-r--r-- | Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c | 17 | ||||
-rw-r--r-- | Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.cmake | 12 |
3 files changed, 48 insertions, 2 deletions
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index bd5abd1..38ccaa3 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -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"; diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c b/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c new file mode 100644 index 0000000..088da30 --- /dev/null +++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c @@ -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(); +} diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.cmake index 4aa7bba..0a76932 100644 --- a/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.cmake +++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.cmake @@ -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) |