- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个使用 Makefile 构建的共享库文件。我遇到了一个问题,在构建库之后,我会遇到可怕的 GLIBCXX_ not found
链接器错误。
这个案例特别奇怪。当我使用 -g3
标志编译时,我没有收到错误。如果我使用 -O2
编译,我会收到错误。
因此,当我使用 -O2
进行编译,并对编译后的 .so
文件运行 ldd
时,我得到:
$ ldd MYLIB.so.1
./MYLIB.so.1: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./MYLIB.so.1)
linux-vdso.so.1 => (0x00007fff21e8d000)
libz.so.1 => /lib64/libz.so.1 (0x00002b2cd4c40000)
libpng12.so.0 => /usr/lib64/libpng12.so.0 (0x00002b2cd4e54000)
libjpeg.so.62 => /usr/lib64/libjpeg.so.62 (0x00002b2cd5079000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b2cd529b000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b2cd54b7000)
libm.so.6 => /lib64/libm.so.6 (0x00002b2cd57b8000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b2cd5a3b000)
libc.so.6 => /lib64/libc.so.6 (0x00002b2cd5c49000)
/lib64/ld-linux-x86-64.so.2 (0x0000003891400000)
所以在这里,由于某种原因,/usr/lib64/libstdc++.so.6
正在寻找GLIBCXX_3.4.9
,它在/中不存在usr/lib64/libstdc++.so.6
,正如我们使用 strings
实用程序所见:
$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_FORCE_NEW
因此,为了进一步研究这一点,我针对编译后的 .so
文件运行 nm
,并尝试找出正在寻找哪些符号 GLIBCXX_3.4.9
$ nm --demangle MYLIB.so.1 | grep GLIBCXX_3.4.9
U std::ostream& std::ostream::_M_insert<unsigned long>(unsigned long)@@GLIBCXX_3.4.9
U std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)@@GLIBCXX_3.4.9
好的,看起来一些标准的 C++ ostream
代码需要 GLIBCXX_3.4.9。好的...但似乎只有这个符号需要 GLIBCXX_3.4.9。其他一切都与 GLIBCXX_3.4
正确链接:
$nm --demangle MYLIB.so.1 | grep GLIBCXX
U std::string::find(char const*, unsigned long, unsigned long) const@@GLIBCXX_3.4
U std::string::compare(char const*) const@@GLIBCXX_3.4
U std::string::compare(std::string const&) const@@GLIBCXX_3.4
U std::logic_error::what() const@@GLIBCXX_3.4
U std::runtime_error::what() const@@GLIBCXX_3.4
U std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const@@GLIBCXX_3.4
U std::basic_iostream<char, std::char_traits<char> >::~basic_iostream()@@GLIBCXX_3.4
... etc ...
那么这可能是什么原因呢?为什么一个特定的符号会链接 GLIBCXX_3.4.9,而其他符号却不会?更奇怪的是 - 只有当我使用 -O2
编译时才会发生这种情况。
我对此感到很困惑。那么,发生这种情况的可能原因有哪些?链接器/编译器链如何确定特定符号所在的 GLIBCXX 版本?
最佳答案
这只是意味着您正在使用比 /usr/lib64/libstdc++.so
库所属的更新的 GCC 进行编译,并且您没有告诉动态链接器如何找到正确的 libstdc++。所以
对 GLIBCXX_3.4.9 的引用意味着您至少使用 GCC 4.2.0 进行编译,但系统 libstdc++.so 来自旧版本 4.1.1 或 4.1.2。
事实上它只是 -O2 处的问题并不真正相关,如果您使用较新的 GCC 进行编译,则需要使用其 libstdc++.so,句号。似乎除非您使用 -O2 进行编译,否则您实际上不会对较新的 libstdc++ 产生硬依赖。所以但这只是机会,如果您对代码进行任何小的更改导致它的优化略有不同,它可能会发生变化。
您需要阅读 https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_paths和 https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html#manual.intro.using.linkage.dynamic
Why would one particular symbol link GLIBCXX_3.4.9, but the rest don't?
因为其他符号在 GCC 3.4 和 4.2 之间没有变化,并且旧 libstdc++.so 中符号的版本与构建可执行文件时链接的版本相同。
未找到的符号是 GCC 4.2 中的新符号,因此它获得了较新的符号版本,并且在旧库中找不到。
关于c++ - 当指定 O2 标志时,gcc 链接到错误的 GLIBCXX 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30514416/
背景:我有运行 nodejs 6.10 的 AWS Lambda。对于我的代码,我需要一个 C 库来运行算法。这是由 node-gyp 在我的机器上编译的。 我的构建服务器是一个过时的 ubuntu
如果我在我的机器上编译一个 C++ 程序,并在另一台机器上运行它(使用较旧的软件),我会得到:/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not
如果我在我的机器上编译一个 C++ 程序,并在另一个(使用旧软件)上运行它,我会得到:/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not foun
我在同一台机器上编译、链接和运行的程序在尝试运行时怎么可能出现 GLIBCXX 版本错误?有人知道吗? 这是我得到的错误: 0.01s$ build/test/gamgee_test build/te
当我在我的计算机上使用 g++ 编译一个 c++ 程序并将可执行文件传输到我的大学服务器上运行它时,我得到了 ./main: /usr/lib/libstdc++.so.6: version `GLI
这是对之前在这里提出的问题的扩展:libstdc++ GLIBCXX version errors 我有一个在本地运行良好的 Node.js 应用程序 (Ubuntu 16.04),但是当我将 bun
我尝试使用 gdb 调试程序,但在运行命令后出现错误(在 gdb 内) /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found 我确
[情况] 我正在开发一个 C++ 库。我遇到了 GLIBCXX 版本的问题。 之前,我在版 native GLIBCXX_3.4.22上开发。 但我的库无法在具有 GLIBCXX_3.4.19 的目标
众所周知,glibc(据我所知,还有 glibstd++)使用符号版本控制机制。 (详情引用:How can I link to a specific glibc version。) 问题是如何确定链
ImportError:/lib64/libstdc++.so.6:未找到版本“GLIBCXX_3.4.20” 我在我的系统中安装 python 包(fbprophet)时遇到了这个错误 我的环境详细
我想为在 Linaro 14.04 上运行的 ARM 目标交叉编译一个软件。 当我使用 arm-linux-gnueabihf-g++ 从我的 Ubuntu 18.04 交叉编译,并尝试在目标上运行它
我已经搜索了很多,但没有解决这个问题,所以我想把它放在这里。 我有在 Ubuntu 上编译得很好的源代码,我想在我的 Centos 7 机器上使用它。为了这个问题,让我们假设在Centos上编译代码是
我试过用这个文件编译 #include #include #include #include #include using namespace cv; static void help( c
假设我有以下本地 gcc, g++ 版本: $ gcc -v $ g++ -v gcc version 6.3.1 与我的编译器版本相比,我不理解以下内容的关系和含义: 这是指什么? /usr/lib
我一直在努力关注this example在 Ubuntu 11.10 上使用 mex 在 MATLAB 中编译 vtk。我使用的mex命令如下: mex -I/usr/include/vtk-5.6
我已经安装了bsoft当我想运行一些需要 libstdc++.so.6 的函数时遇到问题。 bimg: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.9
我有一个使用 Makefile 构建的共享库文件。我遇到了一个问题,在构建库之后,我会遇到可怕的 GLIBCXX_ not found 链接器错误。 这个案例特别奇怪。当我使用 -g3 标志编译时,我
我在玩弄valarrays当我碰到某些东西时,我认为是编译器的 STL 实现中的错误。这是我可以制作的最小示例: #include #include #include #include #in
鉴于此版本的 stdc++ 库的 GLIBCXX 版本(示例 GLIBCXX_3.4.17),在哪里可以找到指定已实现哪些功能的文档? 此外,有没有一种方法可以在给定 SO NAME 版本的情况下提供
我是一名优秀的程序员,十分优秀!