C++ 使用 -static-libgcc -static-libstdc++ 编译仍然会导致对 libc.so 的动态依赖

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26304531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:34:03  来源:igfitidea点击:

Compiling with -static-libgcc -static-libstdc++ still results in dynamic dependency on libc.so

c++cgccglibcstatic-linking

提问by Claudiu

I'm trying to make an executable that's as portable as possible. After removing a few dependencies, I came across the following when running the binary on another system:

我正在尝试制作一个尽可能可移植的可执行文件。删除一些依赖项后,我在另一个系统上运行二进制文件时遇到了以下问题:

/lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.15' not found (required by foob)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.15' not found (required by foob)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by foob)

I'd prefer my binary not to require the user to upgrade their version of libc, so I'd like to remove this dependency as well.

我更喜欢我的二进制文件不要求用户升级他们的libc版本,所以我也想删除这个依赖项。

The linker flags that produced the above binary already included -static-libgcc -static-libstdc++. How come the binary still requires on the shared libc.so.6?

生成上述二进制文件的链接器标志已经包括在内-static-libgcc -static-libstdc++。为什么二进制文件仍然需要共享libc.so.6

I tried adding the -staticflag as well, however when I try to run thatbinary the result is very strange:

我也尝试添加-static标志,但是当我尝试运行二进制文件时,结果非常奇怪:

$ ls -l foob
-rwxr-xr-x 1 claudiu claudiu 13278191 Oct 10 13:03 foob
$ ./foob
bash: ./foob: No such file or directory

What to do?

该怎么办?

EDIT:

编辑:

$ file foob
foob: ELF 64-bit LSB  executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=5adee9a598b9261a29f1c7b0ffdadcfc72197cd7, not stripped
$ strace -f ./foob
execve("./foob", ["./foob"], [/* 64 vars */]) = -1 ENOENT (No such file or directory)
write(2, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
exit_group(1)                           = ?
+++ exited with 1 +++

Interestingly, if I lddthe version without-static, it has two lessentries than the version with -static, namely:

有趣的是,如果我不带ldd的版本,它比带 的版本两个条目,即:-static-static

libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4f420c1000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4f41636000)

回答by zwol

GNU libc is not designed to be statically linked. Important functions, e.g. gethostbynameand iconv, will malfunction or not work at all in a static binary. Arguably even worse, under some conditions a static binary will attempt to dynamically open and use libc.so.6, even though the whole point of static linkage is to avoid such dependencies.

GNU libc 并非设计为静态链接。重要的函数,例如gethostbynameiconv,在静态二进制文件中会出现故障或根本无法工作。可以说更糟糕的是,在某些情况下,静态二进制文件将尝试动态打开和使用libc.so.6,即使静态链接的全部目的是避免这种依赖性。

You should compile your program against uClibcor musl libcinstead.

您应该改为针对uClibcmusl libc编译您的程序。

(This has been true for at least 15 years.)

(至少 15 年来一直如此。)

回答by crash

First be aware that static linking of libc might not improve portability of your program, as libc might depend on other parts of your system e.g. kernel version.

首先请注意,libc 的静态链接可能不会提高程序的可移植性,因为 libc 可能取决于系统的其他部分,例如内核版本。

If you want to try complete static linking just using -static should the trick. Provided that there are static versions of all used libraries installed.

如果您想尝试完全静态链接,只需使用 -static 即可。前提是安装了所有使用的库的静态版本。

You can check if your program has only linked static libraries by using:

您可以使用以下方法检查您的程序是否仅链接了静态库:

ldd binary_name

EDIT:

编辑:

Another way that provides useful information for debugging this problem would be to add --verbose to your linker flags.

为调试此问题提供有用信息的另一种方法是将 --verbose 添加到链接器标志。