先介绍一下使用环境
资源 | 详情 |
---|---|
平台 | 树莓派4B |
系统 | 2022-04-04-raspios-bullseye-arm64 |
GCC | gcc (Debian 10.2.1-6) 10.2.1 20210110 |
CMAKE | cmake version 3.18.4 |
刚入手树莓派,发现在使用cmake的时候无法使用pthread_create
创建函数,添加-pthread
依然无法编译通过,非常奇怪,遂研究了一翻。
先说结论:在CMakeLists末尾添加一句: target_link_libraries(你的输出文件名 pthread)
,并去掉-lpthread
即可。
1 简单的C文件测试
(1)创建一个main.c 文件,添加一个简单的线程
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void pthread1(void)
{
while (1)
{
sleep(1); //延迟1秒
printf("子线程在工作\r\n");
}
}
int main(void)
{
pthread_t tid_test;
pthread_create(&tid_test, NULL, (void *)pthread1, NULL);
while (1)
{
sleep(1);
printf("主线程在工作\r\n");
}
}
(2)通过命令行使用gcc及-pthread
gcc main.c -o main -lpthread
结论:可正常使用线程
2 基于CMAKE的线程编译测试
在上边创建了main.c 的基础上,再创建一个CMakeLists.txt,内容如下:
set (CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.16)
# 设置工程名
project (Pthread_Test)
set(CMAKE_C_FLAGS -pthread) #编译命令后缀 使用线程添加-lpthread
# 指定生成目标
add_executable(main main.c)
编译
cmake .
make
编译不通过。
备注:如果你原本的工程编译不通过,现在像我这样新建测试工程反而能通过的,继续往下看。
3 修改CMakeLists.txt 文件
我们修改了一下CMakeLists.txt,末尾添加一句:target_link_libraries(main pthread)
。此时可以去掉-lpthread
,如下:
set (CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.16)
# 设置工程名
project (Pthread_Test)
set(CMAKE_C_FLAGS) #编译命令后缀 不需要添加-lpthread
add_executable(main main.c)
#添加pthread库
target_link_libraries(main pthread)
重新编译执行。
cmake .
make
./main
你会发现他可以编译成功了。
这就很奇怪了,因为target_link_libraries(main pthread)
就等效于-lpthread
才对。
但是,能用就行,人生苦短,不必纠结。
4 cmake+wiringPi+pthread编译不通过
当你使用pthread又使用wiringPi时,如果又有下边的提示。
建议不使用-lwiringPi
和-lpthread
,改用 target_link_libraries
语句,如下:
#***************CMakeLists.txt*********************
set (CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.16)
# 设置工程名
project (Pthread_Test)
set(CMAKE_C_FLAGS) #编译命令后缀 这里什么都不用添加
add_executable(main main.c)
#添加pthread库
target_link_libraries(main pthread)
target_link_libraries(main wiringPi)
如果找不到wiringPi,可以将target_link_libraries(main wiringPi)
改成下边:
# 链接到 wiringPi库
find_library(WIRINGPI_LIBRARIES NAMES wiringPi)
target_link_libraries(main ${WIRINGPI_LIBRARIES})
以上。