现有的其他方法:
- docker容器部署:由于需要打包镜像,每次更新包都比较大,且费时
- docker容器安装:需要在本地安装docker,并安装服务器对应的linux版本镜像,然后在里面安装gcc等工具集,缺点是比较占用空间,且每次重启后需要编译的话需要启动docker容器,费时。
- 升级服务器gcc版本:例如debian系的gcc相对与arch系gcc版本要旧,只能自己重新编译,而且贸然升级服务器的gcc版本,可能会导致各种问题,风险极大。
一直以来都没有什么好的方法解决libc库不兼容的问题。后面找到了这个方法,经过测试,应用可以正常运行,步骤如下(以打包程序xxx.bin为例):
1. 准备工作
- 在服务器上,或者跟服务器glibc同一个(或者稍旧)版本的docker linux容器里面编译
patchelf
git clone https://github.com/NixOS/patchelf.git
# 网速慢的话可以在github的镜像站上面下载
./bootstrap.sh
./configure
make
sudo make install
2. 打包依赖库
- 拷贝动态库的脚本
copylib.sh如下,执行copylib.sh xxx.bin将程序所需依赖复制到当前路径的lib文件夹下面
#!/bin/bash
# copylib.sh
LibDir=$PWD"/lib"
Target=$1
lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*"))
mkdir $LibDir
for Variable in ${lib_array[@]}
do
cp "$Variable" $LibDir
done
3. 修改elf的interpreter和dynamic loader (“ELF interpreter”)
- 将上述程序
lib文件夹拷贝到xxx.bin同级目录,修改elf的脚本如下modify-elf.sh,执行modify-elf.sh xxx.bin,将程序依赖修改为上述拷贝的依赖,执行程序后发现没有提示错误了,可以运行。
#!/bin/bash
patchelf --set-rpath `pwd`/lib $1
patchelf --set-interpreter `pwd`/lib/ld-linux-x86-64.so.2 $1