Search code examples
cmakepthreads

CMake adds neither "-pthread" to compiler options nor "-lpthread" to the linker


I try to add the flag compiler flag -pthread using Cmake and Ninja. I tried the solutions described in

However, if I call ninja -vv and look at the invoked commands neither -pthread is passed to the compilation phase nor -lpthread is passed to the linker.

My CMakeLists.txt is

cmake_minimum_required(VERSION 3.27)

project(milter-alias)

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)

add_executable(
    milter-alias
    src/main.c
)

target_compile_options(milter-alias PRIVATE -Wall -Wextra -pedantic -Werror)
target_compile_features(milter-alias PRIVATE c_std_11)
target_link_libraries(milter-alias PRIVATE milter Threads::Threads)

install(TARGETS milter-alias RUNTIME DESTINATION bin)

ninja -vv results in

matthias@matthias-pc ~/Entwicklung/milter-alias/build $ ninja -vv
[1/2] /usr/bin/cc   -Wall -Wextra -pedantic -Werror -MD -MT CMakeFiles/milter-alias.dir/src/main.c.o -MF CMakeFiles/milter-alias.dir/src/main.c.o.d -o CMakeFiles/milter-alias.dir/src/main.c.o -c /home/matthias/Entwicklung/milter-alias/src/main.c
[2/2] : && /usr/bin/cc   CMakeFiles/milter-alias.dir/src/main.c.o -o milter-alias  -lmilter && :

What do I miss? In particular I am wondering why target_link_libraries( ... Threads::Threads ...) alone should be sufficient. I did expect to use target_compile_options as well.

In case it helps:

  • CMake 3.27.9
  • Ninja 1.11.1
  • GCC 13.2.1

Addendum

As requested by a comment, this is the cmake output:

matthias@matthias-pc ~/Entwicklung/milter-alias/build $ cmake -G Ninja ..
-- The C compiler identification is GNU 13.2.1
-- The CXX compiler identification is GNU 13.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Configuring done (0.2s)
-- Generating done (0.0s)
-- Build files have been written to: /home/matthias/Entwicklung/milter-alias/build

Solution

  • What do I miss?

    The event of merging pthread with main glibc and removing the confusing "unimplemted pthread when not linking with it" behavior.

    https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread

    In older versions the compiler flag -pthread also defined the preprocessor macro _REENTRANT, i.e. as if -D_REENTRANT was provided. Does any header file of the new glibc 2.34 (with integrated pthread support) define this macro unconditionally?

    From man feature_test_macros:

    _REENTRANT

    Historically, on various C libraries it was necessary to define this macro in all multithreaded code. (Some C libraries
    may still require this.) In glibc, this macro also exposed definitions of certain reentrant functions.

    However, glibc has been thread-safe by default for many years; since glibc 2.3, the only effect of defining _REENTRANT has
    been to enable one or two of the same declarations that are also enabled by defining _POSIX_C_SOURCE with a value of
    199606L or greater.

    _REENTRANT is now obsolete. In glibc 2.25 and later, defining _REENTRANT is equivalent to defining _POSIX_C_SOURCE with
    the value 199606L. If a higher POSIX conformance level is selected by any other means (such as _POSIX_C_SOURCE itself,
    _XOPEN_SOURCE, _DEFAULT_SOURCE, or _GNU_SOURCE), then defining _REENTRANT has no effect.

    This macro is automatically defined if one compiles with cc -pthread.

    Also https://github.com/bminor/glibc/blob/155bb9d036646138348fee0ac045de601811e0c5/include/features.h#L319 .