【问题标题】:CXX11 undefined references with GCC 6.2.0GCC 6.2.0 的 CXX11 未定义引用
【发布时间】:2016-12-08 12:01:40
【问题描述】:

我们已经在一台 Scientific Linux 机器上手动安装了 GCC 6.2.0。 C++ 应用程序的编译看起来不错,但在链接时我们会收到很多 undefined references 到 CXX11

file.cpp:(.text+0x16cb): undefined reference to `std::__cxx11::list<void*, std::allocator<void*> >::list(std::__cxx11::list<void*, std::allocator<void*> > const&)'

我们知道double ABI issue,但使用-D_GLIBCXX_USE_CXX11_ABI=0 编译没有区别。我们还有哪些其他选择?

更新

CMAKE配置如下:

-- The C compiler identification is GNU 6.2.0
-- The CXX compiler identification is GNU 6.2.0
-- Check for working C compiler: /opt/GNU/gcc-6.2.0/bin/gcc
-- Check for working C compiler: /opt/GNU/gcc-6.2.0/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/GNU/gcc-6.2.0/bin/g++
-- Check for working CXX compiler: /opt/GNU/gcc-6.2.0/bin/g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done

这是file.cpp的编译行

gcc-6.2.0/bin/g++ -O3 -fopenmp -DNO_HDF5 -D_GLIBCXX_USE_CXX11_ABI=0  -I./include -I/opt/mpich/3.2/include  -o file.cpp.o -c file.cpp

和链接(实际上失败的地方)

gcc-6.2.0/bin/g++ -O3 -fopenmp -DNO_HDF5 -D_GLIBCXX_USE_CXX11_ABI=0     main.cpp.o  -o ASTEP -rdynamic libMainASTEPlib.a -lhdf5_hl -lhdf5 -lz -lm -lhdf5_hl -lhdf5 -lz -lm /opt/mpich/3.2/lib/libmpicxx.so /opt/mpich/3.2/lib/libmpi.so -Wl,-rpath,/opt/mpich/3.2/lib

此外,MPICH 3.2 已使用新编译器 (gcc 6.2.0) 构建

【问题讨论】:

  • 如何链接你的程序?与ld?与gcc?与g++?
  • 删除目标文件并重新编译。
  • 在安装 gcc 时,gcc 更愿意假设它的库将安装到 /usr/lib(64)? 中,而不管您实际将 gcc 推到哪里。因此,您的代码最终会与系统的标准库链接。不幸的是,我忘记了如何从 gcc 的配置中剔除垃圾的血腥细节,以便正确设置它以与安装它们的库链接。你必须弄清楚,就像我 10 年前所做的那样......如果我记得所有这些,我会发布一个答案。
  • 这意味着file.cpp 没有与-D_GLIBCXX_USE_CXX11_ABI=0 一起编译。发布编译系统发出的编译器和链接器命令行。
  • @n.m. ——这正是我的意思。期望当我在某个目录中安装 GCC 和 libstdc++ 时,我只是正常链接我的代码,一切都在没有神秘链接选项的情况下工作,这并非不合理。 Freebsd 正确打包了 GCC,多个 gccNN 命令,每个命令都与它的 libstdc++ 链接,并为运行时提供 rpath。

标签: c++ c++11 gcc abi gcc5


【解决方案1】:

我不明白为什么当您使用-D_GLIBCXX_USE_CXX11ABI=0 编译时,您的对象仍然引用std::__cxx11::list,除非随后在头文件/源文件中重新定义宏。您应该确保 file.o 对象被正确放置到应该包含它的任何存档中(并且任何旧版本肯定已经消失)。话虽如此:

您可能需要链接 gcc 6.2.0 附带的 libstdc++ 库,而不是该库的系统版本,它似乎对应于早期的编译器。

这可能需要使用-nostdlib,然后手动添加-L/(path)/gcc-6.2.0/lib -lstdc++ -lc 或类似名称。

或者,您可以使用系统 C++ 头文件而不是 gcc 6.2.0 头文件进行编译。然后,您还应该能够成功链接到系统 libstdc++ 库。在这种情况下,您需要-nostdinc++,然后是-I/usr/include/c++/5(例如)。请注意,在这种情况下,-D_GLIBCXX_USE_CXX11_ABI=0 将无效且不必要;旧库没有双 ABI。

【讨论】:

  • gcc 在自己的安装中搜索libstdc++,而不是在系统位置(我一直将 gcc 安装到非标准位置)。
  • @n.m.然而,在这种情况下显然没有这样做。
  • 事实上,gcc 默认是这样做的。在这种情况下,我们对手头的一些未知现象进行了一些间接观察。从这里到明确建立任何东西是一条漫长的道路。至少在我们发布详细的构建日志之前。
  • @n.m.我的个人知识/经验使我得出结论,如果链接器未找到错误中提到的符号,则未链接适当版本的 libstdc++.so.6。该库的错误版本要么在它之前,要么被完全省略。我宁愿提出一个在这两种情况下都可能有所帮助的解决方案,而不是仅仅考虑无数其他不太可能的可能性。
  • 看起来像一个错误的库一个错误的对象正在链接。你的理论没有解释这一点。一定存在其他问题。
猜你喜欢
  • 2019-02-22
  • 2014-04-21
  • 2012-12-12
  • 2018-05-07
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多