FindThreads module with static build?

Hey there,

I was using the FindThreads module in my project, and all is fine when building a dynamic library/executable.

The issue comes in when building a fully static binary. If using glibc < 2.34, the thread library has some issues (due to weak symbols) and requires some adjusting to get right:

New workaround: -Wl,--whole-archive -lrt -lpthread -Wl,--no-whole-archive

I attempted to use CMAKE_LINK_LIBRARY_USING to order to make this work, with the WHOLE_ARCHIVE feature.

However, I get the following errors:

CMake Warning (dev) at src/CMakeLists.txt:22 (add_library):
  The feature 'WHOLE_ARCHIVE', specified as part of a generator-expression
  '$<LINK_LIBRARY:WHOLE_ARCHIVE>', will not be applied to the INTERFACE
  library 'Threads::Threads'.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at tests/CMakeLists.txt:12 (add_executable):
  The feature 'WHOLE_ARCHIVE', specified as part of a generator-expression
  '$<LINK_LIBRARY:WHOLE_ARCHIVE>', will not be applied to the INTERFACE
  library 'Threads::Threads'.
This warning is for project developers.  Use -Wno-dev to suppress it.

I then tried the following:

set(THREADS_PREFER_PTHREAD_FLAG ON)

find_package(Threads REQUIRED)

set(THREAD_LIBRARY Threads::Threads)
if(BUILD_STATIC_LIBS AND NOT APPLE)
    set(THREAD_LIBRARY -Wl,--whole-archive -lrt -lpthread -Wl,--no-whole-archive)
endif()

But CMake somehow hijacks the -lpthread, as the resultant build command gets modified:
... -Wl,--whole-archive -lrt -Wl,--no-whole-archive ... -pthread ...

What is the expected way to achieve this on the latest version of CMake?

Just to update the thread here, I got something working:

# Required for glibc < 2.34
# https://discourse.cmake.org/t/findthreads-module-with-static-build/9846
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58909
if(BUILD_STATIC_LIBS AND NOT APPLE)
    target_link_options(Threads::Threads INTERFACE
            -pthread -Wl,--whole-archive -lrt -lpthread -Wl,--no-whole-archive)
endif()

Hopefully this unblocks others that hit the same issue.

You probably want to tell CMake that there’s some structure here with the whole-archive bits. @marc.chevrier, can you verify that this works:

-pthread $<LINK_LIBRARY:WHOLE_ARCHIVE,rt,pthread>

Needs CMake 3.24+ though.

The syntax for WHOLE_ARCHIVE feature is correct, but the $<LINK_LIBRARY> genex is only valid to specify link libraries. So it is required to use target_link_libraries() command:

if(BUILD_STATIC_LIBS AND NOT APPLE)
    target_link_options(Threads::Threads INTERFACE -pthread)
    target_link_libraries(Threads::Threads INTERFACE
            "$<LINK_LIBRARY:WHOLE_ARCHIVE,rt,pthread>")
endif()