android-ndk开发(10): use of undeclared identifier ‘pthread_getname_np‘
1. 报错描述
使用 pthread 获取线程名字, 用到 pthread_getname_np
函数。 交叉编译到 Android NDK 时链接报错
test_pthread.cpp:19:5: error: use of undeclared identifier 'pthread_getname_np'19 | pthread_getname_np(thread_id, thread_name, sizeof(thread_name));| ^
1 error generated.
ninja: build stopped: subcommand failed.
用到的构建脚本 build-android.ps1
:
$NDK="d:/soft/android-ndk/r28b"
$BUILD_DIR = "build-android"cmake `-S . `-B $BUILD_DIR `-G Ninja `-DCMAKE_TOOLCHAIN_FILE="$NDK/build/cmake/android.toolchain.cmake" `-DANDROID_ABI=arm64-v8a `-DANDROID_PLATFORM=21cmake --build $BUILD_DIR
用到的关键代码: test_pthread.cpp
// 线程函数
void* hello(void* arg)
{char thread_name[16];pthread_getname_np(thread_id, thread_name, sizeof(thread_name));printf("Thread name: %s\n", thread_name);return NULL;
}
3. 分析和解决
3.1 pthread_getname_np 的 np 是什么意思?
是 non portable (不可移植) 的意思.
https://man7.org/linux/man-pages/man3/pthread_getname_np.3.html (参考链接[1])
hence the suffix “_np” (nonportable) in the names.
3.2 torchat issue 2
https://github.com/FraMecca/torchat/issues/2 (参考链接[2])
提问者贴出的编译 log,看起来是 linux-x64 native 编译。
仓库 owner 回复说, 需要定义 _GNU_SOURCE
宏。
The issue is probably related to a missing #define _GNU_SOURCE .
尝试在 test_pthread.cpp
开头添加, 报错不变。
3.3 pocoproject issue 4042
https://github.com/pocoproject/poco/issues/4042 (参考链接[5]) 报告了相同的错误, 是在 android armv7-a.
project member 和 contributor 的回答没什么用处。 用户已经包含了 pthread.h
头文件。
3.4 从 bionic 找到答案
pthread 是在 Android bionic 库里定义实现的。
git clone https://android.googlesource.com/platform/bionic # 参考链接[3]
以 pthread_getname_np
为关键字在 *.md
文件里搜索, docs\status.md
有说明:
https://android.googlesource.com/platform/bionic.git/+/refs/heads/main/docs/status.md#libc (参考链接[4]) 是它在线版:
New libc functions in O (API level 26):...* `pthread_getname_np`
意思是: pthread_getname_np()
是 API level 26 开始支持的.
因此解决方案是:修改 -DANDROID_PLATFORM=21
为 -DANDROID_PLATFORM=26
或更高版本:
build-android.ps1
:
$NDK="d:/soft/android-ndk/r28b"
$BUILD_DIR = "build-android"cmake `-S . `-B $BUILD_DIR `-G Ninja `-DCMAKE_TOOLCHAIN_FILE="$NDK/build/cmake/android.toolchain.cmake" `-DANDROID_ABI=arm64-v8a `-DANDROID_PLATFORM=26cmake --build $BUILD_DIR
4. 总结
pthread_getname_np()
是在 Android API 26 新增的函数, 在 cmake configure 阶段需要传入 -DANDROID_PLATFORM=26
或更高版本。 这在 Android C 标准库 bionic 的文档里有提及: https://android.googlesource.com/platform/bionic.git/+/refs/heads/main/docs/status.md 。
References
- [1] https://man7.org/linux/man-pages/man3/pthread_getname_np.3.html
- [2] https://github.com/FraMecca/torchat/issues/2 (方案无效)
- [3] https://android.googlesource.com/platform/bionic.git/
- [4] https://android.googlesource.com/platform/bionic.git/+/refs/heads/main/docs/status.md#libc
- [5] https://github.com/pocoproject/poco/issues/4042