[OS] Linux共享库的组织
由于动态链接的诸多优点,大量的程序开始使用动态链接机制,导致系统里面存在数量极为庞大的共享对象。如果没有很好的方法将这些共享对象组织起来,整个系统中的共享对象文件则会散落在各个目录下,给长期维护、升级造成了很大的问题。所以操作系统一般会对共享对象的目录组织和使用方法有一定的规则。
共享库的开发者会不停的更改共享库的版本,以修正原有的Bug,增加新的功能或改进性能等。由于动态链接的灵活性,使得程序本身和程序所依赖的共享库可以分别独立开发和更新,但是共享库版本的更新可能会导致接口的更改或删除,这可能导致依赖于该共享库的程序无法正常运行。
既然共享库存在兼容性问题,那么保持共享库在系统中的兼容性,保证依赖于它们的应用程序能够正常运行时必须要解决的问题。有几种方法可用于解决共享库的兼容性问题,有效办法之一就是使用共享库版本的方法。
Linux有一套规则来命名系统中的每一个共享库,它规定共享库的文件名规则必须如下:libname.so.x.y.z
。其中,lib
是前缀,name
是库的名字,.so
是后缀,最后跟着的三个数字组成版本号。x
表示主版本号(Major Version Number),y
表示次版本号(Minor Version Number),z
表示发布版本号(Release Version Number)。主版本号表示不兼容的升级,次版本号表示增量升级,发布版本号表示修正错误或性能改进等更新。
既然相同主版本号的共享库是兼容的,那么确定依赖关系时,只需要维护共享库的名字和主版本号即可,这就是共享库的SO-NAME
。例如,libname.so.x.y.z
的SO-NAME
就是libname.so.x
。系统会为每个共享库在它所在的目录创建一个跟它的SO-NAME
相同且指向它的软链接(Symbol Link),这个软链接会指向目录中主版本号相同,但是次版本号和发布版本号最新的共享库。这样依赖某个共享库的模块,在编译、链接和运行时,都可以使用共享库的SO-NAME
,而不必使用详细的版本号了。