glibc默认系统库目录问题

在修包过程中,遇到了几个库版本符号链接方面的错误,与glibc的ldconfig命令有关,进而与dl-cache.h中系统库目录列表有关。由于对glibc的认识有限,恳请大佬们指导。

一、问题

  1. tss2在打包阶段报出libibmtssutils.so.1不存在。进入构建环境查看,该文件应该是个版本库的符号链接,版本库本身是存在的,但这个符号链接没有安装到BUILDROOT下。原始报告见下述链接中的问题描述部分:【构建失败】【待合并】【已解决】tss2 · Pull Request !2 · openEuler-RISC-V/tss2 - Gitee.com

  2. 安装leveldb后,系统报libleveldb.so.1不是个符号链接错误。通过它的spec文件和构建环境查看,该文件本应是个版本库的链接链接,但实际安装成了实体文件。File _service:tar_scm:leveldb.spec of Package leveldb - Open Build Service

二、分析

试验构建了x86的对应包,结果是没有任何错误。分析构建过程,在make install结束后,x86和riscv的状态是一样的,即tss2的libibmtssutils.so.1也不存在,leveldb的libleveldb.so.1也是实体文件。但在执行了make install之后的%ldconfig_scriptlets宏以后,x86上这种错误状态得到了纠正。

追踪%ldconfig_scriptlets宏,发现是/sbin/ldconfig -N -r "$RPM_BUILD_ROOT"这个命令,在x86上发挥了作用,在riscv上没起作用。

查看ldconfig的manpage,ldconfig确有修复库版本符号链接功能,即可以补上缺少的版本库符号链接,也能将错误的实体文件修改为符号链接。手动实验,在riscv上,如果相关库文件是存在于/usr/lib64/lp64d目录下,或者/usr/lib64下有个lp64d符号链接,则都可以解决上述问题。

由此判断问题出在系统库目录设置上。浏览ldconfig源代码,在dl-cache.h中查到了系统库目录列表,dl-cache.h - sysdeps/unix/sysv/linux/riscv/dl-cache.h - Glibc source code (glibc-2.36) - Bootlin ,里面确实没有以lib64结尾的目录。

三、如何解决为好

解决上述问题,可采取不同的办法:

  1. 将/usr/lib64或/lib64加入dl-cache的系统库目录列表。这样做是否合适?是否符合RISC-V API设计初衷

  2. 修改%ldconfig_scriptlets宏,在实际进行ldconfig之前,人为地增加上lp64d

  3. 基本构建环境统一提供lp64d这个虚点

RV 系统上应该不存在 32 位和 64位 应用并存的问题吧?为什么还需要 /usr/lib64 ?直接都放 /usr/lib 里面不就好了?

大概与应用程序的要求有关,应用程序可能需要适应多架构,从而要进行32和64的区分

ELF文件头的e_ident指明了ELFCLASS64或32,e_flags指明了EF_RISCV_FLOAT_ABI_DOUBLE等,而且psABI明确描述“e_flags Describes the format of this ELF file. These flags are used by the linker to disallow linking ELF files with incompatible ABIs together”,那为什么glibc还要用lp64d这种目录,仅仅是判别这些字段的效率开销因素?还是即成事实的因素?