编译后程序迁移问题

最近有一个需求,把一个在高版本机器上编译好的程序迁移到低版本上,由于我是C++小白完全不懂怎么解决,折腾了好久,写个博客记录一下

把动态库一起放上去

先查看一下依赖

1
2
3
4
5
6
7
8
linux-vdso.so.1 (0x00007ffdf57fc000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f45cd3d5000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f45cd3b2000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f45cba1e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f45cd263000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f45cd248000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45cb82c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f45cd3e4000)

然后写一个bash脚本把所有依赖拷进一个文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/sh

# List of libraries to copy
libs="/lib/x86_64-linux-gnu/libstdc++.so.6
/lib/x86_64-linux-gnu/libreadline.so.8
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libpthread.so.0
/usr/local/lib/yosys/libyosys.so
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1
/lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libtinfo.so.6
/lib/x86_64-linux-gnu/libffi.so.7
/lib/x86_64-linux-gnu/libz.so.1
/lib/x86_64-linux-gnu/libtcl8.6.so"

# Copy libraries to the current directory
for lib in $libs; do
cp $lib .
done

之后再写一个脚本把所有的依赖路径换成想在目标服务器上放置的路径,这里用的工具是patchelf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/sh

# List of libraries to copy
libs="/lib/x86_64-linux-gnu/libstdc++.so.6
/lib/x86_64-linux-gnu/libreadline.so.8
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libpthread.so.0
/usr/local/lib/yosys/libyosys.so
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1
/lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libffi.so.7
/lib/x86_64-linux-gnu/libz.so.1
/lib/x86_64-linux-gnu/libtcl8.6.so"

# Extract library name from path and prepend './dll/'
for lib_path in $libs; do
extracted_lib=$(basename $lib_path)

patchelf --replace-needed $extracted_lib '$ORIGIN/'$extracted_lib ./workflow
echo "patchelf --replace-needed $extracted_lib ./dll/$extracted_lib ./workflow"
done

之后在目标服务器上修改rpath

1
patchelf --set-rpath your/rpath your/program

同时,不要忘记修改interpreter,不然ldd看依赖即使正确也会报段错误

1
patchelf --set-interpreter your/interpreter your/program

静态链接

我的程序有一些奇奇怪怪的库用了glibc的动态库,导致我没法用这条路,虽然也不太推荐就是了

使用如下方式,需要注意的是,static需要写在dynamic的前面,高版本gcc还可以用-static的选项

1
2
-Wl,-Bstatic -lstdc++
-Wl,-Bdynamic -lm -ldl -lpthread

其他

  • 动态库的SONAME设置有问题
  • objdump -p + grep 查看设置有没有问题
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 0375w