0

I get the error "undefined reference to 'pthread_create'" when running make on a program that uses pthread library. It works when I build it directly with g++:

g++ -std=c++11 -pthread pthread_Mutex.c stopwatch.o -o pthread_Mutex

But not with CMake.

I've examined a few good examples, including here: cmake and libpthread

I've tried thehouse's examples for 3.1+ and 2.8+ versions of CMake. I'm running 3.5.1 on Ubuntu. Here is my CMakeList.txt.

cmake_minimum_required(VERSION 3.5)
project(pthread_Mutex)
set (CMAKE_CXX_STANDARD 11)
set(THREADS_PREFER_PTHREAD_FLAG ON)

find_package(Threads REQUIRED)

include_directories(include)
file(GLOB SOURCES "src/*.cpp") 
add_executable(stopwatch ${SOURCES})
add_executable(pthread_Mutex ${SOURCES})

# I've tried this one by itself 
#target_link_libraries(pthread_Mutex Threads::Threads)


if(THREADS_HAVE_PTHREAD_ARG)
  target_compile_options(pthread_Mutex PUBLIC "-pthread")
endif()
if(CMAKE_THREAD_LIBS_INIT)
  target_link_libraries(pthread_Mutex "${CMAKE_THREAD_LIBS_INIT}")
endif()

target_link_libraries(pthread_Mutex pthread) 

Here is my directory structure:

├── build
├── CMakeLists.txt
├── include
│   └── stopwatch.h
├── src
    ├── pthread_Mutex.cpp
    └── stopwatch.cpp

pthread_Mutex.cpp is my main program. stopwatch.cpp is a library that does not use pthreads.

But I get the following errors when running cmake VERBOSE=1:

/usr/bin/cmake -H/home/ben/workspaces/c++/thread_experiments -B/home/ben/workspaces/c++/thread_experiments/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
make -f CMakeFiles/pthread_Mutex.dir/build.make CMakeFiles/pthread_Mutex.dir/depend
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
cd /home/ben/workspaces/c++/thread_experiments/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles/pthread_Mutex.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
make -f CMakeFiles/pthread_Mutex.dir/build.make CMakeFiles/pthread_Mutex.dir/build
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
make[2]: Nothing to be done for 'CMakeFiles/pthread_Mutex.dir/build'.
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
[ 50%] Built target pthread_Mutex
make -f CMakeFiles/stopwatch.dir/build.make CMakeFiles/stopwatch.dir/depend
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
cd /home/ben/workspaces/c++/thread_experiments/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build /home/ben/workspaces/c++/thread_experiments/build/CMakeFiles/stopwatch.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
make -f CMakeFiles/stopwatch.dir/build.make CMakeFiles/stopwatch.dir/build
make[2]: Entering directory '/home/ben/workspaces/c++/thread_experiments/build'
[ 66%] Linking CXX executable stopwatch
/usr/bin/cmake -E cmake_link_script CMakeFiles/stopwatch.dir/link.txt --verbose=1
/usr/bin/c++      CMakeFiles/stopwatch.dir/src/pthread_Mutex.cpp.o CMakeFiles/stopwatch.dir/src/stopwatch.cpp.o  -o stopwatch 
CMakeFiles/stopwatch.dir/src/pthread_Mutex.cpp.o: In function `main':
pthread_Mutex.cpp:(.text+0x15a): undefined reference to `pthread_attr_getstacksize'
pthread_Mutex.cpp:(.text+0x19f): undefined reference to `pthread_attr_setstacksize'
pthread_Mutex.cpp:(.text+0x260): undefined reference to `pthread_create'
pthread_Mutex.cpp:(.text+0x29d): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
CMakeFiles/stopwatch.dir/build.make:120: recipe for target 'stopwatch' failed
make[2]: *** [stopwatch] Error 1
make[2]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/stopwatch.dir/all' failed
make[1]: *** [CMakeFiles/stopwatch.dir/all] Error 2
make[1]: Leaving directory '/home/ben/workspaces/c++/thread_experiments/build'
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

So I must have something wrong in the CMakeList.txt file, but I'm running out of ideas to try.

Thanks

BenW
  • 737
  • 10
  • 41
  • Did you check the output of `make VERBOSE=1` after running CMake? This can help verify that `g++` is getting the same compile options that it was getting without CMake (when you ran `g++` directly). – Kevin Apr 15 '19 at 03:03
  • 1
    I think `# target_link_libraries(pthread_Mutex Threads::Threads)` should just work in 3.1. It looks like cmake didn't set the correct import target Threads::Threads for you. You could try cmake --trace to see the verbose cmake internal log to see what is wrong. – 2power10 Apr 15 '19 at 07:43
  • @squareskittles, I added the make VERBOSE=1 output to my original post. It looks to me like -pthread is being included. It's not to clear to me. – BenW Apr 16 '19 at 02:14
  • @2power10, I did the cmake --trace. It filled up the buffer with all kinds of things. What should I be looking for? – BenW Apr 16 '19 at 02:17

2 Answers2

0

You have used target_compile_options, that's great for the compilation flags, but you forgot to do the same for the link options. Add the same line with also target_link_options.

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
0

target_compile_options adds the flag for the compilation step. You also need to link to the pthread lib -

target_link_libraries(pthread_Mutex pthread)
  • Hi Shubham Goyal, I've tried this, but I still get the errors. I added the change to my original post. Is that correct? – BenW Apr 16 '19 at 02:24
  • I am not sure what CMake does with same project and executable name, Maybe try naming the executable as `pthread_Mutex_bin` and set the output name as `pthread_Mutex` by set_target_properties(pthread_Mutex_bin PROPERTIES OUTPUT_NAME pthread_Mutex) Also, You can try - set_target_properties(pthread_Mutex PROPERTIES LINK_FLAGS -pthread) – Shubham Goyal Apr 16 '19 at 09:16