265

I'm running RHEL 5.1 and use gcc.

How I tell cmake to add -pthread to compilation and linking?

3
  • 6
    Can you choose an answer for this? Commented May 9, 2015 at 23:46
  • 1
    Dude, you gotta choose @Manuel's as the answer. Commented Sep 10, 2016 at 9:54
  • @Ehsan thehouse's answer is way better! :-) Commented Dec 11, 2016 at 17:36

4 Answers 4

310

@Manuel was part way there. You can add the compiler option as well, like this:

If you have CMake 3.1.0+, this becomes even easier:

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(my_app PRIVATE Threads::Threads)

If you are using CMake 2.8.12+, you can simplify this to:

find_package(Threads REQUIRED)
if(THREADS_HAVE_PTHREAD_ARG)
  target_compile_options(my_app PUBLIC "-pthread")
endif()
if(CMAKE_THREAD_LIBS_INIT)
  target_link_libraries(my_app "${CMAKE_THREAD_LIBS_INIT}")
endif()

Older CMake versions may require:

find_package(Threads REQUIRED)
if(THREADS_HAVE_PTHREAD_ARG)
  set_property(TARGET my_app PROPERTY COMPILE_OPTIONS "-pthread")
  set_property(TARGET my_app PROPERTY INTERFACE_COMPILE_OPTIONS "-pthread")
endif()
if(CMAKE_THREAD_LIBS_INIT)
  target_link_libraries(my_app "${CMAKE_THREAD_LIBS_INIT}")
endif()

If you want to use one of the first two methods with CMake 3.1+, you will need set(THREADS_PREFER_PTHREAD_FLAG ON) there too.

Sign up to request clarification or add additional context in comments.

6 Comments

It seems like e.g. CMake 3.0.2 won't set THREADS_HAVE_PTHREAD_ARG if pthread library was found (NOT CMAKE_HAVE_THREADS_LIBRARY), e.g. on Ubuntu 15.04 :(
The version given for CMake 2.8.12+ won't work as intended, because of how the code works in /usr/share/cmake-2.8/Modules/FindThreads.cmake (eg. see here apt-browse.org/browse/ubuntu/trusty/main/all/cmake-data/…) Basically, THREADS_HAVE_PTHREAD_ARG is only set if the other variations of the flag weren't found (ie. -lpthread, -lpthread, or -lthread)
This gives the error "Cannot specify link libraries for target "my_app" which is not built by this project." -- how do you enable it universally without having to do it individually for each target?
Is the first still the easiest way in 2020/ cmake 3.17?
What happens if you don't set the THREADS_PREFER_PTHREAD_FLAG flag, just find and link?
|
213

The following should be clean (using find_package) and work (the find module is called FindThreads):

cmake_minimum_required (VERSION 2.6) 
find_package (Threads)
add_executable (myapp main.cpp ...)
target_link_libraries (myapp ${CMAKE_THREAD_LIBS_INIT})

5 Comments

This doesn't work when using in a CXX only project. Does anyone know a nice workaround?
@Simon a bit late but please see this: stackoverflow.com/questions/15193785/…
This solution works accros Mac OS X, Centos 6 and Solaris 10.
Note that this won't set -pthread compiler flag
is find_package also the approch on windows for .dll dependencies? Because usually, you have your lib dependencies in a thirdParty directory... but cmake looks in a IMPORTED_LOCATION path, isn't it?
39

Here is the right anwser:

ADD_EXECUTABLE(your_executable ${source_files})

TARGET_LINK_LIBRARIES( your_executable
pthread
)

equivalent to

-lpthread

6 Comments

This is equivalent. "-pthread" donates much more - at compilation it's -D_REENTRANT, at link time -lpthread. On some system at even can be more than this.
SET(CMAKE_CXX_FLAGS_DEBUG "... -lpthread") SET(CMAKE_CXX_FLAGS_RELEASE "... -lpthread")
this solution bricks as soon as you change from linux to freebsd or windows.
Doesn't work, "target_link_libraries(your_executable pthread)" is how it should be written.
This is not the right answer by any means. Even if you don't like thehouse's answer, and considering this was written in 2009, it's completely non-cross platform. Use thehouse's answer - and if you don't like it then go for something like target_link_libraries(target "$<$<CXX_COMPILER_ID:GNU>:-pthread>$<$<CXX_COMPILER_ID:Clang>:-pthreads>") which is at least target-based and doesn't fail on Windows and other platforms.
|
7

target_compile_options solution above is wrong, it won't link the library.

Use:

SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -pthread")

OR

target_link_libraries(XXX PUBLIC pthread)

OR

set_target_properties(XXX PROPERTIES LINK_LIBRARIES -pthread)

1 Comment

This is brittle/outdated. Use find_package(Threads) and target_link_libraries(my_app PRIVATE Threads::Threads) instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.