Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

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?

I tried adding the -static flag as well, however when I try to run that binary the result is very strange:

$ 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 ldd the version without -static, it has two less entries than the version with -static, namely:

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)
like image 472
Claudiu Avatar asked Oct 10 '14 17:10

Claudiu


2 Answers

GNU libc is not designed to be statically linked. Important functions, e.g. gethostbyname and 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.

You should compile your program against uClibc or musl libc instead.

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

like image 63
zwol Avatar answered Nov 19 '22 01:11

zwol


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.

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.

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.

like image 26
crash Avatar answered Nov 19 '22 02:11

crash