如何在现有的libstdc ++中使用备用glibc? [英] How to use alternate glibc with existing libstdc++?
问题描述
我需要使用glibc
(2.18)的自编译版本,比系统上的默认版本(2.15)更新.我可以编译和链接C ++程序,但是当我尝试运行它时,出现关于libstdc++.so.6
的错误. (C程序似乎可以正常工作.)是否需要针对较新的glibc
重新编译gcc
才能使其正常工作?为什么? (更新:我已经弄清楚了这部分,但是在底部还有其他一些问题.)
I need to use a self-compiled version of glibc
(2.18), newer than the default one on the system (2.15). I can compile&link a C++ program, but when I try to run it, I get errors about libstdc++.so.6
. (C programs seems to work just fine.) Do I need to recompile gcc
against the newer glibc
for this to work? Why? (Update: I figured this part out, but I have a few other questions at the bottom.)
这是一个示例C ++程序:
Here is a sample C++ program:
#include <iostream>
int main()
{
std::cout << "ok\n";
return 0;
}
在此答案之后,我将其编译为:
Following this answer, I compiled it with:
g++ -Wl,--rpath=/path/to/glibc-2.18/lib -Wl,--dynamic-linker=/path/to/glibc-2.18/lib/ld-2.18.so a.cpp
它编译没有错误,然后ldd
说:
It compiles with no errors, then ldd
says:
$ ldd a.out
linux-vdso.so.1 => (0x00007fff421fe000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3b96e7f000)
libc.so.6 => /path/to/glibc-2.18/lib/libc.so.6 (0x00007f3b96ad1000)
libm.so.6 => /path/to/glibc-2.18/lib/libm.so.6 (0x00007f3b967cf000)
/path/to/glibc-2.18/lib/ld-2.18.so => /lib64/ld-linux-x86-64.so.2 (0x00007f3b9719d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3b965b9000)
但是当我尝试运行它时:
But when I try to run it:
$ ./a.out
./a.out: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
这令人困惑,因为看起来ldd
发现libstdc++.so.6
很好(特定版本为libstdc++.so.6.0.16
).
This is confusing because it looks like ldd
finds libstdc++.so.6
just fine (the specific version is libstdc++.so.6.0.16
).
更新:问题似乎是(不确定)新的2.18
动态链接器正在使用其自己的库路径,该路径仅包含/path/to/glibc-2.18/lib
的子文件夹.通过添加此新路径,然后是到/path/to/glibc-2.18/etc/ld.so.conf
的标准路径(/lib', '/usr/lib
等),然后运行/path/to/glibc-2.18/sbin/ldconfig
,可以使程序运行.更多问题:
Update: The problem seems to have been (not sure) that the new 2.18
dynamic linker is using its own library path which includes only subfolders of /path/to/glibc-2.18/lib
. I got the program to run by adding this new path, followed by the standard paths (/lib', '/usr/lib
, etc) to /path/to/glibc-2.18/etc/ld.so.conf
and running /path/to/glibc-2.18/sbin/ldconfig
. More questions:
-
我绝对需要新的
2.18
动态链接程序来运行带有glibc-2.18
的程序吗?标准链接器不能这样做吗? (这将避免我不得不设置并不断更新2.18
动态链接器的路径.)
Do I absolutely need the new
2.18
dynamic linker to run a program withglibc-2.18
? Can't the standard linker do it? (This would avoid me having to set up and continuously update the paths of the2.18
dynamic linker.)
如果我使用2.18
动态链接器进行编译,但没有--rpath
,则该程序将无法运行.为什么?
If I compile with the 2.18
dynamic linker but without --rpath
, the program doesn't work. Why?
是否应该在编译命令中使用-L/path/to/glibc-2.18/lib
(除了--rpath
和--dynamic-linker
之外)?
Should I be using -L/path/to/glibc-2.18/lib
in the compilation command (in addition to --rpath
and --dynamic-linker
)?
推荐答案
我绝对需要新的2.18动态链接程序来运行带有glibc-2.18的程序吗?
Do I absolutely need the new 2.18 dynamic linker to run a program with glibc-2.18?
是的(差不多,请参见脚注).
Yes (well, almost. See footnote).
这将避免我不得不设置并不断更新2.18动态链接器的路径.
This would avoid me having to set up and continuously update the paths of the 2.18 dynamic linker.
一种常见的技术是创建一个g++
外壳包装程序,例如g++glibc2.18
,并封装在其中添加必要的链接参数.然后,简单的make CXX=g++glibc2.18
会做正确的事.
A common technique is to create a g++
shell wrapper, e.g. g++glibc2.18
, and encapsulate adding the necessary link arguments there. Then a simple make CXX=g++glibc2.18
would do the right thing.
标准链接器不能这样做吗?
Can't the standard linker do it?
不.有关说明,请参见此答案.
No. See this answer for explanation.
如果我使用2.18动态链接器但没有--rpath进行编译,则该程序将无法运行.为什么?
If I compile with the 2.18 dynamic linker but without --rpath, the program doesn't work. Why?
看到相同的答案.
是否应该在编译命令中使用-L/path/to/glibc-2.18/lib(除了--rpath和--dynamic-linker之外)?
Should I be using -L/path/to/glibc-2.18/lib in the compilation command (in addition to --rpath and --dynamic-linker)?
是的,如果要使用glibc-2.18中存在但系统库中不存在的符号.否则,不会.
Yes, if you want to use symbols that are present in glibc-2.18 but not present in your system library. Otherwise, no.
脚注:
作为替代方案,您可以在不使用特殊标志的情况下构建程序,然后使用显式加载程序调用"实际运行它:/path/to/glibc-2.18/lib/ld-2.18.so /path/to/a.out
.
As an alternative, you could build your program without the special flags, then use "explicit loader invocation" to actually run it: /path/to/glibc-2.18/lib/ld-2.18.so /path/to/a.out
.
当心:这并不总是有效:如果程序喜欢重新执行exec
本身(以及在其他罕见情况下).以这种方式调用它时,您可能还无法调试它.
Beware: this doesn't always work: if the program likes to re-exec
itself (and under other rare conditions). You may also have trouble debugging it when it is invoked that way.
这篇关于如何在现有的libstdc ++中使用备用glibc?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!