温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

unix平台动态连接库的管理是什么

发布时间:2021-11-09 09:44:35 来源:亿速云 阅读:131 作者:柒染 栏目:建站服务器

这篇文章给大家介绍unix平台动态连接库的管理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

    世界上唯一不变的是变化,对于动态连接库更是如此。动态库天生为方便程序的更新而设计,只需要替代库文件,无需重新编译主程序,即可运行更新后的版本。另外,动态库是多应用共享的,多个程序使用同一个库,那么库只会加载一份。
    但是,现实往往不这么简单。既然动态库有新版本,那就会有与旧版本兼容或者不兼容的情况出现。当系统里存在多个使用此动态库的应用程序时,如果是兼容旧版本的更新还好,如果是不兼容,那么使用旧版本的应用程序就会受影响不能正常运行。特别的,当动态库集中放在系统指定的库目录下时(windows的system32),版本的冲突就形成了著名的“windows dll hell”。

    为了解决这个问题,很多UNIX系统使用了ELF格式的DT_SONAME字段来应对。例如,linux的ld命令中,就有这么一个选项。
       -h name
       -soname=name
           When creating an ELF shared object, set the internal DT_SONAME
           field to the specified name.  When an executable is linked with a
           shared object which has a DT_SONAME field, then when the executable
           is run the dynamic linker will attempt to load the shared object
           specified by the DT_SONAME field rather than the using the file
           name given to the linker.
    表示使用-h或者-soname选项,可以在动态库里指定DT_SONAME字段,保存运行时查找的动态库名字,使得编译时和运行时动态库名可以不同。例如,编译libwel.so时使用-soname=libwel.so.1,那么编译可执行程序时-lwel,连接libwel.so,会记录运行时在搜索路径查找libwel.so.1加载。

    ELF是一种应用非常广泛的二进制目标格式,与之类似的,UNIX的二进制目标还有a.out格式(SCO UNIX),XCOFF格式(AIX)。这两种格式就无法支持soname了。

    那么,如何使多个版本的动态连接库同时支持呢,总结一下使用这种命名方式既可以新旧不兼容版本共存,又可以兼容版本正常升级。动态库命名为libxxx.so.n.m,soname名为libxxx.so.n,建立软连接libxxx.so指向最新的n版本libxxx.so.n供编译可执行程序使用,建立软连接libxxx.so.n指向版本n最新的m版本。这样,n的变化表示不兼容旧版本的改动,相同n下m的变化表示兼容n版本的改动。
    还是以libwel.so举例。1.0版本的wel.c提供的函数void welcome(void) { printf("aaa\n"); },编译成库libwel.so.1.0,soname为libwel.so.1。建立软连接libwel.so.1,libwel.so。使用1.0库的主程序main1.c调用welcome(),编译成main1程序。1.1版本的wel.c改成void welcome(void) { printf("bbb\n"); },动态库只修改内部实现,对外接口兼容1.0版本,编译成库libwel.so.1.1。此时更新软连接libwel.so.1为libwel.so.1.1,主程序main1无需变动,即可输出更新后的bbb。2.0版本的wel.c改变了对外接口,提供的函数void welcome(char *p) { printf("%s\n",p); }。编译成库libwel.so.2.0,soname为libwel.so.2。建立软连接libwel.so.2,libwel.so。使用2.0库的主程序main2.c应以一个参数调用welcome("test")。main1和main2主程序互不兼容,必须分别调用版本1和版本2的库。此时,库目录下存在libwel.so.1指向1.1版本,libwel.so.2指向2.0版本,main1会连接1.1版本运行,main2会连接2.0版本运行。由此可见,小版本升级时应用程序自动使用最新版本,大版本升级时,使用旧版本的“过时”应用程序不受影响,从而避免了动态库版本的混乱。

    同样,以link方式为例,给出各UNIX平台加设soname的动态库编译方法。(AIX不支持)

 linux:
  编译libwel.so:
   gcc -fPIC -shared -Wl,-soname,libwel.so.1 -o libwel.so.1.0 wel.c -lc
   ln -sf libwel.so.1.0 libwel.so.1
   ln -sf libwel.so.1 libwel.so
    -Wl,-soname,libwel.so.1 指定libwel.so.1.0的实际soname为libwel.so.1

 sco unix open server:
  编译libwel.so:
   cc -K pic -G -h libwel.so.1 -o libwel.so.1.0 wel.c -lc
   ln -sf libwel.so.1.0 libwel.so.1
   ln -sf libwel.so.1 libwel.so
    -h libwel.so.1 指定libwel.so.1.0的实际soname为libwel.so.1

 HP UX:
  编译libwel.so:
   cc +z -c wel.c
   ld -b -o libwel.sl.1.0 wel.o +h libwel.sl.1 -lc
   ln -sf libwel.sl.1.0 libwel.sl.1
   ln -sf libwel.sl.1 libwel.sl
    +h libwel.sl.1 指定libwel.sl.1.0的实际soname为libwel.sl.1

 SUN OS:
  编译libwel.so:
   cc -G -h libwel.so.1 -o libwel.so.1.0 wel.c -lc
   ln -sf libwel.so.1.0 libwel.so.1
   ln -sf libwel.so.1 libwel.so
    -h libwel.so.1 指定libwel.so.1.0的实际soname为libwel.so.1

关于unix平台动态连接库的管理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI