From 50fdaf8f1f6e34d9362b679df0a26d6bbf77c0ba Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 14 Nov 2023 12:45:06 -0500 Subject: cmComputeLinkInformation: Track targets named by TARGET_OBJECTS sources Since commit b6a5382217 (Ninja: depend on language module information files directly, 2023-02-10, v3.27.0-rc1~502^2), the return value of `cmCommonTargetGenerator::GetLinkedTargetDirectories` must account for linked object libraries because they may provide modules (#25112). These were added by commit b665966933 (cmComputeLinkInformation: track OBJECT library dependencies, 2023-07-22, v3.27.1~5^2). However, targets named by `$` sources are also needed (#25365). The latter were added by commit 22da18b995 (Fortran: Restore support for TARGET_OBJECTS providing modules, 2023-10-27, v3.28.0-rc4~9^2) and commit 035302b7e3 (cmComputeLinkDepends: also copy the target from object link items, 2023-10-27, v3.28.0-rc4~9^2~2). However, their approach added link entries not actually specified by projects. It also incorrectly re-used `cmComputeLinkDepends::AddLinkObject` for object library targets when it is meant for their individual object files. These problems caused additional regressions (#25417). Revert the implementation parts of those commits and leave behind an assertion and comment to help avoid the mistake in the future. Instead, track targets named by `$` sources with a dedicated member. Issue: #25112 Issue: #25365 Fixes: #25417 Co-authored-by: Ben Boeckel --- Source/cmCommonTargetGenerator.cxx | 3 +++ Source/cmComputeLinkDepends.cxx | 22 ++------------- Source/cmComputeLinkDepends.h | 1 - Source/cmComputeLinkInformation.cxx | 31 ++++++++++++++++++++++ Source/cmComputeLinkInformation.h | 5 ++++ Tests/ObjectLibrary/CMakeLists.txt | 2 ++ .../TransitiveLinkDeps/CMakeLists.txt | 15 +++++++++++ Tests/ObjectLibrary/TransitiveLinkDeps/dep.c | 4 +++ Tests/ObjectLibrary/TransitiveLinkDeps/impl_obj.c | 6 +++++ Tests/ObjectLibrary/TransitiveLinkDeps/main.c | 6 +++++ 10 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 Tests/ObjectLibrary/TransitiveLinkDeps/CMakeLists.txt create mode 100644 Tests/ObjectLibrary/TransitiveLinkDeps/dep.c create mode 100644 Tests/ObjectLibrary/TransitiveLinkDeps/impl_obj.c create mode 100644 Tests/ObjectLibrary/TransitiveLinkDeps/main.c diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index e9233b6..a5536d0 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -200,6 +200,9 @@ std::vector cmCommonTargetGenerator::GetLinkedTargetDirectories( for (cmGeneratorTarget const* target : cli->GetObjectLibrariesLinked()) { addLinkedTarget(target); } + for (cmGeneratorTarget const* target : cli->GetExternalObjectTargets()) { + addLinkedTarget(target); + } } return dirs; } diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 4100135..f80c5fb 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -26,7 +26,6 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" -#include "cmSourceFile.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" @@ -320,9 +319,6 @@ cmComputeLinkDepends::Compute() // Follow the link dependencies of the target to be linked. this->AddDirectLinkEntries(); - // Add dependencies on targets named by $ sources. - this->AddTargetObjectEntries(); - // Complete the breadth-first search of dependencies. while (!this->BFSQueue.empty()) { // Get the next entry. @@ -503,6 +499,8 @@ std::pair cmComputeLinkDepends::AddLinkEntry( void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item) { + assert(!item.Target); // The item is an object file, not its target. + // Allocate a spot for the item entry. auto lei = this->AllocateLinkEntry(item); @@ -516,7 +514,6 @@ void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item) LinkEntry& entry = this->EntryList[index]; entry.Item = BT(item.AsStr(), item.Backtrace); entry.Kind = LinkEntry::Object; - entry.Target = item.Target; // Record explicitly linked object files separately. this->ObjectEntries.emplace_back(index); @@ -705,21 +702,6 @@ void cmComputeLinkDepends::AddDirectLinkEntries() } } -void cmComputeLinkDepends::AddTargetObjectEntries() -{ - std::vector externalObjects; - this->Target->GetExternalObjects(externalObjects, this->Config); - for (auto const* externalObject : externalObjects) { - std::string const& objLib = externalObject->GetObjectLibrary(); - if (objLib.empty()) { - continue; - } - cmLinkItem const& objItem = - this->Target->ResolveLinkItem(BT(objLib)); - this->AddLinkObject(objItem); - } -} - template void cmComputeLinkDepends::AddLinkEntries(size_t depender_index, std::vector const& libs) diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 63c289c..22c4e2a 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -100,7 +100,6 @@ private: void AddLinkObject(cmLinkItem const& item); void AddVarLinkEntries(size_t depender_index, const char* value); void AddDirectLinkEntries(); - void AddTargetObjectEntries(); template void AddLinkEntries(size_t depender_index, std::vector const& libs); void AddLinkObjects(std::vector const& objs); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index f06e96f..9046f92 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -15,6 +15,7 @@ #include "cmComputeLinkDepends.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" +#include "cmLinkItem.h" #include "cmList.h" #include "cmListFileCache.h" #include "cmLocalGenerator.h" @@ -23,6 +24,7 @@ #include "cmOrderDirectories.h" #include "cmPlaceholderExpander.h" #include "cmPolicies.h" +#include "cmSourceFile.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" @@ -531,6 +533,12 @@ cmComputeLinkInformation::GetObjectLibrariesLinked() const return this->ObjectLibrariesLinked; } +const std::vector& +cmComputeLinkInformation::GetExternalObjectTargets() const +{ + return this->ExternalObjectTargets; +} + bool cmComputeLinkInformation::Compute() { // Skip targets that do not link or have link-like information consumers may @@ -678,6 +686,9 @@ bool cmComputeLinkInformation::Compute() this->Target->GetBacktrace()); } + // Record targets referenced by $ sources. + this->AddExternalObjectTargets(); + return true; } @@ -1052,6 +1063,26 @@ cmComputeLinkInformation::GetGroupFeature(std::string const& feature) .first->second; } +void cmComputeLinkInformation::AddExternalObjectTargets() +{ + std::vector externalObjects; + this->Target->GetExternalObjects(externalObjects, this->Config); + std::set emitted; + for (auto const* externalObject : externalObjects) { + std::string const& objLib = externalObject->GetObjectLibrary(); + if (objLib.empty()) { + continue; + } + if (emitted.insert(objLib).second) { + cmLinkItem const& objItem = + this->Target->ResolveLinkItem(BT(objLib)); + if (objItem.Target) { + this->ExternalObjectTargets.emplace_back(objItem.Target); + } + } + } +} + void cmComputeLinkInformation::AddImplicitLinkInfo() { // The link closure lists all languages whose implicit info is needed. diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 8393a29..1052b96 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -98,6 +98,8 @@ public: std::set const& GetSharedLibrariesLinked() const; std::vector const& GetObjectLibrariesLinked() const; + std::vector const& GetExternalObjectTargets() + const; std::vector const& GetRuntimeDLLs() const { return this->RuntimeDLLs; @@ -135,6 +137,7 @@ private: std::vector RuntimeSearchPath; std::set SharedLibrariesLinked; std::vector ObjectLibrariesLinked; + std::vector ExternalObjectTargets; std::vector RuntimeDLLs; // Context information. @@ -219,6 +222,8 @@ private: bool FinishLinkerSearchDirectories(); void PrintLinkPolicyDiagnosis(std::ostream&); + void AddExternalObjectTargets(); + // Implicit link libraries and directories for linker language. void LoadImplicitLinkInfo(); void AddImplicitLinkInfo(); diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt index b57761b..2bc2327 100644 --- a/Tests/ObjectLibrary/CMakeLists.txt +++ b/Tests/ObjectLibrary/CMakeLists.txt @@ -77,3 +77,5 @@ add_subdirectory(ExportLanguages) add_subdirectory(LinkObjects) add_subdirectory(Transitive) + +add_subdirectory(TransitiveLinkDeps) diff --git a/Tests/ObjectLibrary/TransitiveLinkDeps/CMakeLists.txt b/Tests/ObjectLibrary/TransitiveLinkDeps/CMakeLists.txt new file mode 100644 index 0000000..3f561fa --- /dev/null +++ b/Tests/ObjectLibrary/TransitiveLinkDeps/CMakeLists.txt @@ -0,0 +1,15 @@ +add_library(implgather INTERFACE) + +add_library(dep STATIC dep.c) + +add_library(deps INTERFACE) +target_link_libraries(deps INTERFACE dep) + +add_library(impl_obj OBJECT impl_obj.c) +target_link_libraries(impl_obj PUBLIC deps) + +target_sources(implgather INTERFACE "$") +target_link_libraries(implgather INTERFACE impl_obj) + +add_executable(useimpl main.c) +target_link_libraries(useimpl PRIVATE implgather) diff --git a/Tests/ObjectLibrary/TransitiveLinkDeps/dep.c b/Tests/ObjectLibrary/TransitiveLinkDeps/dep.c new file mode 100644 index 0000000..7cc62c3 --- /dev/null +++ b/Tests/ObjectLibrary/TransitiveLinkDeps/dep.c @@ -0,0 +1,4 @@ +int from_dep(void) +{ + return 0; +} diff --git a/Tests/ObjectLibrary/TransitiveLinkDeps/impl_obj.c b/Tests/ObjectLibrary/TransitiveLinkDeps/impl_obj.c new file mode 100644 index 0000000..f5760b7 --- /dev/null +++ b/Tests/ObjectLibrary/TransitiveLinkDeps/impl_obj.c @@ -0,0 +1,6 @@ +int from_dep(void); + +int impl_obj(void) +{ + return from_dep(); +} diff --git a/Tests/ObjectLibrary/TransitiveLinkDeps/main.c b/Tests/ObjectLibrary/TransitiveLinkDeps/main.c new file mode 100644 index 0000000..5661f57 --- /dev/null +++ b/Tests/ObjectLibrary/TransitiveLinkDeps/main.c @@ -0,0 +1,6 @@ +int impl_obj(void); + +int main(int argc, char* argv[]) +{ + return impl_obj(); +} -- cgit v0.12