Using --whole-archive linker option with CMake and libraries with other library dependencies

For 3.12 and newer versions of CMake, I would use object libraries.

The workaround I found for versions earlier than that was to create an intermediate static library that used some property magic to place all linkage dependencies inside the --whole-archive section. For me, the top-level static library was called 'source'. It contained actually nothing itself, but had linkage dependencies on a bunch of other static libraries. I created 'source-combined' as follows:

add_library(source-combined STATIC "")
set_target_properties(source-combined PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(source-combined PUBLIC
  -Wl,--whole-archive
  $<TARGET_PROPERTY:source,INTERFACE_LINK_LIBRARIES>
  -Wl,--no-whole-archive
)

Now when I create an executable or a shared library by linking against this souce-combined library, I get the --whole-archive and --no-whole-archive as bookends around the entire set of static libraries that were the link dependencies of 'source'. It took forever to stumble across this technique, so I'm sharing it.


The following worked for me. Consider two libraries:

  • my_platform
  • my_clib

We want the whole archive of my_clib, and my_platform links to it.

add_library(my_platform INTERFACE) # this could also be a regular library

add_library(my_clib STATIC)
target_sources(my_clib
PRIVATE 
    gcc_newlib_nano.c 
    gcc_newlib_nano_cpp.cc 
)

# Link my_clib and any other libs
target_link_libraries(my_platform
INTERFACE
    my_clib
)
# Ensure the whole archive is linked
target_link_options(my_platform
INTERFACE
-Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/libmy_clib.a -Wl,--no-whole-archive
)

Tags:

C++

G++

Cmake