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

时间:2014-10-10 17:04:40

标签: c++ c gcc glibc static-linking

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

/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)

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

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

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

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

怎么办?

编辑:

$ 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 +++

有趣的是,如果我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)

2 个答案:

答案 0 :(得分:25)

GNU libc并非设计为静态链接。重要的功能,例如gethostbynameiconv,会在静态二进制文件中出现故障或无法正常工作。可能更糟糕的是,在某些情况下,静态二进制文件将尝试动态打开并使用libc.so.6 ,即使静态链接的整个要点是避免这种依赖。

您应该针对uClibcmusl libc编译您的计划。

(这已经至少15年了。)

答案 1 :(得分:0)

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

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

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

ldd binary_name

修改

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