20260903
1.问题描述
我使用Ubuntu16.04编译的可执行程序, 放到CentOS7.9上必然会报一个错误
/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20` not found
屡次,每次,可以复现.
这个错误是绑定到了操作系统(Ubuntu 16.04)上了吗?
是因为我在Ubuntu上编译的时候使用了更高版本的GCC?
我确认了Ubuntu16.04的GCC是5.4.0
CentOS7.9的GCC是4.8.5
我现在的需求是在Ubuntu上编译代码, 然后放到CentOS上面去运行,GCC版本是改变不了的.
如何解决?我可以在makefile层面上通过显式的指定GCC版本为4.8.4来解决跨平台GCC不兼容的问题吗?
Ubuntu16.04的GCC版本号
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
CentOS7.9的GCC版本号
CentOS 7.9 默认 GCC 版本为 4.8.5(gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44))。
该版本支持 C++11,不支持 C++14/C++17。
查看GCC版本号 Linux
好多老旧服务器普遍采用GCC版本号还停留在4.8.5的阶段, 查看Linux自带GCC版本的命令:
gcc --version
或更简洁
gcc -dumpversion
2.根因
这个错误不是绑定到操作系统上的,而是绑定到了 libstdc++.so.6 的版本上。
| 系统 | GCC | libstdc++ 最高符号 |
|---|---|---|
| Ubuntu 16.04 | 5.4.0 | GLIBCXX_3.4.21 |
| CentOS 7.9 | 4.8.5 | GLIBCXX_3.4.19 |
在 Ubuntu 上编译时,程序链接了 Ubuntu 自带的 libstdc++.so.6(包含 GLIBCXX_3.4.21)。放到 CentOS 上运行时,系统找不到这个版本的符号,直接报错。
GCC 5.4 链接的 libstdc++ 包含 GLIBCXX_3.4.20/21 符号,CentOS 7.9 的 libstdc++ 最高只到 GLIBCXX_3.4.19,找不到就报错。
不能通过 Makefile 指定 GCC 4.8.4 解决
Ubuntu 16.04 没有 gcc-4.8 包,且即使装了,链接器仍然会用系统的 libstdc++.so.6,问题照旧。
3.解决方案
方案一(推荐,改一行):
LDFLAGS += -static-libstdc++ -static-libgcc
把 libstdc++ 静态打包进二进制,运行时不再依赖系统库。
方案二:装低版本编译器
在Ubuntu16.04上安装低版本的编译器(也即对齐到CentOS 7.9的GCC 4.8.5)
sudo apt install g++-4.8
在makefile中指定
CXX := g++-4.8
方案一最省事,加一行就ok,药到病除,立竿见影

2670

被折叠的 条评论
为什么被折叠?



