如何在目标平台上探测系统版gcc使用的C++ ABI

Bru*_*ams 5 c++ linux gcc configure c++14

我有一个配置探针,它根据平台和版本确定要传递给g ++的标志.我通常使用更高版本的gcc而不是本机安装版本,以便获得对C++ 14功能的访问.在较旧的平台上,这意味着我需要添加-D_GLIBCXX_USE_CXX11_ABI = 0以使用旧的C++ ABI,或者我无法与主机版本的C++库链接.然而,一些较新的平台确实使用新的ABI,在这种情况下需要-D_GLIBCXX_USE_CXX11_ABI = 1(或根本没有).

我可以根据目标平台的版本(即lsb_release -a的输出)来做到这一点,但我想要一个更通用的方法.

我认为我已经用原生编译器编译了一个C++ hello world程序(与我后来的编译器相反),但我无法弄清楚如何探测ABI版本.例如

>strings hello | grep ABI
.note.ABI-tag
>strings hello | grep CXX
GLIBCXX_3.4

或类似地使用hello探针程序使用的libstdc ++版本.

ldd ./hello | grep stdc++ | sed -e 's_.* /_/_' | cut -f 1 -d' ' |xargs strings | grep 

有没有人有更好的建议?

更新: 事实上我根本不需要这样做.我真正的问题是我有一个较旧版本的libstdc ++.所以闲逛.编译选择了一个版本6.0.20,运行时选择了一个不兼容的6.0.19(反之亦然).我有一个未解决的符号,我错误地将其归咎于ABI版本.与流行的看法相反,libstdc ++的次要版本并不总是二进制兼容.我的目的是始终在运行和编译时使用完全相同的版本(如果不使用主机本机版本).

Jon*_*ely 5

与流行的观点相反,libstdc++ 的次要版本并不总是二进制兼容的。

它们在两个方向上都不是二进制兼容的。libstdc++.so.6.0.20 可以在需要 libstdc++.so.6.0.19 时使用,但反过来不行。

但是,在 GCC 5 之前,C++11 支持仍处于试验阶段(即正在进行中),因此新 C++11 组件的 ABI 不稳定,因此您不能混合 C++11/C++使用 GCC 4.x 和 GCC 4.y 或 GCC 4 和 GCC 5 编译的 14 代码。对于 C++98 代码,您可以自由混合和匹配(只需使用较新的,libstdc++.so因为它只在一个方向兼容)。

GCC 5 之前的主要 C++11 不兼容性的详细信息记录在https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

无论如何,回答现在无关紧要的问题:

我想我已经完成了使用本机编译器编译 C++ hello world 程序的一半(而不是我后来的编译器),但我不太清楚如何探测 ABI 版本

如果您可以运行本机编译器,那么我看不出问题是什么,只需检查宏的默认值:

echo '#include <string>' | g++ -x c++ -E -dM - | fgrep _GLIBCXX_USE_CXX11_ABI
Run Code Online (Sandbox Code Playgroud)