The shared library soname

来源:互联网 发布:linux创建用户指定组 编辑:程序博客网 时间:2024/06/08 06:27
下面引用一段英文原文

The shared library soname

In the earlier example, we embedded the actual name(the realname) of the shared library in an executablefile.

It is possible to createan alias, calledthe soname, which willbe embedded in an executable file insteadof the realname

At run-time, the dynamic linker will usethe soname when searching forthe library. 

The purpose of the soname is to provide a levelof indirection.

  • At run-time, executable can use aversion of the shared library that is different (but compatible)from that against which it was linked.

    The sharedlibrary soname (cont.)

    Here's how to use a soname:

    1. Specify soname when creating sharedlibrary:
      $ gcc -fPIC -c -Wall -g mod1.c mod2.c mod3.c $ gcc -shared -Wl,-soname,libbar.so -o libfoo.so \           mod1.o mod2.o mod3.o 
      -Wl,-soname,libbar.so instructslinker to mark the shared library libfoo.so withthe soname libbar.so.
    2. Create executable:


      $ gcc -g -Wall -o prog prog.c libfoo.so 
      Linker detects that libfoo.so containsthe soname libbar.so andembeds the latter name inside the executable.
    3. Run the program:
      $ LD_LIBRARY_PATH=. ./prog ./prog: error in loading shared libraries: libbar.so: cannot open shared object file: No such file or directory
      Dynamic linker cannot find anythingnamed libbar.so.
    4. Create a symbolic link fromthe soname tothe realname of the library:
      $ ln -s libfoo.so libbar.so $ LD_LIBRARY_PATH=. ./prog Called mod1-x1Called mod2-x2

    At run-time this link can point to a version of the librarywhich is different from the version against which linking wasperformed

    The sharedlibrary soname (cont.)

    This diagram shows the steps required in building a shared library,linking a program against it, and creating the requiredsoname symbolic link.

    The <wbr>shared <wbr>library <wbr>soname 

    The sharedlibrary soname (cont.)

    This diagram shows the steps that occur as the program isexecuted:

    The <wbr>shared <wbr>library <wbr>soname 

    Compatible Versus Incompatible Libraries

    We probably need to change a library overtime.

    A new library version is said tobe compatible withan existing library version if all of the followingconditions hold true:

    • The semantics of each functionin the library remain unchanged

      • All functions continue to produce sameeffect on global variables and returnedarguments

      • All functions continue to returnthe same resultvalues

      • Performance improvements and bug fixes (perhaps resulting incloser conformance to specifiedbehavior) are compatiblechanges. 

    • No function in the library APIis removed.
      New functions can be added.
    • The structures exported (i.e.allocated within and returned) by each function remainunchanged.
      Possible exception: new items may be added to the endof the existing structure

    If any of these conditions is violated, then the new libraryversionis incompatible withthe previous version.



    Shared library versions and naming

    • If a new version of a shared libraryis compatible withan existing library, we can make anew minorversion of thelibrary. 

    • If a new version of a shared libraryis incompatible withan existing library, we must make anew majorversion of thelibrary. 

    • Constraint: it must bepossible to continue running programs requiring the older versionof the library. 

    • Solution:a namingconvention is used for sharedlibrary realnames and sonames.

    Shared library versions and naming (cont.)

    Real name

    Name of the file containing library code.

    Format: libname.so.major-id.minor-id

    • Major versionidentifier is a number which issequentially incremented with each incompatible release of thelibrary. 

    • Minor versionidentifier distinguishes differentcompatible minor versions of a library within the same majorversion.
      Usually either a number, or two numbers separated by adot, with first number identifying minorversion, and second number indicating a patch levelor revisionnumber within the minorversion.

    Examples:

    libdemo.so.1.0.1libdemo.so.1.0.2libdemo.so.2.0.1libreadline.so.4.0

    Shared library versions and naming (cont.)

    soname

    Format: libname.so.major-id

    soname includesthe same major versionidentifier as corresponding real name,but does not include minorversionidentifier. 

    Purpose: run-time loading is dependent only on majorversion number of the library 

    soname is createdas a symboliclink (usually in same directoryas real name).

    • The soname for each majorlibrary version points to most recent minorversion

    • Since it isthe soname (notthe real name)that is embedded in executable by linker: 

      1. At any time, we canchange soname symbolic link topoint to a newer minor version

      2. Different major versions canco-exist and be accessed by the programsthat require them.

    Examples of sonames (along with the realnames to which they might be symbolically linked):

    libdemo.so.1        -> libdemo.so.1.0.2libdemo.so.2        -> libdemo.so.2.0.1libreadline.so.4    -> libreadline.so.4.0

    Shared library versions and naming (cont.)

    Linker name

    • Format: libname.so 

    • Purpose: allows usto construct version-independent linkcommands which automatically operate withthe right (i.e. most up to date) version of the sharedlibrary. 

    • Created asa symboliclink toeither realname or soname of most recent majorversion of the library. 

    • More convenient to have it pointto sonameWhy? 

    • Examples:
      libdemo.so           -> libdemo.so.2libreadline.so       -> libreadline.so.4

    Shared library versions and naming (cont.)

    Relationships between shared library names

    The <wbr>shared <wbr>library <wbr>soname

    Creating Shared Libraries Using Standard Naming Conventions

    We can create a shared library using standard naming conventions asfollows:

    1. Create the shared librarywith realname libdemo.so.1.0.1 and soname libdemo.so.1.
      $ gcc -fPIC -g -c -Wall mod1.c mod2.c mod3.c $ gcc -shared -Wl,-soname,libdemo.so.1 -o libdemo.so.1.0.1 \          mod1.o mod2.o mod3.o 
    2. Create symbolic links forthe soname and linkername:
      $ ln -s libdemo.so.1.0.1 libdemo.so.1 $ ln -s libdemo.so.1 libdemo.so $ ls -l libdemo.so* | cut -c 1-11,55- # Verify the setup lrwxrwxrwx  libdemo.so -> libdemo.so.1lrwxrwxrwx  libdemo.so.1 -> libdemo.so.1.0.1-rwxr-xr-x  libdemo.so.1.0.1
    3. Build executable usingthe linker name:
      $ gcc -g -Wall -o ./prog prog.c -L. -ldemo 
    4. Run the program as usual:
      $ LD_LIBRARY_PATH=. ./prog Called mod1-x1Called mod2-x2

    Installing Shared Libraries

    • Production applications should notrequire the user to set LD_LIBRARY_PATH

    • Privileged userscan install a shared library in one of thestandard library directories

      • /usr/lib -directory in which most standardlibraries areinstalled 

      • /lib -directory containing libraries requiredduring system startup 

      • /usr/local/lib non-standardor experimental libraries should beinstalled here;
        Also useful if /usr/lib isa network mount shared among multiple systems, and we want toinstall a library locally.
      or in one of the directories listedin /etc/ld.so.conf.【注:linux版本如有“/etc/ld.so.conf.d目录”也可以将my.conf这样的配置文件放在/etc/ld.so.conf.d目录下, my.conf的内容格式为/ldddir/dir】 

    • After installation, symbolic linksfor soname and linkername must be created, as relative links inthe same directory.

    ldconfig(8)

    ldconfig(8) addressestwo potential problems with shared libraries:

    1. Speed: Sharedlibraries can reside in many different directories:it could take the dynamic linker a longtime to search them

    2. Manuallykeeping sonames symlinks up to dateis error-prone as new versions oflibraries are installed, or old versions are removed.

    ldconfig solvesthese problems by:

    1. Creating a cache file:
      ldconfig searchesfor latest major libraryversions in: 

      • all of the directories specifiedin /etc/ld.so.conf
      • /lib
      • /usr/lib

      and updates a cachefile, /etc/ld.so.cache,to contain a list of the latest major library versions, and theirlocations.
      Cache file is used by dynamic linker atrun-time when resolving librarynames. 

    2. Automating the creationof sonames

      • ldconfig examines(the latest minor version of) each major version of each library tofind the embedded soname, and 

      • creates a relative symbolic link forthis soname, inthe same directory as the library. 

    In order to work properly, ldconfig relieson the use of the standard naming convention for shared libraries(i.e.,libname.maj.min) 


    ldconfig(8) (cont.)

    Example - installing two different major versions of alibrary.

    We copy both versions into /usr/lib:

    # mv libdemo.so.1.0.1 libdemo.so.2.0.1 /usr/lib # cd /usr/lib 

    We run ldconfig toupdate the dynamic linker cache:

    # ldconfig -v | grep libdemo libdemo.so.1 -> libdemo.so.1.0.1 (changed)        libdemo.so.2 -> libdemo.so.2.0.1 (changed)
    • (We use grep toeliminate other output from ldconfig.)

    Then we manually create the linker name:

    # ln -s libdemo.so.2 libdemo.so 


    To install a new 2.x minor version:

    # mv libdemo.so.2.0.2 /usr/lib # cd /usr/lib # ldconfig -v | grep libdemo libdemo.so.1 -> libdemo.so.1.0.1        libdemo.so.2 -> libdemo.so.2.0.2 (changed)

    The ldconfig command effectivelyalso updates linker name...


    ldconfig(8) (cont.)

    • ldconfig shouldbe run whenever a new library isinstalled oran existing library is updated orremoved

    • ldconfig-p shows the current contents of thecache. 


    Upgrading Shared Libraries

    Note: A new major or minorversion of a library can be installed, even while running programsare making use of an existing version.

    Example - upgrading a shared library with a new minorversion (1.0.2):

    # gcc -fPIC -g -c -Wall mod1.c mod2.c mod3.c # gcc -shared -Wl,-soname,libdemo.so.1 -o libdemo.so.1.0.2 \        mod1.o mod2.o mod3.o # mv libdemo.so.1.0.2 /usr/lib # ldconfig -v | grep libdemo libdemo.so.1 -> libdemo.so.1.0.2 (changed)

    Assuming the linkername was already correctly set up, we do notneed to modify it.

    Then upgrading to a new major version (2.0.1):

    # gcc -fPIC -g -c -Wall mod1.c mod2.c mod3.c # gcc -shared -Wl,-soname,libdemo.so.2 -o libdemo.so.2.0.1 \        mod1.o mod2.o mod3.o # mv libdemo.so.2.0.1 /usr/lib # ldconfig -v | grep libdemo libdemo.so.1 -> libdemo.so.1.0.2        libdemo.so.2 -> libdemo.so.2.0.1 (changed)      # cd /usr/lib # ln -sf libdemo.so.2 libdemo.so 

    ldconfig automaticallycreates a soname symbolic link, but wemust manually update the linker name symboliclink. 


    Finding Shared Libraries at Run-time

    The dynamic linker searches for shared libraries in the followingorder:

    1. If LD_LIBRARY_PATH isdefined, then each of the colon-separated directories listed in itsvalue is searched in turn. 

    2. /etc/ld.so.cache ischecked to see if it contains an entry for thelibrary. 

    3. /lib and /usr/lib aresearched (in that order).


    英文通俗易懂,大致总结一下:
    1.gcc编译编译选项-soname为实际库文件(libsoname.so.major.minor)生成的别名,这个别名libname.so.major,别名存放在实际库文件的头部,执行readelf-d libsoname.so.major.minor命令可以看到“0x0000000e(SONAME)                  Library soname: [libname.so.major]”

    2.执行ldconfig -n /current_dir命令,ldconfig会去读取/current_dir目录下所有动态库文件中(SONAME)信息,并生成指向各动态库文件的链接文件,链接文件的名字为相应(SONAME)字段值(libname.so.major)。

    3.如果/current_dir被加入到/etc/ld.so.conf或/etc/ld.so.conf.d/中,则执行ldconfig-v命令可生成/current_dir目录下所有的SONAME链接文件并查看繁多的链接信息。

    4.连接器(linker)通过SONAME字段值(libname.so.major)在用户指定的路径查找链接libname.so.major

    5.手动指定libname.so--> libname.so.major,控制程序(progam)链接的实际库文件(libsoname.so.major.minor),在/current_dir目录下我们会看到形如,
    libname.so --> libname.so.major
    libname.so.major--> libname.so.major.minor
    的链接,其中仅
    libname.so.major.minor为规则文件。

    6.动态库的主、次版本号利用如下的一套约定即可实现动态库的版本管理。
    a.新生成库实际文件libname.so.major.minor,当
    库中函数接口未变化(更新不影响相关模块)主版本号major不改变,次版本号   minor加1。
    b.库中函数接口变化(更新影响相关模块)主版本号major加1,次版本号从0开始增加。
    c.当出现新旧版本共存情况
        libname.so.1--> libname.so.1.2
        libname.so.2--> libname.so.2.0
    时需用户通过手动建立链接(libname.so链接libname.so.1还是libname.so.2),决定程序链接动态库。

    7.实际项目中可通过Makefile文件管理项目的动态库版本,具体实施过程待实践。

0 0
原创粉丝点击