ldd 程序报告缺少我的共享库所需的一些共享库。 (我在另一台装有 Red Hat Linux 7 的计算机上构建了它,并希望在另一台装有 Red Hat Linux 6 的计算机上运行它。)
在下面的“版本信息”部分中,有 libc.so.6 的三个条目;每个版本后面的括号中都有不同的版本(GLIBC_2.14、GLIBC_2.4 和 GLIBC_2.2.5)。其中第一个没有在计算机上安装关联的共享库。
我是 Linux 新手,不明白如何解释这个输出,更不用说解决问题了。下面是命令和输出。
>ldd -v libAtlasUtilsPB.so
./libAtlasUtilsPB.so: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./libAtlasUtilsPB.so)
./libAtlasUtilsPB.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by ./libAtlasUtilsPB.so)
./libAtlasUtilsPB.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./libAtlasUtilsPB.so)
linux-vdso.so.1 => (0x00007fffa3dff000)
librt.so.1 => /lib64/librt.so.1 (0x00007fea7a7b2000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fea7a4ab000)
libm.so.6 => /lib64/libm.so.6 (0x00007fea7a227000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fea7a011000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fea79df3000)
libc.so.6 => /lib64/libc.so.6 (0x00007fea79a5f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fea7ad17000)
Version information:
./libAtlasUtilsPB.so:
libgcc_s.so.1 (GCC_3.0) => /lib64/libgcc_s.so.1
libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6
libpthread.so.0 (GLIBC_2.2.5) => /lib64/libpthread.so.0
libc.so.6 (GLIBC_2.14) => not found
libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
libstdc++.so.6 (GLIBCXX_3.4.18) => not found
libstdc++.so.6 (GLIBCXX_3.4.15) => not found
libstdc++.so.6 (GLIBCXX_3.4.9) => /usr/lib64/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4.11) => /usr/lib64/libstdc++.so.6
libstdc++.so.6 (CXXABI_1.3) => /usr/lib64/libstdc++.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /usr/lib64/libstdc++.so.6
答案1
ldd
列出其参数所需的共享库。使用该-v
选项,它会列出所有可用信息,包括版本符号。
表格的线条
linux-vdso.so.1 => (0x00007fffa3dff000)
librt.so.1 => /lib64/librt.so.1 (0x00007fea7a7b2000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fea7a4ab000)
列出 所需的库libAtlasUtilsPB.so
以及它们是如何解析的;在你的情况下所有必需的图书馆被发现。linux-vdso.so.1
很特别,它是虚拟图书馆由内核提供。
表格的线条
libgcc_s.so.1 (GCC_3.0) => /lib64/libgcc_s.so.1
libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6
libpthread.so.0 (GLIBC_2.2.5) => /lib64/libpthread.so.0
列出 所需的版本符号libAtlasUtilsPB.so
,以及它们的解析方式。这是ldd
无法解析项目的地方,它通过在此处指示“未找到”并在输出开始时打印错误消息来指示。
GLIBC_...
等GLIBCXX_...
是版本符号,在某些库(包括GNU C库和GCC库)中使用它们来标识所需的版本并管理向后兼容性。二进制文件(可执行文件或库)通常最终需要多个版本,具体取决于它实际使用的目标库中的符号。为了满足给定二进制文件的要求,您需要提供一个支持所有所需版本的库 -IE至少匹配需求列表中最高版本符号的库。
最终可能需要多个版本的原因是每个导入的对象(函数等)都可以有一个版本,并且给定的二进制文件可以链接到它使用的所有函数的多个版本。例如,在我的系统上选择一个具有两个版本的示例/lib/x86_64-linux-gnu/libgcc_s.so.1
,ldd -v
显示
/lib/x86_64-linux-gnu/libgcc_s.so.1:
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
libgcc_s.so.1
需要来自 的两个版本符号libc.so.6
。为了找出原因,我们需要查看它包含的未定义符号 - 这些是它需要导入的符号:
$ objdump -T /lib/x86_64-linux-gnu/libgcc_s.so.1|grep -F '*UND*'
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 dl_iterate_phdr
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 w D *UND* 0000000000000000 __pthread_key_create
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 abort
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strlen
0000000000000000 w D *UND* 0000000000000000 pthread_getspecific
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memset
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 calloc
0000000000000000 w D *UND* 0000000000000000 pthread_key_create
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.14 memcpy
0000000000000000 w D *UND* 0000000000000000 pthread_once
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 pthread_mutex_unlock
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 malloc
0000000000000000 w D *UND* 0000000000000000 pthread_setspecific
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 realloc
0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 pthread_mutex_lock
这列出了许多版本化符号(那些带有GLIBC_2.2.5
或GLIBC_2.14
在倒数第二列中的符号),我们可以在这里看到这些版本与我们看到的ldd
.为什么我们最终会得到多个版本符号?这就是向后兼容性发挥作用的地方。版本 2.2.5 是 GNU C 库中符号版本控制的基线; 2.2.5 版本中存在的任何函数都带有该版本。在 GNU C 库 2.13 版本中, 的行为memcpy
发生了改变;这破坏了许多程序,因此在 2.14 版本中,使用可选版本标签放置了向后兼容的版本GLIBC_2.2.5
,并添加了带有版本标签的新版本GLIBC_2.14
。因此,使用早期版本的 C 库构建的旧二进制文件使用旧版本的memcpy
,而使用 2.14 版及更高版本构建的二进制文件则使用新版本的memcpy
。
同样的故事也适用于libstdc++.so.6
,但随着版本号的更新,有更多的变化;手册libstdc++
提供了详细信息。
在你的情况下,你需要libstdc++.so.6
匹配GLIBCXX_3.4.18
,IEGCC 4.8.0 或更高版本提供的版本以及 GNU C 库的 2.14 版本。
您无法轻松地在 RHEL 7 上构建二进制文件并在 RHEL 6 上运行它们(这就是主要版本不同的原因)。你最好在 RHEL 6 上重建你的程序......