news 2026/6/10 1:10:08

RK3399E Android 11 将自己的库放到系统库方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3399E Android 11 将自己的库放到系统库方法

1.系统库的准备

1.1 检查库

检查需要放入系统的系统库libxxx.so是否非TLS 64, 在命令行中输入:

/home/xxx/Android/Sdk/ndk/27.3.13750724/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-readelf -l libxxx.so | grep -A5 TLS

命令行输出:

TLS 0x12f0440 0x00000000012f1440 0x00000000012f1440 0x000000 0x000028 R 0x40 DYNAMIC 0x13777b8 0x00000000013787b8 0x00000000013787b8 0x0001c0 0x0001c0 RW 0x8 GNU_RELRO 0x12f1430 0x00000000012f2430 0x00000000012f2430 0x0a7280 0x0a7bd0 R 0x1 GNU_EH_FRAME 0x64b810 0x000000000064b810 0x000000000064b810 0x04526c 0x04526c R 0x4 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0 NOTE 0x0002a8 0x00000000000002a8 0x00000000000002a8 0x0000bc 0x0000bc R 0x4

可以看到第一行最后一列为: 0x40, 如果不为0x40, 则需要重新编译so。

另外一种方法是在将libxxx.so 库放到/system/lib64 目录下,然后运行如下命令:

adb shell ldd /system/lib64/libxxx.so # 检查依赖

如果输出如下:

linux-vdso.so.1 => [vdso] (0x7bc9149000) error: "linker64": executable's TLS segment is underaligned: alignment is 8, needs to be at least 64 for ARM64 Bionic Aborted

说明该库没有64位对齐, 需要重新编译so库

如果输出为:

linux-vdso.so.1 => [vdso] (0x78fca6c000) liblog.so => /system/lib64/liblog.so (0x78fb726000) libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x78fa2a0000) libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x78fb748000) libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x78fa195000) libc++.so => /system/lib64/libc++.so (0x78fb786000)

则该库正常。

1.2 重新编译库

在libxxx.so 的任意C++文件中添加如下代码:注意只需要添加一次:

#if defined(__ANDROID__) && defined(__aarch64__) // 放在任意一个参与编译的 .cpp 文件中即可 extern "C" { __attribute__((visibility("default"))) __attribute__((aligned(64))) thread_local int _android_tls_alignment_fix = 0; } #endif

为了确保它能成功修复对齐问题,请注意以下几点:

1. 必须被链接进目标库

这个代码片段必须放在会被编译并链接进 librosa.so 的源文件中。你把它放在 rosa/RosaLinux.cc 是完美的,因为你的 CMakeLists.txt 中明确把这个文件编译进了 rosa 库。

2. 每个动态库(.so)只需要一个

链接器(linker)在生成 librosa.so 时,会扫描所有参与链接的 .o 文件(对象文件)。它会找到所有 thread_local 变量,并取其中最大的对齐值作为整个 PT_TLS 段的对齐属性。只要有一个地方定义了 alignas(64) 的 TLS 变量,整个库的 TLS 就会变成 64 字节对齐。不要在同一个库的多个源文件中放置同名的变量,否则会触发“重定义(multiple definition)”错误。

3. 不要放在 .h 头文件中

千万不要放在 .h 文件中(除非使用了 static 或 inline 修饰),原因有二:

如果头文件被多个 .cpp 包含,会导致重定义错误。如果头文件没被任何 .cpp 包含,代码就不会被编译,也就没法生效。

adb root adb remount # 确认是 lib64 还是 lib adb push librosa.so /system/lib64/ adb shell chmod 644 /system/lib64/libxxx.so # 恢复 SELinux 标签 adb shell restorecon /system/lib64/libxx.so adb reboot

4. 为什么这个代码能“隔空”生效?

你可能会奇怪:我只是在 RosaLinux.cc 里加了一个没被用到的变量,为什么能解决 spdlog 或其他代码里的错误?

物理结构决定:在一个 ELF 文件(.so)中,所有的线程本地变量(来自不同的 .cpp)最终都会被挤在同一个物理段(Segment)里,这个段叫 PT_TLS。

整体属性:PT_TLS 段作为一个整体,在文件头中只有一个“对齐(Alignment)”属性。链接器必须满足该段内要求最严格(对齐值最大)的那个变量。

木桶效应反转:这就像木桶效应的反面——只要有一块木板足够长,整个木桶的额定长度就会被标记为那个长度。

重新编译后,记得用 llvm-readelf -l librosa.so | grep TLS 确认最后那一列是否变成了 0x40。如果是,你的 adb shell ldd 报错就彻底解决了。

2. 将SO库设置为系统库

2.1 部署SO库

在命令行中依次输入如下命令:

adb root adb remount # 确认是 lib64 还是 lib adb push libxxx.so /system/lib64/ adb shell chmod 644 /system/lib64/libxxx.so # 恢复 SELinux 标签 adb shell restorecon /system/lib64/libxxx.so adb reboot

重启后,如果系统正常起来,说明设置成功。

2.2 如何正确测试库是否能加载?

如果你想验证这个库是否能被系统正确识别(且不再报 TLS 对齐错误),你应该使用 Android 链接器 来“追踪”加载过程,而不是直接运行它。

请在终端执行:

# 验证库的依赖和对齐是否通过 adb shell LD_TRACE_LOADED_OBJECTS=1 /system/bin/linker64 /system/lib64/libxxx.so

终端输出为:

Segmentation fault

3.公开系统库

通过 public.libraries.txt 公开(推荐系统开发者使用)

如果你希望这个库像 liblog.so 或 libc.so 一样,让所有 App 都能通过 System.loadLibrary 访问,确实需要在 public.libraries.txt 中添加它。

3.1 remount 系统

adb root adb remount

3.2 修改文件:

在 /system/etc/public.libraries.txt 的末尾添加一行

libxxx.so

注意(非常重要):

格式:只写库的文件名,不要写路径。

换行符:必须使用 Unix 格式的换行符(LF)。

末尾:确保最后一行后有一个换行符,且没有多余的空格或乱码。

3.3 SELinux 检查:

确保 /system/lib64/libxxx.so 的标签是正确的,否则 App 在加载时会报 Permission Denied:

adb shell restorecon /system/lib64/libxxx.so adb shell restorecon /system/etc/public.libraries.txt

3.4 重启系统:

adb reboot

修改该文件后必须重启,Android 的库管理服务才会重新加载配置。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 7:49:37

CLIP图文匹配微调实战

💓 博客主页:借口的CSDN主页 ⏩ 文章专栏:《热点资讯》 CLIP图文匹配微调实战:从理论到垂直领域落地目录CLIP图文匹配微调实战:从理论到垂直领域落地 引言:为何CLIP微调是图文理解的“关键一跃” CLIP微调的…

作者头像 李华
网站建设 2026/6/9 3:34:51

ue 蓝图 调用 c++ websocket 音频

目录 ue 中,打开关卡蓝图, ue 中,打开关卡蓝图, 添加变量,类型直接 web socket client 。 WebSocketClient.h #pragma once#include "CoreMinimal.h" #include "UObject/Object.h" #include "IWebSocket.h" #include "WebSocketClie…

作者头像 李华
网站建设 2026/6/7 11:18:32

Thinkphp-Laravel微信小程序的考试刷题及分析系统小程序

目录摘要项目开发技术介绍PHP核心代码部分展示系统结论源码获取/同行可拿货,招校园代理摘要 该系统基于ThinkPHP和Laravel框架开发,结合微信小程序平台,旨在为学生和教师提供高效的考试刷题与学习分析功能。系统分为前端小程序与后端管理平台&#xff0…

作者头像 李华
网站建设 2026/6/9 20:12:03

新手必看:Image-to-Video首次使用踩坑总结与解决方案

新手必看:Image-to-Video首次使用踩坑总结与解决方案 📖 引言:从零开始的图像转视频实践之旅 随着AIGC技术的快速发展,图像生成视频(Image-to-Video) 已不再是遥不可及的技术幻想。由社区开发者“科哥”基于…

作者头像 李华
网站建设 2026/6/9 20:09:25

用Sambert-HifiGan为电子导购添加个性化语音

用Sambert-HifiGan为电子导购添加个性化语音 引言:让电子导购“声”入人心 在智能零售与电商服务日益普及的今天,电子导购系统正从“看得见”向“听得清、有情感”演进。传统的机械式语音播报已难以满足用户对自然交互体验的需求。如何让机器说话不仅清晰…

作者头像 李华
网站建设 2026/6/9 22:46:50

Sambert-HifiGan情感控制详解:如何调节语音情绪表现

Sambert-HifiGan情感控制详解:如何调节语音情绪表现 📌 引言:中文多情感语音合成的现实需求 在智能客服、虚拟主播、有声阅读等应用场景中,单一语调的语音合成已无法满足用户对自然度和情感表达的需求。传统TTS(Text-t…

作者头像 李华