为什么 linux ld 有时使用库的符号 link
Why linux ld somtime use the symbolic link of libs
我在我的 linux cli 工具中使用 jsoncpp 库。
CMakeLists.txt包含
find_library(LIB_JSON jsoncpp)
target_link_libraries(${PROJECT_NAME} ${LIB_JSON})
结果是
/usr/bin/c++ -rdynamic CMakeFiles/cktwagent.dir/agent_main.cpp.o -o cktwagent -ljsoncpp
当我检查我发现的二进制文件时:
$> ldd cktwagent
linux-vdso.so.1 (0x00007ffe4cfd1000)
libjsoncpp.so.24 => /usr/lib/libjsoncpp.so.24 (0x00007f87505bd000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f87503e0000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f875029a000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f8750280000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f87500b7000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f87506ce000)
为什么 ld 使用 /usr/lib/libjsoncpp.so.24 而不是符号 link /usr/lib/libjsoncpp.so?
为什么 ld 有时会将 linbrary link 解析为真正的库文件?
$> ls -l /usr/lib/libjsoncpp.so
lrwxrwxrwx 1 root root 16 26. Sep 17:02 /usr/lib/libjsoncpp.so -> libjsoncpp.so.24
在 /usr/lib/libstdc++.so.6 的情况下,ld 使用符号 link。当我检查 ldd 输出的路径时,libstdc++.so.6 指向一个符号 link.
$> ls -l /usr/lib/libstdc++.so.6
lrwxrwxrwx 1 root root 19 9. Nov 12:43 /usr/lib/libstdc++.so.6 -> libstdc++.so.6.0.28
我喜欢理解这种行为。因为当我将二进制文件复制到不同的系统时,link 到 libjsoncpp.so 可用。但它指向一些不同的版本。
非常感谢
托马斯
这是一个版本兼容性功能。按照惯例,API 兼容性由主版本号决定。所以 6.0.28
与 6.1.1
兼容,但与 5.0.1
或 7.0.1
.
不兼容
为了兼容升级,libstdc++.so.6.0.28
被符号link编辑为 libstdc++.so.6
。然后它可以二进制升级到例如libstdc++.so.6.0.29
不接触依赖 libstdc++
的 API 版本 6
的应用程序。
此外,它允许具有不同主版本号的库在同一系统中共存。安装 libstdc++.so.7.0.0
不会破坏 link 针对 libstdc++.so.6
的应用程序。
Why ld use /usr/lib/libjsoncpp.so.24
and not the symbolic link /usr/lib/libjsoncpp.so
?
那是因为 libjsoncpp
的 soname 为 libjsoncpp.so.24
。显然它遵循让主版本号确定兼容性的相同约定。
如果您 link 像这样
,您可以使用共享库 libfoo
实现相同的行为:
gcc -shared -Wl,-soname,libfoo.so.<major> -o libfoo.so.<major>.<minor>
有关详细信息,请参阅 GCC Howto - Version numbering, sonames and symlinks。
我在我的 linux cli 工具中使用 jsoncpp 库。
CMakeLists.txt包含
find_library(LIB_JSON jsoncpp)
target_link_libraries(${PROJECT_NAME} ${LIB_JSON})
结果是
/usr/bin/c++ -rdynamic CMakeFiles/cktwagent.dir/agent_main.cpp.o -o cktwagent -ljsoncpp
当我检查我发现的二进制文件时:
$> ldd cktwagent
linux-vdso.so.1 (0x00007ffe4cfd1000)
libjsoncpp.so.24 => /usr/lib/libjsoncpp.so.24 (0x00007f87505bd000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f87503e0000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f875029a000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f8750280000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f87500b7000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f87506ce000)
为什么 ld 使用 /usr/lib/libjsoncpp.so.24 而不是符号 link /usr/lib/libjsoncpp.so?
为什么 ld 有时会将 linbrary link 解析为真正的库文件?
$> ls -l /usr/lib/libjsoncpp.so
lrwxrwxrwx 1 root root 16 26. Sep 17:02 /usr/lib/libjsoncpp.so -> libjsoncpp.so.24
在 /usr/lib/libstdc++.so.6 的情况下,ld 使用符号 link。当我检查 ldd 输出的路径时,libstdc++.so.6 指向一个符号 link.
$> ls -l /usr/lib/libstdc++.so.6
lrwxrwxrwx 1 root root 19 9. Nov 12:43 /usr/lib/libstdc++.so.6 -> libstdc++.so.6.0.28
我喜欢理解这种行为。因为当我将二进制文件复制到不同的系统时,link 到 libjsoncpp.so 可用。但它指向一些不同的版本。
非常感谢
托马斯
这是一个版本兼容性功能。按照惯例,API 兼容性由主版本号决定。所以 6.0.28
与 6.1.1
兼容,但与 5.0.1
或 7.0.1
.
为了兼容升级,libstdc++.so.6.0.28
被符号link编辑为 libstdc++.so.6
。然后它可以二进制升级到例如libstdc++.so.6.0.29
不接触依赖 libstdc++
的 API 版本 6
的应用程序。
此外,它允许具有不同主版本号的库在同一系统中共存。安装 libstdc++.so.7.0.0
不会破坏 link 针对 libstdc++.so.6
的应用程序。
Why ld use
/usr/lib/libjsoncpp.so.24
and not the symbolic link/usr/lib/libjsoncpp.so
?
那是因为 libjsoncpp
的 soname 为 libjsoncpp.so.24
。显然它遵循让主版本号确定兼容性的相同约定。
如果您 link 像这样
,您可以使用共享库libfoo
实现相同的行为:
gcc -shared -Wl,-soname,libfoo.so.<major> -o libfoo.so.<major>.<minor>
有关详细信息,请参阅 GCC Howto - Version numbering, sonames and symlinks。