c++ - 如何在 Red Hat 上强制 cxx11 ABI?
问题描述
我正在使用 gcc 7.3 在 Ubuntu 16.04 和 Red Hat 7 上构建一个小型 .so 库。当我使用 nm 命令检查导出符号名称时,我发现在 Ubuntu 上编译的库使用 cxx11 ABI,但在 RedHat 上编译的库没有。
例如,在 Ubuntu 上编译的函数的导出符号如下所示。
_Z12customLoad3DPKN8nlohmann10basic_jsonISt3mapSt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS_14adl_serializerEEEPP11IVolumeDataPSA_
但是在 RedHat 上编译时相同的导出符号看起来像这样。
_Z12customLoad3DPKN8nlohmann10basic_jsonISt3mapSt6vectorSsblmdSaNS_14adl_serializerEEEPP11IVolumeDataPS4_
两个库都使用相同的 makefile。该代码使用#define _GLIBCXX_USECXX11_ABI 1 和命令行选项-std=c++11。我还尝试使用具有不同值的 -fabi-version 选项,但均无效。我无法使用该#ifdef __cplusplus extern "C"
方法解决此问题,因为这些函数使用模板类参数。
如何强制 RedHat 上的 gcc 使用 cxx11 ABI?我不能使用双 ABI 链接,因为 .so 库用作应用程序的插件,该应用程序在运行时使用重编码名称的硬编码列表链接到库中的函数。该插件无法在 Red Hat 上运行,因为损坏的名称与程序的预期不符。我该如何解决?
谢谢!
解决方案
libstdc++
Red Hat Enterprise Linux 7 不支持 C++11 ABI。您有两种选择:
升级到 Red Hat Enterprise Linux 8。其系统编译器默认为较新的 ABI。
使用Developer Toolset在 Red Hat Enterprise Linux 7 上重建应用程序。混合链接模型确保应用程序将在 Red Hat Enterprise Linux 7 上运行。只有旧的 ABI 可用,但由于重建,这通常无关紧要,因为结果在内部是一致的。
推荐阅读
- angular - 角度问题“垫表”不是已知元素
- ruby-on-rails - 创建后脚手架时不破坏
- java - 在 jboss 部署期间验证错误。如何解决这个问题?
- r - AzureRMR 中的 list_resources() 对于某些订阅失败,并出现“无效的对象名称”错误
- linux - 可以将地址加载到缓存中但不能加载到主存中吗?
- vscode-tasks - vscode:任务扩展另一个任务/传递参数
- rabbitmq - 如何使用 Github Actions 设置 rabbitmq 服务?
- git - 从 github windows 中删除多个文件
- c++ - C++ - 执行makefile时找不到目录
- javascript - 未获取未定义的 JavaScript 值即将到来