共享对象文件中的版本号 我使用GCC从一组C++源文件构建共享对象文件。所有关于构建.so文件的示例教程都显示了在.so后缀后使用版本号创建的文件。例如: gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 calc_mean.o

共享对象文件中的版本号 我使用GCC从一组C++源文件构建共享对象文件。所有关于构建.so文件的示例教程都显示了在.so后缀后使用版本号创建的文件。例如: gcc -shared -Wl,-soname,libmean.so.1 -o libmean.so.1.0.1 calc_mean.o,c++,linux,gcc,compiler-construction,shared-libraries,C++,Linux,Gcc,Compiler Construction,Shared Libraries,这将生成.so文件libmean.so.1.0.1 此外,如果我浏览本地机器上的/usr/lib目录,我会看到许多。因此文件的末尾都有版本号 但是,当我编译一个共享对象文件并将其放入/usr/lib中时,如果我在末尾添加了版本号,链接器将无法找到它。如果我删除了版本号,它可以正常工作。我真的不在乎是否输入版本号,我只是不明白为什么这似乎是一个常见的约定,但这会导致共享库无法与链接器一起工作。那么,这是怎么回事?为什么有一种惯例,将版本号放在文件名的末尾?附加版本号,以便您可以在系统中共存多个不兼

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

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


但是,当我编译一个共享对象文件并将其放入
/usr/lib
中时,如果我在末尾添加了版本号,链接器将无法找到它。如果我删除了版本号,它可以正常工作。我真的不在乎是否输入版本号,我只是不明白为什么这似乎是一个常见的约定,但这会导致共享库无法与链接器一起工作。那么,这是怎么回事?为什么有一种惯例,将版本号放在
文件名的末尾?

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

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

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

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

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
您可以使用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)
它显然找不到,但这就是符号链接的用途:

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)

更新:以上所有内容都是正确的,但我自己并不知道版本号第三部分的含义。直到最近,我还认为它只是一个补丁号(或类似的东西)。错了!因为它有一个特殊的意义

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

建议阅读:


我不太明白你答案中的年龄部分。libtool doc说,“[年龄]是该库实现的最新和最旧接口之间的差异。换句话说,该库实现了从数字current-age到current的所有接口编号。”我认为这是一个更好的解释。“推荐阅读”中的两个链接中的第一个指向Martin Sustrik的博客文章,这篇文章解释得很好。嗯,也许答案确实值得更新,我马上就做。