linux项目部署时依赖库的处理


因项目需求,需要在多台服务器进行项目部署,当项目复杂依赖项过多时还需要考虑动态库依赖的问题。

1、开发机准备依赖环境动态库

以可执行程序 AIServer 例,

  • 1、使用ldd AIServer 查看依赖项

    ubuntu@ubuntu-server:/home//AIServer/bin$ ldd AIServer
            libswscale.so.5 => /lib/x86_64-linux-gnu/libswscale.so.5 (0x00007fb171fe2000)
            libavcodec.so.58 => /lib/x86_64-linux-gnu/libavcodec.so.58 (0x00007fb170a00000)
            libavutil.so.56 => /lib/x86_64-linux-gnu/libavutil.so.56 (0x00007fb17073c000)
            libavformat.so.58 => /lib/x86_64-linux-gnu/libavformat.so.58 (0x00007fb1704b3000)
            libswresample.so.3 => /lib/x86_64-linux-gnu/libswresample.so.3 (0x00007fb16d74d000)
    
  • 2、保留so的完整文件路径
    执行命令 ldd AIServer | awk '{if (match($3,"/")) {print $3}}', 将前述控制台输出每一行的第3列进行以“/”匹配,若成功则打印该列对应so的完整路径。

    ubuntu@ubuntu-server:/home//AIServer/bin$ ldd AIServer | awk '{if (match($3,"/")) {print  $3}}'
    /lib/x86_64-linux-gnu/libswscale.so.5
    /lib/x86_64-linux-gnu/libavcodec.so.58
    /lib/x86_64-linux-gnu/libavutil.so.56
    /lib/x86_64-linux-gnu/libavformat.so.58
    /lib/x86_64-linux-gnu/libswresample.so.3
    
  • 3、拷贝所有依赖so到指定目录

    当so较小时,直接手动依次拷贝so文件即可。当so较多,且有可能是软链接时,使用脚本处理。
    创建 test.sh 脚本:

    deplist=$( ldd $1 | awk '{if (match($3,"/")){ print $3}}' )
    cp -L -n $deplist $2
    

    参数 -L 表示拷贝文件(如果是软链接,会拷贝到最终的文件); -n 表示不覆盖已有文件

    将AIServer依赖的动态库拷贝到目标目录/tmp/lib, 执行命令 #sudo ./test.sh AIServer /tmp/lib/

2、动态库链接目录设置

部署时,常规方式是将so放入到系统、用户链接库目录中,如 /lib,/usr/lib 和 /usr/local/lib 等。 若so较少时也可以直接放在可执行文件的目录下。

这里考虑so较多的情况,

  • 完全拷贝到系统目录

    如果开发机和部署机器环境相同,直接复制并无问题。 如果部署机有修改的特殊库、或者系统不同,直接复制轻则导致其他程序异常,重则系统崩溃,例如我们前面检查AIServer的依赖项有 libc.so.6等系统底层库。 如果要复制,要避免覆盖系统已有的库。

  • /etc/profile 中 对 LD_LIBRARY_PATH 追加查找动态库目录

    这种方式修改后对该用户有效,重启依然有效。先用 echo 查看当前链接库目录。

    $ echo $LD_LIBRARY_PATH
    :/usr/local/cuda-11.2/lib64:/usr/local/lib
    

    /etc/profile 追加一行目录,并执行 source /etc/profile 生效修改。

    export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/home/ubuntu/tmp/lib"
    

    再次echo查看结果

    $ echo $LD_LIBRARY_PATH
    :/usr/local/cuda-11.2/lib64:/usr/local/lib:/home/ubuntu/tmp/lib
    
  • 临时追加LD_LIBRARY_PATH 查找动态库目录

    运行程序前,控制台执行 export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/home/ubuntu/tmp/lib"命令,当前修改仅对运行shell有效。

3、测试

在当前目录下,有可执行文件app,依赖库为 dst/libmylib.so,运行结果为输出一行文字。

$ tree -L 2
├── app
├── dst
    └── libmylib.so

直接执行时,结果如下

$ ./app
./app: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory

为方便运行,执行脚本 run_app.sh, 结果如下

$ cat run_app.sh
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:./dst"
./app

$ ./run_app.sh
Hello, from mylib!

如果在其他目录运行时,需要在sh文件中填写完整路径。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

waf13916

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值