编译环境:
ubuntu20.04
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
运行环境:
centos7.9
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
验证源文件 main.cpp:
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
std::string tmp("hello world test link libstdc++.so");
printf("hello world link libc.so\n");
std::cout << tmp << std::endl;
return 0;
}
编译为可执行文件:
g++ -o main main.cpp
编译环境下, 运行输出: ./main
hello world link libc.so
hello world test link libstdc++.so
把main直接拷贝到运行环境,并运行: ./main
./main: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./main)
我们分析main在编译环境下,到底依赖高版本中的哪些文件:
编译环境下,查看可执行文件的依赖:ldd main
linux-vdso.so.1 (0x00007ffecf5af000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fbae4d72000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbae4b80000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbae4a31000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbae4f72000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fbae4a16000)
可以看出,main依赖编译环境下的这几个文件:
/lib/x86_64-linux-gnu/libstdc++.so.6
/lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libm.so.6
/lib64/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/libgcc_s.so.1
把编译环境下的这5个文件,拷贝到运行环境下,可执行文件main同目录中的lib文件夹中,相对位置如下:
运行环境下,修改rpath:
yum install patchelf -y
patchelf --set-rpath `pwd`/lib main
运行环境下,运行:./main
./main: relocation error: /data/gopath/src/helloworld_dll/src/main/tmp/lib/libc.so.6: symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
运行环境下,修改interpreter,这一步是关键,即在运行环境下也一定要使用编译环境下的ld-linux-x86-64.so.2来引导编译环境下编译的可执行文件main
patchelf --set-interpreter `pwd`/lib/ld-linux-x86-64.so.2 ./main
运行环境下,再次运行,终于不报错了:./main
hello world link libc.so
hello world test link libstdc++.so
参考:
高版本gcc编译出的程序在低版本glibc机器上运行 - 简书 (jianshu.com)