GCC链接不存在的库:为何出现重复缺失的ICU库?
技术问题
将两个库共同链接是否会生成引用了不存在第三方库的程序?本地测试需确保已安装ICU和g++。
输出结果
ldd out1: linux-vdso.so.1 (0x00007ffd5cdaf000) liblcf.so.0 => /home/aleck099/.local/lib/liblcf.so.0 (0x00007ff200600000) libicuuc.so.72 => /usr/lib/libicuuc.so.72 (0x00007ff200200000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007ff1ffe00000) libm.so.6 => /usr/lib/libm.so.6 (0x00007ff200518000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007ff2008a1000) libc.so.6 => /usr/lib/libc.so.6 (0x00007ff1ffc19000) libicui18n.so.71 => not found libicuuc.so.71 => not found libicudata.so.71 => not found libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007ff200874000) libicudata.so.72 => /usr/lib/libicudata.so.72 (0x00007ff1fde00000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007ff2008ea000) ldd out2: linux-vdso.so.1 (0x00007ffdfed78000) libicui18n.so.72 => /usr/lib/libicui18n.so.72 (0x00007fa088000000) libicuuc.so.72 => /usr/lib/libicuuc.so.72 (0x00007fa087c00000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fa087800000) libm.so.6 => /usr/lib/libm.so.6 (0x00007fa08834d000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fa087fe0000) libc.so.6 => /usr/lib/libc.so.6 (0x00007fa087619000) libicudata.so.72 => /usr/lib/libicudata.so.72 (0x00007fa085800000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fa08845e000)
从out1的ldd输出可见,有三个库显示“not found”,且这些库是系统已存在的ICU库的重复版本(71版,系统已安装72版)。请问该异常情况为何会发生?
补充信息
- 使用clang和gcc编译均出现相同结果
liblcf.so由easyrpg编译生成
问题解答
这个异常的核心是动态库的依赖传递与版本兼容性问题,具体原因拆解如下:
liblcf.so的依赖版本固化liblcf.so在编译时链接的是ICU 71版本,因此它的动态依赖列表中会被写入带版本后缀的库名:libicui18n.so.71、libicuuc.so.71、libicudata.so.71。ICU的版本后缀对应不同的ABI(应用二进制接口),不同版本的ABI不兼容,无法用高版本库替代低版本,反之亦然。链接器的依赖合并逻辑
当你把liblcf.so和系统的ICU 72库共同链接生成out1时,链接器会收集所有直接依赖和间接依赖:
- 直接依赖:你显式指定的ICU 72系列库
- 间接依赖:
liblcf.so自带的ICU 71系列库
链接器不会自动识别同库的不同版本并去重,而是将所有依赖都写入最终可执行文件的动态段,导致同一库的不同版本同时出现在依赖列表中。
- 运行时动态加载器的查找行为
系统中仅安装了ICU 72,没有71版本,所以ldd检查时,动态加载器找不到对应的71版库文件,就会显示“not found”。而out2只直接链接了ICU 72,没有引入liblcf.so的旧版本依赖,因此所有库都能正常定位。
验证方式
执行objdump -x liblcf.so.0 | grep NEEDED,可以直接查看liblcf.so的依赖列表,会确认它确实依赖ICU 71版本的库。
解决方案
- 重新编译
liblcf.so,让它链接系统当前的ICU 72版本,从根源上消除版本不匹配的依赖; - 若必须保留
liblcf.so的现有版本,可安装ICU 71到系统中,但这种方法可能引发其他程序的版本冲突,不推荐。
内容的提问来源于stack exchange,提问作者aleck099
相关产品推荐
相关产品推荐

