Ale*_*eph 4 c++ gcc c++11 c++14
我试着理解如何克服GCC 5中引入的双ABI的问题.但是,我没有设法做到这一点.这是一个重现错误的简单示例.我使用的GCC版本是5.2.如您所见,我的main函数(在main.cpp文件中)非常简单:
// main.cpp
#include <iostream>
#include <string>
int main()
{
std::string message = "SUCCESS!";
std::cout << message << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
当我输入
/home/aleph/gcc/5.2.0/bin/g++ main.cpp
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
/tmp/ccjsTADd.o: In function `main':
main.cpp:(.text+0x26): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
main.cpp:(.text+0x43): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
main.cpp:(.text+0x5c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
main.cpp:(.text+0x8c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
collect2: erreur: ld a retourné 1 code d'état d'exécution
Run Code Online (Sandbox Code Playgroud)
如果我将值更改_GLIBCXX_USE_CXX11_ABI为0,问题就会消失.
但是,如何使用默认的ABI工作呢?
编辑:更简单的问题(删除了cmake脚本)
我通过向gcc添加更多详细信息(-v标志)找到了解决方案.如果您遇到同样的问题,您需要告诉gcc在包含您的发行版的libstdc ++版本的存储库中搜索库.换句话说,你应该尝试这样的事情:
/home/aleph/gcc/5.2.0/bin/g++ -L /home/aleph/gcc/5.2.0/lib64 main.cpp
Run Code Online (Sandbox Code Playgroud)
之后应该正确执行链接步骤.但是,您可能无法运行程序.进入
./a.out
Run Code Online (Sandbox Code Playgroud)
可能会导致以下错误:
./a.out: relocation error: ./a.out: symbol _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_, version GLIBCXX_3.4.21 not defined in file libstdc++.so.6 with link time reference
Run Code Online (Sandbox Code Playgroud)
实际上,您可以通过键入来检查您的可执行文件是否依赖于错误版本的libstdc ++
ldd a.out
Run Code Online (Sandbox Code Playgroud)
应该导致类似的东西:
linux-vdso.so.1 => (0x00007ffebb722000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000003a71400000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x0000003d03a00000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x0000003a71000000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000003d02e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d02a00000)
Run Code Online (Sandbox Code Playgroud)
将LD_LIBRARY_PATH设置为您自己的libstdc ++版本的路径将解决问题:
LD_LIBRARY_PATH=/home/aleph/gcc/5.2.0/lib64 ./a.out
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
编辑:正如Marc所注意到的,可以修改rpath,而不是修改环境变量LD_LIBRARY_PATH.这是一个CMake配置脚本.
project (example CXX)
add_executable(main main.cpp)
if(GCC_ROOT)
set(CMAKE_CXX_COMPILER ${GCC_ROOT}/bin/g++)
target_link_libraries(main ${GCC_ROOT}/lib64/libstdc++.so)
link_directories(${GCC_ROOT}/lib64)
endif(GCC_ROOT)
Run Code Online (Sandbox Code Playgroud)
此脚本可以与通常的组合一起使用
cmake ..
make
Run Code Online (Sandbox Code Playgroud)
在'build'子目录中.但是也可以通过提供GCC发行版根目录的路径来选择我们自己的编译器:
cmake -D GCC_ROOT=/home/aleph/gcc/5.2.0 ..
make
Run Code Online (Sandbox Code Playgroud)
编写脚本,以便libstdc ++的版本对应于输入GCC分发的版本.