动态库的麻烦之处

动态库的麻烦之处在于 - 若是你的程序使用了成百上千个动态库,你的程序在运行时如何找到这些动态库? html

通常有三个方法:网络

1、设置LD_LIBRARY_PATHapp

export LD_LIBRARY_PATH="/path/to/lib"

直接手工设是不可能完成的任务,由于你也知道有不少path (多不是问题,问题时你得知道这些path),因此通常须要在由编译系统来自动产生这些path,并放到一个runscript中:工具

#set path
export LD_LIBRARY_PATH=/path/to/lib1
export LD_LIBRARY_PATH=/path/to/lib2:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/path/to/lib3:$LD_LIBRARY_PATH
# ...
export LD_LIBRARY_PATH=/path/to/lib100:$LD_LIBRARY_PATH

# run app
/path/to/myapp

 

2、设置rpathpost

rpath设置能够在编译时:ui

g++ -Wl,-rpath,/path/to/lib ...
or
ld -rpath /path/to/lib ...

rpath应该能够是-L一致,因此能够在编译系统中作些工做自动产生rpath,premake目前(4.4beta)还不支持,但能够比较简单的作个扩展支持:(同时也展示了premake的灵活性)spa

origin_libdirs = libdirs
function libdirs(dirs) 
    origin_libdirs(dirs)
    if type(dirs) == 'string' then
        dirs = { dirs }
    end
    for _, dir in ipairs(dirs) do
        linkoptions('-Wl,-rpath,' .. dir)
    end
end

将libdirs都做为rpath编译到binary中去。code

能够经过readelf查看htm

readelf -d binary

而cmake则提供了比较好内建支持,有选项能够选择是否加入rpath。blog

 

可是,你编译时的rpath并不表明就是你最终生产环境中的rpath,考虑一下continuous delivery中的一个状况:

该项目有一个shared library和一个binary,在CI的build agent上编译产生,因此指向shared library的rpath是一个指向build agent上local的path,这些artifacts会被上传到artifact repository,而后在发布时被部署到生产环境中,此时该rpath一定是错误 --- 运行失败。

此时须要postprocess来修改rpath,有个叫作patchelf的工具:

patchelf --set-rpath /path/to/production/lib

一样,怎么改rpath不是重点,重点是有哪些rpath,改为什么样 - 这些须要在build system在编译过程当中收集。

还能够去掉不须要的rpath:

patchelf --shrink-rpath program

 

3、拷贝或者symbolic link

Windows下通常直接把全部dll打包放一块儿 - 与app同一目录,连PATH都不用设。

Linux下咱们能够把全部的library都symblic link到同一目录下,PATH只要设一个便可 - 这个在网络环境下尤为有用,以前这篇文章也讲到过。

相关文章
相关标签/搜索