as

Settings
Sign out
Notifications
Alexa
亚马逊应用商店
Ring
AWS
文档
Support
Contact Us
My Cases
新手入门
设计和开发
应用发布
参考
支持

使用链接器命名空间管理原生库

使用链接器命名空间管理原生库

链接器命名空间是一种库隔离技术,可将共享库安排到进程内单独的链接环境中。Vega的动态链接器 (ld-linux-<arch>.so) 采用这项技术来防止应用的库和系统库之间发生冲突。动态链接器在所有设备上都会在运行时强制执行命名空间边界。链接器命名空间适用于在Vega OS上运行的所有原生代码。

需要此项功能的情况

如果您处于以下情况,则需要了解链接器命名空间:

使用原生代码构建应用

  • 在Vega应用中使用C/C++库
  • 集成第三方原生SDK(视频播放器、分析、DRM)
  • 使用原生实现创建自定义Turbo模块
  • 将现有的Android或Linux应用移植到Vega

遇到构建或运行时问题

  • 构建失败,显示错误消息“library found in package”(在程序包中找到库)
  • 应用崩溃,显示错误消息“cannot open shared object file”(无法打开共享目标文件)
  • 符号在运行时解析不正确
  • 应用在一台设备上正常运行,但在另一台设备上失败

为亚马逊应用商店提交做准备

  • 您的应用在认证期间必须通过ABI验证
  • 您需要确保您的应用在操作系统更新后都能正常运行
  • 您希望避免因库冲突而被拒绝

链接命名空间可带来什么

  • 稳定性: 应用只能访问版本控制良好且应用二进制接口 (ABI) 稳定的系统库
  • 隔离: 捆绑库永远不会与系统库发生冲突
  • 兼容性: 应用在操作系统更新后继续运行

您可以用链接器命名空间做什么

  • 使用正确利用共享库的原生代码构建应用
  • 在不引起冲突的情况下捆绑第三方库
  • 安全高效地链接到部分系统库
  • 对与库依赖项或ABI违规相关的构建故障进行故障排除

工作方式

动态链接器将库分隔成两个命名空间,以强制执行隔离并防止发生冲突。

您的应用的命名空间

  • 包含应用程序包中捆绑的所有库(运行时挂载到/pkg/lib/<arch>/, /pkgs/, /mnt/
  • 可以从Vega OS公共ABI列表中访问经批准的系统库
  • 与内部操作系统库隔离

系统命名空间

  • 包含操作系统内部库
  • 仅将公共ABI列表中的库公开给应用
  • 防止访问不稳定或版本不兼容的系统库

运行时加载过程

在运行时,应用的原生入口点加载到应用命名空间中。然后,对于每个随后加载的库,动态链接器会执行以下操作:

  1. 确定所请求的库属于哪个命名空间。
  2. 检查您的应用是否有权限访问该库。
  3. 仅在该库属于您应用的命名空间或在公共ABI列表上的情况下才加载该库。
  4. 阻止访问系统内部库,防止因不兼容版本而导致运行时故障。

访问系统库

公共ABI列表中的系统库最初加载到系统命名空间中,但您的应用仍可通过符号解析来访问它们。方法如下:

示例: 您的应用使用libpthread.so.0中的pthread_create

  1. 您的应用的库请求pthread_create
  2. 动态链接器在公共ABI列表中找到libpthread.so.0
  3. 链接器通过标准符号解析让符号可供您的应用使用。
  4. 您的应用无需直接访问系统命名空间即可成功调用pthread_create

此机制可确保您的应用仅访问稳定且采用版本控制的API,同时保持命名空间隔离。这些系统库(libpthread.so.0本身依赖的库)的传递依赖项将与系统命名空间隔离,除非它们也出现在公共ABI列表中。

库搜索顺序

Vega动态链接器会使用不同的搜索路径,具体取决于所请求的库是公共操作系统ABI的一部分还是与您的应用捆绑在一起。

系统库(在公共操作系统ABI列表中)

当请求的库出现在公共操作系统ABI列表中时,链接器按以下顺序进行搜索:

  1. /lib/:/usr/lib/:/vendor/usr/lib/(系统首选搜索路径)
  2. DT_RPATH(如果不存在DT_RUNPATH
  3. LD_LIBRARY_PATH
  4. DT_RUNPATH
  5. 剩余的系统默认搜索路径

应用捆绑库(不在公共操作系统ABI列表中)

当请求的库不在公共操作系统ABI列表中时,链接器按以下顺序进行搜索:

  1. /pkg/lib/<arch>/:/pkgs/:/mnt/(应用首选的搜索路径)
  2. DT_RPATH(如果不存在DT_RUNPATH
  3. LD_LIBRARY_PATH
  4. DT_RUNPATH
  5. 剩余的系统默认搜索路径

强制执行策略

Vega通过两层方法强制执行ABI合规性:

构建时验证(尽力验证)

Vega开发工具包含了构建时ABI尽力验证功能,可在开发过程中尽早发现问题,也可在CI管道中运行。这样可以避免以后在运行时出现问题。

  • 目的: 在设备部署之前识别潜在的运行时故障
  • 作用域: 根据ABI要求验证程序包结构和依赖项建模
  • 限制: 无法捕捉所有可能的运行时场景,例如动态dlopen路径和环境符号

运行时强制执行

当您的应用在Vega系统映像中的物理或虚拟设备上运行时,动态链接器会严格强制执行命名空间隔离。应用无法访问非公共系统库,只能访问ABI列表中的库,系统会通过代理机制公开这些库。

验证您的程序包

从SDK版本0.22开始,ABI验证会在构建过程中自动运行。Vega打包工具 (vpt) 会检查您的程序包中是否:

  • 存在应动态链接的捆绑系统库
  • 缺少第三方依赖项
  • 库路径或加载模式不正确

构建因ABI违规而失败

如果您的构建未通过ABI验证:

  1. 从您的程序包中移除显示在Vega OS公共ABI列表中的系统库。
  2. 更新您的构建配置(CMakeLists.txt、Makefiles)以动态链接系统库。
  3. 确认您已将所有非系统依赖项捆绑在程序包中。
  4. 重新构建您的VPKG并重新验证。
  5. 在实际设备上测试以确认运行时行为。

最佳实践

请遵循以下最佳实践来确保您的应用符合Vega的ABI要求并避免运行时冲突。

在捆绑库之前,请务必查看Vega OS公共ABI列表。如果某个库出现在此列表中,请动态链接到该库,而不是进行捆绑

在构建配置中使用DT_NEEDED条目(首选)或显式调用系统库的dlopen()

# 在您的CMakeLists.txt中,将系统库添加到target_link_libraries
# 此操作会为动态链接创建DT_NEEDED条目
target_link_libraries(your_app PRIVATE pthread)

捆绑所有第三方依赖项

将所有不在Vega OS公共ABI列表中的库直接包含在您的应用程序包中。

例如,将libcurl捆绑到应用中:

# 在您的CMakeLists.txt中:
# 1.在您的构建环境中查找该库
find_library(CURL_LIBRARY curl)

# 2.链接到您的目标
target_link_libraries(your_app PRIVATE ${CURL_LIBRARY})

# 3.安装到程序包的lib目录中
install(FILES ${CURL_LIBRARY} DESTINATION lib)

使用非限定的库名称

调用dlopen() 时,使用不带路径的库名称:

// 正确
dlopen("libutil.so.1", RTLD_NOW);

// 不正确:避免使用完全限定路径
dlopen("/some/path/libutil.so.1", RTLD_NOW);

显式模型依赖项

不要依赖环境符号。务必通过DT_NEEDED条目或显式dlopen() 调用声明依赖项。

如果您遵循这些最佳实践,您的应用会受益于Vega的命名空间隔离模型,该模型提供了:

  • 安全捆绑: 应用可以捆绑任何不在操作系统公共ABI列表中的第三方库,而不会发生冲突
  • 符号隔离: 防止应用库和系统库之间发生符号冲突(包括不当绑定)
  • ABI一致性: 确保每个命名空间保持一致且符合预期的ABI语义
  • 版本独立性: 应用和系统可以不受干扰地使用同一个库的不同版本

Vega OS公共ABI列表

以下库可通过公共ABI提供给所有应用:

描述
ld-linux-<arch>.so 动态链接器
libc.so.6 Glibc v2.35
libdl.so.2 Glibc v2.35
libm.so.6 Glibc v2.35
libpthread.so.0 Glibc v2.35
librt.so.1 Glibc v2.35
libutil.so.1 Glibc v2.35
libkeplerscript-2.so.2 用于自定义TurboModule支持
libkeplerscript-3.so.3 用于自定义TurboModule支持
libapmf.so 用于原生IDL支持

Last updated: 2026年6月18日