当前位置: 技术问答>linux和unix
创建共享库文件(.so)版本冲突问题如何解决
来源: 互联网 发布时间:2015-05-24
本文导语: 将一部分函数代码通过-fPIC和-shared参数编译为libxxx.so共享库,然后使用-lxxx参数来编译链接调用这些库函数的执行文件,使用正常。 现在libxxx.so有了更新,增加了新的函数,如果简单的覆盖旧so文件会造成原先编译链...
将一部分函数代码通过-fPIC和-shared参数编译为libxxx.so共享库,然后使用-lxxx参数来编译链接调用这些库函数的执行文件,使用正常。
现在libxxx.so有了更新,增加了新的函数,如果简单的覆盖旧so文件会造成原先编译链接的执行文件运行错误,于是将新的libxxx.so命名为libxxx.so.2,那么怎么才能做到现在新编译的执行文件使用libxxx.so.2,原先编译的旧执行文件仍然继续使用libxxx.so?在不需要重新编译原有执行文件的前提下。
现在libxxx.so有了更新,增加了新的函数,如果简单的覆盖旧so文件会造成原先编译链接的执行文件运行错误,于是将新的libxxx.so命名为libxxx.so.2,那么怎么才能做到现在新编译的执行文件使用libxxx.so.2,原先编译的旧执行文件仍然继续使用libxxx.so?在不需要重新编译原有执行文件的前提下。
|
1、是要重新编译。同名so没有用,重要的是使用的那个,其它的是摆设。soname选项不是解决你的问题的。
2、升级gcc与更新libc是完全不同的两个问题。更新libc,如果其接口修改了,应用也一样要重新编译。
3、用-2的方式与换个库名称没有区别,不如用新名字,避免混淆。
2、升级gcc与更新libc是完全不同的两个问题。更新libc,如果其接口修改了,应用也一样要重新编译。
3、用-2的方式与换个库名称没有区别,不如用新名字,避免混淆。
|
这就是ldconfig的作用了,他会生成ld.so.conf对应的路径下的最新版本的库的符号连接到/usr/lib下,供你使用,这个符号连接的名字就是编译时soname所给的名字。可执行文件在连接so时要查看ld.so.cache动态依赖来决定连接的库文件。
你需要做的是
编译时使用-soname为动态库内部添加soname,如-soname libxxx.so.2 -o libxxx.so
添加你的库路径到/etc/ld.so.conf里,然后ldconfig.这样做会在/usr/lib下生成名为libxxx.so.2的符号连接,并且更新动态库依赖缓存。
然后编译客户程序时使用 -lxxx.so.2
你需要做的是
编译时使用-soname为动态库内部添加soname,如-soname libxxx.so.2 -o libxxx.so
添加你的库路径到/etc/ld.so.conf里,然后ldconfig.这样做会在/usr/lib下生成名为libxxx.so.2的符号连接,并且更新动态库依赖缓存。
然后编译客户程序时使用 -lxxx.so.2
|
编译时加 -soname 这就是调用时使用的库名。
|
可以用LD_LIBRARY_PATH设置路径的查找顺序来控制。
接口改了必须重新编译连接。
接口改了必须重新编译连接。
|
这是大版本号,我是跟着你的文件命名法。
linux里标准作法是,
/usr/lib/libxxx.so.3 ---> /usr/lib/libxxx.so.3.1.2
同时还可能存在 /usr/lib/libxxx.so.3.1.3
同时还可能存在 /usr/lib/libxxx.so.3.1.4
同时还可能存在 /usr/lib/libxxx.so.3.1.5
同时还可能存在 /usr/lib/libxxx.so.3.2.1
同时还可能存在 /usr/lib/libxxx.so.3.3.2
这样就可以方便的控制版本,
就像你这一个文件其实怎么做名字都无所谓。除非你想让多个版本都存在。
在写客户程序时永远只需要写dlopen("libxxx.so.3")不需要修改了;其它事情让ldconfig去做,它每次启动都会执行。
如果你使用动态库的静态连接方式那么,改了那就必须重编客户。加了接口则不必
linux里标准作法是,
/usr/lib/libxxx.so.3 ---> /usr/lib/libxxx.so.3.1.2
同时还可能存在 /usr/lib/libxxx.so.3.1.3
同时还可能存在 /usr/lib/libxxx.so.3.1.4
同时还可能存在 /usr/lib/libxxx.so.3.1.5
同时还可能存在 /usr/lib/libxxx.so.3.2.1
同时还可能存在 /usr/lib/libxxx.so.3.3.2
这样就可以方便的控制版本,
就像你这一个文件其实怎么做名字都无所谓。除非你想让多个版本都存在。
在写客户程序时永远只需要写dlopen("libxxx.so.3")不需要修改了;其它事情让ldconfig去做,它每次启动都会执行。
如果你使用动态库的静态连接方式那么,改了那就必须重编客户。加了接口则不必
|
如果你仅仅在原有.so的基础上增加了新的接口,而没有修改原有接口的话,直接覆盖应该没有问题。我没有试验过,但我觉得应该没问题。
另外一种解决办法是:采用类似com的接口技术以及QueryInterface技术,整个.so仅仅暴露一个接口“QueryInterface”,通过QueryInterface获得一组/几组接口。当然,这并不适用于当前的项目,权作后继开发的一个建议吧
另外一种解决办法是:采用类似com的接口技术以及QueryInterface技术,整个.so仅仅暴露一个接口“QueryInterface”,通过QueryInterface获得一组/几组接口。当然,这并不适用于当前的项目,权作后继开发的一个建议吧
|
当接口发生变化(特别是新增加了接口)的情况下,建议将so文件升版并重新编译可执行文件。