当前位置: 首页 > Linux

CMake编译遇到这种ABI不兼容不要惊慌

时间:2023-04-06 19:01:06 Linux

最近在Linux下使用CMake编译程序时遇到了问题,在此记录一下。事情是这样的,我编译的程序使用了2个第三方库。写完CMakeLists,开始编译,然后就报链接错误,一直报一堆找不到的定义。一堆这样的:'*****std::__cxx11*****'undefinedreference我仔细检查了代码和CMakeLists,尝试了各种修改都无济于事。最后在同事和搜索引擎的帮助下,终于找到了问题所在。问题是我用的GCC版本和第三方库在编译的时候差别太大,两者的ABI不兼容。参考GCC提供的手册,事情就清楚了。在GCC5.1发布的libstdc++中,增加了新的特性,包括std::string和std::list的新实现。新的实现使两者都符合C++11标准。但是,为了与现有代码兼容,libstdc++保留了旧的实现,并与新的实现共存。如何实现?与旧的实现相比,GCC5.1增加了__cxx11命名空间,新实现中的string和list实际上是std::__cxx11::string和std::__cxx11::list。新旧ABI不兼容。那么,如何解决问题呢?也很简单,就是统一你的程序和第三方库使用的实现版本。如果你有第三方库的源码,统一重新编译即可。不管第三方库是否已经编译好,GCC为我们提供了一个宏定义来选择新旧实现——D_GLIBCXX_USE_CXX11_ABI。-D_GLIBCXX_USE_CXX11_ABI=0表示使用旧实现-D_GLIBCXX_USE_CXX11_ABI=1表示使用新实现根据需要添加到CMakeLists。