`LINK_LIBRARY:WHOLE_ARCHIVE` on a target with multiple entries should be grouped implicitly in a LINK_GROUP RESCAN
Consider the following:
add_library(A STATIC a.cpp)
add_library(B STATIC b.cpp)
add_library(C STATIC c.cpp)
target_link_libraries(B PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,A>")
add_library(sink SHARED top.cpp)
target_link_libraries(sink PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,A,B>")
This generates a linker error due to duplicate symbols since A
will be whole archived twice into sink
. If we switch to target_link_libraries(sinkA PRIVATE "$<LINK_GROUP:RESCAN,$<LINK_LIBRARY:WHOLE_ARCHIVE,A,B>>")
everything works as we de-duplicate the whole archiving of A
. Likewise if we do $<LINK_LIBRARY:WHOLE_ARCHIVE,B>
we properly pull A
into the same whole archive grouping as B
.
Given a more complicated example:
add_library(A STATIC a.cpp)
add_library(B STATIC b.cpp)
add_library(C STATIC c.cpp)
target_link_libraries(B PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,A>")
target_link_libraries(C PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,A>")
add_library(sink SHARED top.cpp)
if(BUILD_SHARED_LIBS)
target_link_libraries(sink PRIVATE B C)
else()
target_link_libraries(sink PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,B,C>")
endif()
Here see proper de-duplication of A
across the multiple usage via consumers. It isn't apparent to users why add A
to the WHOLE_ARCHIVE
for sink
will generate a different link line.
We should scan the generator expression and consistently de-duplicate duplicates when they are part of the root list and a dependency list, without explicitly wrapping the call in LINK_GROUP:RESCAN