且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

由于符号与 abi::cxx11 的链接问题?

更新时间:2021-06-28 21:38:56

免责声明,以下内容未经生产测试,使用风险自负.

Disclaimer, the following is not tested in production, use at your own risk.

您可以自己在双 ABI 下发布您的库.这或多或少类似于 OSX 的胖二进制",但完全用 C++ 构建.

You can yourself release your library under dual ABI. This is more or less analogous to OSX "fat binary", but built entirely with C++.

最简单的方法是将库编译两次:-D_GLIBCXX_USE_CXX11_ABI=0-D_GLIBCXX_USE_CXX11_ABI=1.根据宏的值将整个库放在两个不同的命名空间下:

The easiest way to do so would be to compile the library twice: with -D_GLIBCXX_USE_CXX11_ABI=0 and with -D_GLIBCXX_USE_CXX11_ABI=1. Place the entire library under two different namespaces depending on the value of the macro:

#if _GLIBCXX_USE_CXX11_ABI
#  define DUAL_ABI cxx11 __attribute__((abi_tag("cxx11")))
#else
#  define DUAL_ABI cxx03
#endif

namespace CryptoPP {
  inline namespace DUAL_ABI {
    // library goes here
  }
}

现在您的用户可以像往常一样使用 CryptoPP::whatever,这映射到 CryptoPP::cxx11::whateverCryptoPP::cxx03::任何取决于选择的ABI.

Now your users can use CryptoPP::whatever as usual, this maps to either CryptoPP::cxx11::whatever or CryptoPP::cxx03::whatever depending on the ABI selected.

请注意,GCC 手册说此方法将更改标记的内联命名空间中定义的所有内容的重整名称.根据我的经验,这不会发生.

Note, the GCC manual says that this method will change mangled names of everything defined in the tagged inline namespace. In my experience this doesn't happen.

如果 _GLIBCXX_USE_CXX11_ABI 非零,另一种方法是使用 __attribute__((abi_tag("cxx11"))) 标记每个类、函数和变量.这个属性很好地将 [cxx11] 添加到 demangler 的输出中.我认为使用命名空间同样有效,并且需要对现有代码进行较少的修改.

The other method would be tagging every class, function, and variable with __attribute__((abi_tag("cxx11"))) if _GLIBCXX_USE_CXX11_ABI is nonzero. This attribute nicely adds [cxx11] to the output of the demangler. I think that using a namespace works just as well though, and requires less modification to the existing code.

理论上你不需要复制整个库,只需要使用std::stringstd::list的函数和类,以及函数和类使用这些函数和类,等等.但在实践中可能不值得付出努力,尤其是在库不是很大的情况下.

In theory you don't need to duplicate the entire library, only functions and classes that use std::string and std::list, and functions and classes that use these functions and classes, and so on recursively. But in practice it's probably not worth the effort, especially if the library is not very big.