10

I've got an issue where CMake can't detect pthread. As a work-around I tried:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")

However, this inserts -lpthread in the wrong place:

/usr/bin/c++    -std=c++11 -D_GNU_SOURCE  -Wall [manyflags ...]    -lpthread \
    CMakeFiles/connectivity_tool.dir/connectivity_tool/conn_tool.cpp.o       \
    -o connectivity_tool -rdynamic -lboost_system [many libraries...]

This results in:

/usr/bin/ld: /tmp/ccNvRifh.ltrans3.ltrans.o: undefined reference to symbol 'pthread_mutexattr_settype@@GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line

Of course, the -lpthread should be at the end of the 3rd line, not the end of the 1st.

How can I go about either getting CMake to add -lpthread at the end of this line, or perhaps even modifying the generated Makefiles somehow in some hacky way to get this to work?

(If the answer involves actually detecting pthread properly then answer the linked question.)

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • 1
    Are there any additional `includes`, `set(CMAKE_EXE_LINKER_FLAGS ...)` or package references after your `set()`? Also note: For the current standards you should just specify the global `-pthread` option. – πάντα ῥεῖ Jul 17 '14 at 22:44
  • @πάνταῥεῖ: There are, I put this at the very top. Funnily enough though, using `-pthread` made it work! – Claudiu Jul 17 '14 at 22:48
  • 1
    You'll need this option (`-pthread`) for both compilation and linking phases. Glad it seems to solve your problems (IMHO linker automatism). CMake is sometimes somewhat clumsy to get things in the right order :P. I've been falling back to manage my build systems using make and the [mighty mighty make template evaluation functions](https://www.gnu.org/software/make/manual/html_node/Eval-Function.html) recently. CMake provides the same more or less, but I've been hitting unsolvable cases (like embedding CMake generated library lists into appropriate `--start-group`/`--end-group` pairs) – πάντα ῥεῖ Jul 17 '14 at 23:05

1 Answers1

6

"How can I go about either getting CMake to add -lpthread at the end of this line, or perhaps even modifying the generated Makefiles somehow in some hacky way to get this to work?"

1st be sure that your

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")

is the last seen in line by CMake.
Any further library/module references (like e.g. FIND_BOOST) may screw up the order of the flags you want to provide directly.

I would use

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")

and

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")

I think with this option, the linker automatically detects the appropriate pthread library, linked appearing at the end of the linker objects chain.

Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • That `-lpthread` option didn't help in the cmake 3.11.0 in Linux x64 with gcc 5.4. You have to use `-pthread` instead both for the compiler and the linker to resolve it for the cmake. – Andry Apr 06 '18 at 17:19
  • 3
    Note that correct way to add `-pthread` with cmake would be to use `set(THREADS_PREFER_PTHREAD_FLAG true)`, `find_package(Threads REQUIRED)` and `target_link_libraries(myprogram Threads::Threads)` – Carlo Wood Feb 23 '20 at 17:39
  • @Andry IIRC, the `-pthread` vs `-lpthread` thing is an issue on Linux even if you're calling the compiler by hand. – jpaugh Dec 06 '21 at 19:28