android-ndk开发(10): use of undeclared identifier ‘pthread_getname_np‘

1. 报错描述

使用 pthread 获取线程名字, 用到 pthread_getname_np 函数。 交叉编译到 Android NDK 时链接报错

bash 复制代码
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:

cmake 复制代码
$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=21

cmake --build $BUILD_DIR

用到的关键代码: test_pthread.cpp

c 复制代码
// 线程函数
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 库里定义实现的。

bash 复制代码
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]) 是它在线版:

md 复制代码
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:

pwsh 复制代码
$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=26

cmake --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\]

  • 3\]

  • 5\]

相关推荐
baiyu3314 小时前
android-ndk开发(3): 连接设备到开发机
android-ndk
baiyu333 天前
android-ndk开发(7): 从库文件反推ndk版本
android-ndk
baiyu333 天前
android-ndk开发(2): macOS 安装 ndk
android-ndk
baiyu334 天前
android-ndk开发(5): 编译运行 hello-world
android-ndk
baiyu334 天前
android-ndk开发(1): 搭建环境
android-ndk