Linux 共享对象文件中的版本号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5760111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:47:37  来源:igfitidea点击:

Version numbers in shared object files

c++linuxgcccompiler-constructionshared-libraries

提问by Channel72

I'm building a shared object file from a group of C++ source files using GCC. All the example tutorials on building .sofiles show the file created with a version number after the .sosuffix. For example:

我正在使用 GCC 从一组 C++ 源文件构建一个共享对象文件。所有关于构建.so文件的示例教程都显示了使用.so后缀后的版本号创建的文件。例如:

gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1  calc_mean.o

This would produce the .sofile libmean.so.1.0.1

这将产生.so文件 libmean.so.1.0.1

Additionally, if I browse the /usr/libdirectory on my local machine, I see that many of the .sofiles have version numbers at the end.

此外,如果我浏览/usr/lib本地计算机上的目录,我会看到许多.so文件的末尾都有版本号。

However, when I compile a shared object file and place it in /usr/lib, the linker is unable to find it if I put a version number at the end. If I remove the version number, it works fine. I really don't care about putting a version number or not, I just don't understand why this seems to be a common convention, and yet this causes the shared library to not work with the linker. So, what's going on here? Why is there a convention to place the version number at the end of an .sofile name?

但是,当我编译共享对象文件并将其/usr/lib放入 . 如果我删除版本号,它工作正常。我真的不在乎是否提供版本号,我只是不明白为什么这似乎是一个常见的约定,但这会导致共享库无法与链接器一起使用。那么,这里发生了什么?为什么有一个约定将版本号放在.so文件名的末尾?

回答by Code Painters

The version number is appended so you can have multiple incompatible library versions coexisting in the system. You should increment the major version number (the number in soname) every time you change the API in an incompatible way (assuming the previous version is installed and used in the system, of course).

附加版本号,以便您可以在系统中共存多个不兼容的库版本。soname每次以不兼容的方式更改 API 时,您都应该增加主版本号( 中的数字)(当然,假设系统中安装并使用了以前的版本)。

The 2nd and 3rd numbers in the file name allows for multiple minor revisions of the library in the system, switchable system-wide with a simple symlink update.

文件名中的第二个和第三个数字允许对系统中的库进行多个次要修订,可通过简单的符号链接更新在系统范围内切换。

At link time you can give the .sofile name as a linker argument, instead of -loption. ldd is smart enough to extract the sonamefrom it, the binary linked this way uses it to find the library.

在链接时,您可以将.so文件名作为链接器参数而不是-l选项提供。ldd 足够聪明,可以从中提取soname,以这种方式链接的二进制文件使用它来查找库。

For example, let's compile the library and test binary using it:

例如,让我们编译库并使用它测试二进制文件:

czajnik@czajnik:~/z$ gcc -shared -Wl,-soname,libtest.so.2 -o libtest.so.2.3.4  a.c 
czajnik@czajnik:~/z$ gcc -o test b.c -L. ./libtest.so.2.3.4

You can use ldd to verify, that the binary now looks for libtest.so.2:

您可以使用 ldd 来验证二进制文件现在正在查找libtest.so.2

czajnik@czajnik:~/z$ LD_LIBRARY_PATH=. ldd ./test
    linux-gate.so.1 =>  (0x002c1000)
    libtest.so.2 => not found
    libc.so.6 => /lib/libc.so.6 (0x00446000)
    /lib/ld-linux.so.2 (0x00a28000)

It obviously can't find it, but that's what the symlink is for:

它显然找不到它,但这就是符号链接的用途:

czajnik@czajnik:~/z$ ln -s libtest.so.2.3.4 libtest.so.2
czajnik@czajnik:~/z$ LD_LIBRARY_PATH=. ldd ./test
    linux-gate.so.1 =>  (0x00d75000)
    libtest.so.2 => ./libtest.so.2 (0x00e31000)
    libc.so.6 => /lib/libc.so.6 (0x00a5e000)
    /lib/ld-linux.so.2 (0x00378000)


Update:All of the above is true, yet I wasn't myself aware of the meaning of the 3rd component of the version number. Until recently, I believed it is simply a patch number (or similar thing). Wrong! For libtoolit has a special meaning.

更新:以上都是真的,但我自己并不知道版本号的第三个组成部分的含义。直到最近,我才相信它只是一个补丁号(或类似的东西)。错误的!对于libtool来说,它具有特殊的意义。

The 3rd component turned out to be agefield, which says how many major versions are backward compatible with the current one.

第三个组件是age字段,它表示有多少主要版本与当前版本向后兼容

Recommended reading:

推荐阅读: