C++ ABI
摘要
ABI被人熟知,就是编译时,接口不匹配导致运行时的动态库undefined symbol
报错。
ABI (Application Binary Interface)¶
- ABI:应用程序二进制接口(ABI)是两个二进制程序模块之间的接口。z
- 在编译时,我们需要保持接口版本的统一,才能正常通过编译。
- 通常,其中一个模块是库(e.g.,动态库
libstdc++.so
)或操作系统功能,另一个是用户正在运行的程序。
组成¶
“ library API + compiler ABI = library ABI ”1 ,为了编译顺利进行我们需要保持
- library API(Application Programing Interface)
- e.g., types/functions/exceptionsSTH in (STL) include files
- compiler ABI(Application Binary Interface)
- sth during the compilation process, e.g., alignment/funcNameHandling
默认版本¶
- 在 GCC 5 及以后的版本中,默认使用 C++11 ABI(即
-D_GLIBCXX_USE_CXX11_ABI=1
)。这意味着新编译的代码将遵循 C++11 的 ABI 规范。 - 对于旧版本的 GCC,默认使用的是旧的 ABI(
-D_GLIBCXX_USE_CXX11_ABI=0
)。
查看编译器的预定义宏
你可以使用 -dM -E
选项来查看预定义宏,包括 ABI 相关的宏。可以执行以下命令:
- 如果输出是
#define _GLIBCXX_USE_CXX11_ABI 1
,表示当前使用的是 C++11 ABI。 - 如果输出是
#define _GLIBCXX_USE_CXX11_ABI 0
,表示使用的是旧的 ABI。 - 如果没有输出,可能是没有定义该宏,表示使用的编译器可能较老或没有显式设置。
设置与修改¶
CMake¶
CMake 本身不会直接设置 ABI 选项,但会继承所用编译器的默认设置。 可以在 CMakeLists.txt 中显式设置 ABI 选项,例如:
编译器¶
显式版本切换的标志是 -fabi-version
检查¶
在 pintool 编译过程中:
#if !defined(__GXX_ABI_VERSION) || CC_USED_ABI_VERSION != __GXX_ABI_VERSION
#error 您的编译器的 C++ ABI 与 pin 工具包的 ABI 不匹配。
#endif
实践¶
PTA编译严重依赖torch的环境
ABI的开启严重依赖已有的正确的torch