*nix下部署第三方动态库文件

 最近写的一些程序经常需要放到不同的机器上执行,就做了一些工作,减少配置环境的时间,尽量做到从代码库里check out代码到本地就可以直接执行(或者make一次之后执行)。或者说,花了一点时间把程序做得更“绿色”一点。

问题的关键在于我们的程序里依赖一些第三方的动态库(以.so结尾的)文件,比如libxml2,tinyxml和crfpp等等,这些动态库要么不在软件源里,要么在软件源里的版本太低(我们需要2.6.28以上的libxml2,因为<=2.6.28的libxml2在解析一些不规则的html会有问题),不支持一些新的特性,在有些机器上可能又没有足够的权限安装包和拷贝动态库文件到系统目录。与windows不同,出于安全和性能方面的考虑,*nix系统上默认的程序的动态库查找目录中并不包括当前目录。

我想到一些方法,在这里讨论下。为了简化下讨论,假设只需要支持一种体系结构x86_64,假设编译好的动态库文件有比较好的二进制兼容性。

1.最容易想到的就是,既然动态库查找目录不包括当前目录,就通过修改环境变量的方式把它加进去。实际做起来最好写个脚本,设置好环境变量之后使用exec语句加载程序。尽量不要直接在shell里使用export或者以.表示在当前shell中设置环境变量,这样很容易干扰相同shell中其他程序的执行。

可以修改的环境变量包括LD_PRELOAD和LD_LIBRARY_PATH。两个环境变量都是以冒号分割,LD_PRELOAD需要直接指定动态库的完整路径,LD_LIBRARY_PATH顾名思义指定动态库所在目录的路径。实际上firefox的linux版就是通过这样的方式加载它的动态库的,脚本firefox调用脚本run-mozilla.sh,设置好环境变量后最终调用firefox的二进制可执行程序。

2.利用libtool的rpath选项。rpath是指定给连接器的选项,gcc里通过-Wl,-rpath指定,搜索动态库的时候会优先搜索rpath所指定的目录。xampp项目就是通过这样的方式做到免安装部署的,只要解压到/opt目录就可以直接启动。

3.使用gun c库的dlopen函数族,在运行时加载动态库。用这种方法的话比较麻烦的就是要定义一些函数指针,还要在动态加载过程中做一些错误处理。

我们确实比较神奇的使用了这种方式,就是在crfpp项目中添加了新的文件,里面实现了一个简单的接口,把这个文件链接到最终的动态库中,主程序通过简化过的接口调用crfpp的功能。

4.把二进制可执行文件和依赖的动态库打包成一个新的elf格式的二进制可执行文件。典型的项目是elf statifier和类似的商业软件Ermine。打包生成的可执行文件一般体积会比较大,Ermine在这方面做得好一些。

这个问题我想的不多,一些细节也理解的不到位,欢迎大家多补充。

P.S. 要实现最终目标:简化部署,实际可行的方案还有很多,比如修改所要引用的项目的Makefile做成静态库,或者直接把编译生成的目标文件加到最终可执行文件的链接过程中。

你可能感兴趣的:(linux,职场,库,休闲,动态链接库)