Search code examples
c++linuxgccname-mangling

How do I force cxx11 ABI on Red Hat?


I'm building a small .so library on Ubuntu 16.04 and Red Hat 7 using gcc 7.3. When I check the export symbol names using the nm command, I find that the library compiled on Ubuntu uses the cxx11 ABI but the library compiled on RedHat does not.

For example, the export symbol for a function compiled on Ubuntu looks like this.

_Z12customLoad3DPKN8nlohmann10basic_jsonISt3mapSt6vectorNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEblmdSaNS_14adl_serializerEEEPP11IVolumeDataPSA_

But the same export symbol when compiled on RedHat looks like this.

_Z12customLoad3DPKN8nlohmann10basic_jsonISt3mapSt6vectorSsblmdSaNS_14adl_serializerEEEPP11IVolumeDataPS4_

Both libraries use the same makefile. The code uses #define _GLIBCXX_USECXX11_ABI 1 and command line option -std=c++11. I’ve also tried using the -fabi-version option with different values, all with no effect. I can’t resolve this with the #ifdef __cplusplus extern "C" method because the functions use template class parameters.

How do I force gcc on RedHat to use the cxx11 ABI? I can’t use dual ABI linkage because the .so library is used as a plugin for an app that links at runtime to functions in the library using a hardcoded list of mangled names. The plugin won’t work on Red Hat because the mangled names don’t match the program’s expectations. How do I fix this?

Thanks!


Solution

  • The libstdc++ C++11 ABI is not supported on Red Hat Enterprise Linux 7. You have two options:

    • Upgrade to Red Hat Enterprise Linux 8. Its system compiler defaults to the newer ABI.

    • Rebuild the application on Red Hat Enterprise Linux 7, using Developer Toolset. The hybrid linkage model ensures that the application will run on Red Hat Enterprise Linux 7. Only the old ABI is available, but this generally does not matter due to the rebuild because the result is internally consistent.