From d3ee832dfd0cc1b1375ba5db3c1368ed15ec5dc1 Mon Sep 17 00:00:00 2001 From: Yauheni Khnykin <4347948+Hsilgos@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:32:50 +0100 Subject: [PATCH] Processes variant when OBJECT lib links another OBJECT lib (#1569) This variant is important for dependency discovery because linking of OBJECT(1) to OBJECT(2) doesn't mean that final shared library (which links OBJECT(1)) contains also code from OBJECT(2). It might bring wrong dependency and Swift code for OBJECT(2) falsely imports incorrect Framework. Signed-off-by: Yauheni Khnykin --- .../gluecodium/details/GetLinkedTargets.cmake | 13 ++++++- .../CMakeLists.txt | 36 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/cmake/modules/gluecodium/gluecodium/details/GetLinkedTargets.cmake b/cmake/modules/gluecodium/gluecodium/details/GetLinkedTargets.cmake index 7cb8e3acdd..1b79faa6c8 100644 --- a/cmake/modules/gluecodium/gluecodium/details/GetLinkedTargets.cmake +++ b/cmake/modules/gluecodium/gluecodium/details/GetLinkedTargets.cmake @@ -60,7 +60,18 @@ function(gluecodium_get_linked_targets_rec result visited_targets _target only_s elseif(NOT _linked_type STREQUAL "INTERFACE_LIBRARY") get_target_property(_framework ${_linked_lib} FRAMEWORK) # Framework can be static, but it's still final target - if(_linked_type STREQUAL "SHARED_LIBRARY" OR _framework) + if(_framework) + continue() + endif() + + # According to documentation object files only from directly linked OBJECT libraries are + # used. This check processes this variant. + if(_linked_type STREQUAL "OBJECT_LIBRARY" + AND (_target_type STREQUAL "OBJECT_LIBRARY" OR _target_type STREQUAL "INTERFACE_LIBRARY" + )) + # Remove this OBJECT library from visited because it still can be directly linked in + # another place. + list(POP_BACK ${visited_targets}) continue() endif() endif() diff --git a/cmake/tests/unit/get_linked_targets_with_generated_sources/get_linked_targets_with_generated_sources/CMakeLists.txt b/cmake/tests/unit/get_linked_targets_with_generated_sources/get_linked_targets_with_generated_sources/CMakeLists.txt index bef0e26174..e23dc9360e 100644 --- a/cmake/tests/unit/get_linked_targets_with_generated_sources/get_linked_targets_with_generated_sources/CMakeLists.txt +++ b/cmake/tests/unit/get_linked_targets_with_generated_sources/get_linked_targets_with_generated_sources/CMakeLists.txt @@ -129,6 +129,7 @@ test_expect_strequal_lists( if(APPLE AND CMAKE_GENERATOR STREQUAL "Xcode") # cmake-format: off # (G) - target with generated code + # (F) - framework # # SHARED1(G) -> STATIC1(G) -> SHARED2(G) # |-------> STATIC2 -> OBJECT1(G) @@ -150,3 +151,38 @@ if(APPLE AND CMAKE_GENERATOR STREQUAL "Xcode") test_expect_strequal_lists(EXPECTED shared1.generated.code static1.generated.code object1.generated.code ACTUAL ${_targets}) endif() + +# cmake-format: off +# (G) - target with generated code +# (F) - framework +# +# SHARED1(G) -> STATIC1(G) -> SHARED2(G) +# |-------> STATIC2 -> OBJECT1(G) -> OBJECT4(G) +# |-------> OBJECT3 -> SHARED1(G) - loop +# |-------> STATIC3(GF) +# cmake-format: on + +add_library(object4.generated.code OBJECT EXCLUDE_FROM_ALL "cpp/FooImpl.cpp" "lime/foo.lime") +gluecodium_generate(object4.generated.code GENERATORS ${_gluecodium_generators}) +target_link_libraries(object1.generated.code PRIVATE object4.generated.code) + +gluecodium_get_linked_targets_with_generated_sources(_targets shared1.generated.code ONLY_STATIC) +test_expect_strequal_lists(EXPECTED shared1.generated.code static1.generated.code + object1.generated.code ACTUAL ${_targets}) + +# cmake-format: off +# (G) - target with generated code +# (F) - framework +# +# SHARED1(G) -> STATIC1(G) -> SHARED2(G) +# |-------> STATIC2 -> OBJECT1(G) -> OBJECT4(G) +# |-------> OBJECT3 -> SHARED1(G) - loop +# |-------> STATIC3(GF) +# |-------> OBJECT4(G) +# cmake-format: on + +target_link_libraries(shared1.generated.code PRIVATE object4.generated.code) +gluecodium_get_linked_targets_with_generated_sources(_targets shared1.generated.code ONLY_STATIC) +test_expect_strequal_lists( + EXPECTED shared1.generated.code static1.generated.code object1.generated.code + object4.generated.code ACTUAL ${_targets})