web-dev-qa-db-ja.com

-static-libgcc -static-libstdc ++を使用してコンパイルしても、libc.soに動的に依存する

可能な限り移植性の高い実行可能ファイルを作成しようとしています。いくつかの依存関係を削除した後、別のシステムでバイナリを実行しているときに次の問題に遭遇しました。

/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フラグも追加しようとしましたが、that binaryを実行しようとすると、結果が非​​常に奇妙になります。

$ 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のバージョンよりも2つのlessエントリがあります。つまり:

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)
22
Claudiu

GNU libcは静的にリンクされるように設計されていません。重要な機能、例えばgethostbynameおよびiconvは、静的バイナリでは誤動作するか、まったく機能しません。おそらくさらに悪いことに、いくつかの条件では、静的リンクの全体的なポイントがそのような依存関係を回避することであるにもかかわらず、静的バイナリは動的に開いて_libc.so.6_を使用しようとします。

代わりに Clibc または musl libc に対してプログラムをコンパイルする必要があります。

(これは少なくとも15年間当てはまりました。)

27
zwol

Libcがシステムの他の部分に依存している可能性があるため、libcの静的リンクはプログラムの移植性を改善しない可能性があることに最初に注意してください。カーネルバージョン。

-staticを使用するだけで完全な静的リンクを試してみたい場合は、トリックが必要です。使用されているすべてのライブラリの静的バージョンがインストールされている場合。

以下を使用して、プログラムに静的ライブラリのみがリンクされているかどうかを確認できます。

ldd binary_name

編集:

この問題のデバッグに役立つ情報を提供する別の方法は、リンカーフラグに--verboseを追加することです。

1
crash