如何探测目标平台上系统版本的gcc使用的C++ ABI
How to probe the C++ ABI used by the system version of gcc on the target platform
我有一个配置探测器,它根据平台和版本确定要传递给 g++ 的标志。我通常使用比本机安装版本更高版本的 gcc,以便访问 C++14 功能。
在较旧的平台上,这意味着我需要添加 -D_GLIBCXX_USE_CXX11_ABI=0 才能使用较旧的 C++ ABI,否则我无法 link 使用主机版本的 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++.so 闲逛。编译选择了一个版本 6.0.20,运行time 选择了一个不兼容的版本 6.0.19(或者反之亦然)。我有一个未解析的符号,我错误地将其归咎于 ABI 版本。与流行的看法相反,次要版本的 libstdc++ 并不总是二进制兼容的。我的意图是始终在 运行 和编译时使用完全相同的版本(如果不使用主机本机版本)。
Contrary to popular belief minor versions of libstdc++ aren't always binary compatible.
它们不是双向二进制兼容的。需要libstdc++.so.6.0.19时可以使用libstdc++.so.6.0.20,反之则不行。
但是,在 GCC 5 之前,C++11 支持仍处于实验阶段(即正在进行中),因此新 C++11 组件的 ABI 不稳定,因此您不能混合使用 C++使用 GCC 4.x 和 GCC 4.y 或 GCC 4 和 GCC 5 编译的 11/C++14 代码。对于 C++98 代码,您可以自由混合和匹配(只需使用较新的 libstdc++.so
因为它只在一个方向上兼容)。
GCC 5 之前的主要 C++11 不兼容性的详细信息记录在 https://gcc.gnu.org/wiki/Cxx11AbiCompatibility
无论如何,回答现在无关紧要的问题:
I think I'm half way there with compiling a C++ hello world program with the native compiler (as opposed to my later one) but I can't quite figure out how to probe the ABI version
如果你可以 运行 本机编译器那么我看不出问题是什么,只需检查宏的默认值:
echo '#include <string>' | g++ -x c++ -E -dM - | fgrep _GLIBCXX_USE_CXX11_ABI
我有一个配置探测器,它根据平台和版本确定要传递给 g++ 的标志。我通常使用比本机安装版本更高版本的 gcc,以便访问 C++14 功能。 在较旧的平台上,这意味着我需要添加 -D_GLIBCXX_USE_CXX11_ABI=0 才能使用较旧的 C++ ABI,否则我无法 link 使用主机版本的 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++.so 闲逛。编译选择了一个版本 6.0.20,运行time 选择了一个不兼容的版本 6.0.19(或者反之亦然)。我有一个未解析的符号,我错误地将其归咎于 ABI 版本。与流行的看法相反,次要版本的 libstdc++ 并不总是二进制兼容的。我的意图是始终在 运行 和编译时使用完全相同的版本(如果不使用主机本机版本)。
Contrary to popular belief minor versions of libstdc++ aren't always binary compatible.
它们不是双向二进制兼容的。需要libstdc++.so.6.0.19时可以使用libstdc++.so.6.0.20,反之则不行。
但是,在 GCC 5 之前,C++11 支持仍处于实验阶段(即正在进行中),因此新 C++11 组件的 ABI 不稳定,因此您不能混合使用 C++使用 GCC 4.x 和 GCC 4.y 或 GCC 4 和 GCC 5 编译的 11/C++14 代码。对于 C++98 代码,您可以自由混合和匹配(只需使用较新的 libstdc++.so
因为它只在一个方向上兼容)。
GCC 5 之前的主要 C++11 不兼容性的详细信息记录在 https://gcc.gnu.org/wiki/Cxx11AbiCompatibility
无论如何,回答现在无关紧要的问题:
I think I'm half way there with compiling a C++ hello world program with the native compiler (as opposed to my later one) but I can't quite figure out how to probe the ABI version
如果你可以 运行 本机编译器那么我看不出问题是什么,只需检查宏的默认值:
echo '#include <string>' | g++ -x c++ -E -dM - | fgrep _GLIBCXX_USE_CXX11_ABI