Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有人能解释一下Linux库的命名吗?_C++_Linux_Shared Libraries - Fatal编程技术网

C++ 有人能解释一下Linux库的命名吗?

C++ 有人能解释一下Linux库的命名吗?,c++,linux,shared-libraries,C++,Linux,Shared Libraries,在Linux上创建库时,我使用以下方法: 构建:libhelloworld.so.1.0.0 链接:libhelloworld.so.1.0.0 libhelloworld.so 链接:libhelloworld.so.1.0.0 libhelloworld.so.1 版本控制是这样的,如果您更改面向公共的方法,您可以构建libhelloworld.so.2.0.0(并保留1.0.0),这样使用旧库的应用程序就不会中断 但是,将其命名为1.0.0有什么意义?为什么不坚持使用libhellowor

在Linux上创建库时,我使用以下方法:

  • 构建:libhelloworld.so.1.0.0
  • 链接:libhelloworld.so.1.0.0 libhelloworld.so
  • 链接:libhelloworld.so.1.0.0 libhelloworld.so.1
  • 版本控制是这样的,如果您更改面向公共的方法,您可以构建libhelloworld.so.2.0.0(并保留1.0.0),这样使用旧库的应用程序就不会中断

    但是,将其命名为1.0.0有什么意义?为什么不坚持使用libhelloworld.so和libhelloworld.so.1呢

    同样,最佳做法是使用1.0.0(例如)命名库,还是仅使用1

    g++ ... -Wl,-soname,libhelloworld.1
    
    或:


    这种方法的主要优点是可以方便地让用户知道他们拥有的库的哪个版本。例如,如果我知道我得到的一个bug在1.0.4中得到了修复,我可以很容易地检查我链接的库的哪个版本,并知道这是否是修复bug的正确方法


    该数字被称为“共享对象版本”或“soversion”,是ELF二进制标准的一部分。IBM对ELF at有很好的概述。

    您构建x.y.z版本的方式如下:

  • 第一个数字(x)是库的接口版本。每当您更改公共接口时,这个数字就会增加
  • 第二个数字(y)是当前接口的修订号。每当您在不更改公共接口的情况下进行内部更改时,该数字就会上升
  • 第三个数字(z)是而不是构建编号,它是向后兼容计数。这将告诉您支持多少个以前的接口。例如,如果接口版本4严格来说是接口3和接口2的超集,但与1完全不兼容,那么z=2(4-2=2,支持的最低接口号)

  • 因此,x和z数字对于系统非常重要,可以确定给定的应用程序是否可以使用给定的库,给定应用程序的编译依据。y编号主要用于跟踪错误修复。

    来自我发送给同事的关于此问题的旧电子邮件:

    让我们以libxml为例。首先,分享 对象存储在/usr/lib中,并带有一系列符号链接来表示 图书馆的版本如下:

    lrwxrwxrwx 1 root root     16 Apr  4  2002 libxml.so -> libxml.so.1.8.14
    lrwxrwxrwx 1 root root     16 Apr  4  2002 libxml.so.1 -> libxml.so.1.8.14
    -rwxr-xr-x 1 root root 498438 Aug 13  2001 libxml.so.1.8.14
    
    如果我是libxml的作者,并且我提出了一个新版本,libxml 2.0.0,它破坏了与以前版本的接口兼容性,I 可以将其安装为libxml.so.2和libxml.so.2.0.0。请注意,它是 由应用程序程序员负责他链接的内容 到如果我真的是肛门,我可以直接链接到libxml.so.1.8.14和 任何其他版本都会导致我的程序无法运行。或者我可以 链接libxml.so.1,希望libxml开发人员不要 在1.X版本中破坏我的符号兼容性。或者如果你没有 如果你很在意,那么就直接链接到libxml.so,然后获取任何版本 有。有时,当足够多的人这样做时,图书馆的作者 必须对更高版本进行创新。因此,libxml2:

    lrwxrwxrwx 1 root root     17 Apr  4  2002 libxml2.so.2 -> libxml2.so.2.4.10
    -rwxr-xr-x 1 root root 692727 Nov 13  2001 libxml2.so.2.4.10
    
    请注意,在本例中没有libxml2.so。看起来像是开发商
    厌倦了不负责任的应用程序开发人员。

    有几种方法来命名lib:

  • Solaris样式:.so->.so.1
  • GNU样式:.so->.so.1->.so.1.2.3
  • 随机:.so->.so.1.2
  • 见:

    http://www.gnu.org/software/libtool/manual/libtool.html#Versioning

    库命名约定 根据,我们有
    实名
    soname
    链接器名

      Real name  libfoo.so.1.2.3
         Soname  libfoo.so.1
    Linker name  libfoo.so
    
    实名
    是包含实际库代码的文件名。
    soname
    通常是指向
    real name
    的符号链接,当接口以不兼容的方式更改时,其数量会增加。最后,
    链接器名称
    是链接器在请求库时使用的名称,它是没有任何版本号的soname

    因此,要先回答最后一个问题,您应该使用
    soname
    libhelloworld.So.1
    ,作为链接器选项:

    Kerrisk提供了一个非常简短的示例,介绍了如何使用标准命名约定创建共享库。如果您想了解更多关于Linux库的信息,我认为和都非常值得一读

    图书馆编号惯例 关于库的
    实名
    中每个数字的意图和用途,存在一些混淆。我个人认为,在解释每一个数字何时应该递增的规则方面,这个方法做得很好

    简而言之,版本号可以看作是
    libfoo.MAJOR.MINOR.PATCH

    • 补丁
      对于向前和向后兼容其他版本的更改都会递增
    • 如果库的新版本与旧版本的源代码和二进制代码兼容,则应增加
      MINOR
      。不同的次要版本彼此向后兼容,但不一定向前兼容
    • MAJOR
      在引入破坏API的更改或与以前版本不兼容的更改时递增
    这意味着,
    PATCH
    版本可能只在内部有所不同,例如在功能的实现方式上。不允许更改API、公共函数的签名或函数参数的解释

    新的
    MINOR
    版本可能会引入新函数或常量,并弃用现有函数,但可能不会删除任何外部公开的内容。这确保了向后兼容性。换句话说,次要版本
    1.12.3
    可用于替换任何其他
    1.12.x
    或早期版本,如
    1.11.2
    1.5.0
    。但是,它并不是
    1.16.1
    的替代品,因为
      Real name  libfoo.so.1.2.3
         Soname  libfoo.so.1
    Linker name  libfoo.so
    
    g++ ... -Wl,-soname,libhelloworld.so.1 ...