最近开始使用Clion编辑器,踩了不少坑
关键字:
Cmake版本导致的undefined reference to ‘pthread_join’
详细问题描述:
起初,项目clone下来的目录就是这样的:

即CmakeLists.txt和makefile在同一级目录里面。按照原作者的思路,我们应该先在本级目录下make,然后再运行TKeed文件(其实就是linking后的src_code可执行文件别名)。
在terminal中,这样固然是不会遇到问题的。但我想在Clion编辑器中方便的调试,于是乎,按项目规定的配置来设定了以下setting选项:

注意这边的CMake,为之后的坑埋下了伏笔。
配置完成后,Clion提示我选中一个CmakeList.txt文件,选中之后,发现并不能运行。报错

undefined reference to ‘pthread_join’ & ‘pthread_create’。这个报错字面意思是找不到pthead.h里面的两个库函数。
一开始在中文社区搜,搜到质量最高的回答是这个:
https://zhuanlan.zhihu.com/p/81681440
这篇文章简述了遇到这种情况的排查方法,但主要集中在CmakeList.txt是否有没有包括进响应的.h文件,以及c++的内核优化起名问题。然而这个项目是一个纯C的项目,而且这是个库函数报错。
上面说到,Clion默认使用的是Cmake来做编译的过程。因此遵循Cmake -->生成MakeFile -->在MakeFile同级路径下make -->生成.o文件可执行文件的过程,即compile和linking两个主要过程。
排查:
第一步,先检查文件夹中是否有全部的目标.o文件,如果全部出现了,则说明compile编译过程无误。
第二步,检查MakeFile文件中,是否有-pthread或-lpthread的flag。
我们发现,项目中一开始在本级目录下自带的MakeFile文件,里面是带有-lpthread的。
CC = gcc -std=gnu99
TKeed:main.o util.o epoll.o http.o http_parse.o http_request.o priority_queue.o rio.o timer.o threadpool.o
$(CC) *.o -o TKeed -lpthread
main.o:main.c
$(CC) -c main.c
util.o:util.c util.h
$(CC) -c util.c
threadpool.o:threadpool.c threadpool.h
$(CC) -c threadpool.c
...
而使用Cmake来生成的makefile里面却不带有这个flag。因此,可以判断生成makefile这个过程中有错误发生。
经过请教大佬,这个问题是Cmake的版本问题(自己一直没有往这边想)。
//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 CMa、ke 3.1+, you will need
set(THREADS_PREFER_PTHREAD_FLAG ON)
总结:
这个cmakelists.txt本身有问题,需要用pthread lib,但是又没写进去。old makefile是正确的,所以可以bypass cmake的错误。
在使用Clion编辑C项目时遇到undefined reference to ‘pthread_join’ & ‘pthread_create’的问题。排查后发现是Cmake版本导致生成的Makefile缺少-lpthread标志。解决方案是更新Cmake版本或手动修改CmakeLists.txt添加pthread库。
1万+

被折叠的 条评论
为什么被折叠?



