Disclaimer, the following is not tested in production, use at your own risk.
You can yourself release your library under dual ABI. This is more or less analogous to OSX "fat binary", but built entirely with C++.
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
}
}
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.
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.
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.
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…