75

実際、 Linux の-static gcc フラグは現在機能しません。GNU libc FAQ から引用させてください。

2.22. 静的にリンクされたプログラムでさえ、私には受け入れられない共有ライブラリが必要です。私に何ができる?

{AJ} NSS (詳細については、「info libc "Name Service Switch"」と入力してください) は、共有ライブラリがないと正しく動作しません。NSS では、プログラムを再リンクすることなく、1 つの構成ファイル (/etc/nsswitch.conf) を変更するだけで、さまざまなサービス (NIS、ファイル、db、hesiod など) を使用できます。唯一の欠点は、静的ライブラリが共有ライブラリにアクセスする必要があることです。これは、GNU C ライブラリによって透過的に処理されます。

解決策は、--enable-static-nss を使用して glibc を構成することです。この場合、サービスの dns とファイルのみを使用する静的バイナリを作成できます (これについては /etc/nsswitch.conf を変更します)。これらすべてのサービスに対して明示的にリンクする必要があります。例えば:

 gcc -static test-netdb.c -o test-netdb \
   -Wl,--start-group -lc -lnss_files -lnss_dns -lresolv -Wl,--end-group

このアプローチの問題点は、NSS ルーチンを使用するすべての静的プログラムをそれらすべてのライブラリとリンクする必要があることです。
{UD} 実際、このオプションでコンパイルされた libc が NSS を使用しているとは言えません。もうスイッチはありません。したがって、システム上のプログラムの動作に一貫性がなくなるため、 --enable-static-nss を使用しないことを強く お勧めします。

その事実に関して、Linuxで完全に機能する静的ビルドを作成する合理的な方法はありますか、または静的リンクはLinuxで完全に機能しませんか? 私は静的ビルドを意味します:

  • 動的ビルドとまったく同じように動作します (動作に一貫性のない static-nss は悪です!)。
  • glibc 環境と Linux バージョンの合理的なバリエーションで動作します。
4

6 に答える 6

47

これは非常に面倒なことだと思います。また、特定のユース ケースを処理するのに問題があるため、機能を「役に立たない」と呼ぶのは傲慢だと思います。glibc アプローチの最大の問題は、システム ライブラリ (gconv と nss) へのパスがハードコーディングされているため、構築されたものとは異なる Linux ディストリビューションで静的バイナリを実行しようとすると壊れることです。

とにかく、GCONV_PATH を適切な場所を指すように設定することで、gconv の問題を回避できます。これにより、Ubuntu でビルドされたバイナリを取得して、Red Hat で実行することができました。

于 2010-12-14T13:59:20.613 に答える
36

その事実に関して、Linuxで完全に機能する静的ビルドを作成する合理的な方法はありますか、または静的リンクはLinuxで完全に機能しませんか?

歴史的な参照がどこにあるのかわかりませんが、そうです、静的リンクは GNU システムでは死んでいます。(libc4/libc5 から libc6/glibc 2.x への移行中に死亡したと思います。)

この機能は、次の点で役に立たないと判断されました。

  • セキュリティの脆弱性。静的にリンクされたアプリケーションは、libc のアップグレードもサポートしていません。アプリが lib の脆弱性を含むシステムにリンクされた場合、静的にリンクされた実行可能ファイル内で永続化されます。

  • コードの肥大化。多くの静的にリンクされたアプリケーションが同じシステムで実行されている場合、標準ライブラリは再利用されません。これは、すべてのアプリケーションが独自のすべてのコピーを内部に含んでいるためです。(du -sh /usr/lib問題の程度を理解するようにしてください。)

10 ~ 15 年前の LKML と glibc メーリング リストのアーカイブを掘り下げてみてください。ずっと前にLKMLに関連するものを見たことがあると確信しています。

于 2010-08-09T08:54:03.770 に答える
28

静的リンクは、Linux の世界ではあまり愛されていないようです。これが私の見解です。

静的リンクの魅力を理解していない人は、通常、カーネルと下位レベルのオペレーティング システムの領域で働いています。多くの *nix ライブラリ開発者は、常に変化する 100 のライブラリをリンクしようとする避けられない問題に対処するために生涯を費やしてきました。彼らが快適に実行できるバク転を知りたい場合は、autotools を見てください。

しかし、他のすべての人がこれにほとんどの時間を費やすことを期待すべきではありません。静的リンクは、ライブラリ チャーンからのバッファリングに向けて長い道のりを歩むでしょう。開発者は、新しいライブラリ バージョンが表示された瞬間にアップグレードを強制されるのではなく、ソフトウェアのスケジュールに従ってソフトウェアの依存関係をアップグレードできます。これは、必然的に依存する多くの下位レベルのライブラリの流れを制御する必要がある、複雑なユーザー インターフェイスを持つユーザー向けアプリケーションにとって重要です。それが、私が常に静的リンクのファンであり続ける理由です。クロスコンパイルされた移植可能な C および C++ コードを静的にリンクできれば、世界中で成長し続けるさまざまなデバイスに複雑なソフトウェアをより迅速に配信できるため、世界をほぼカキのように扱うことができます。

他の観点からは、そこには多くの反対意見があり、オープンソース ソフトウェアがそれらすべてを許容するのは素晴らしいことです。

于 2016-07-06T23:49:24.720 に答える
13

NSS サービスに動的にリンクする必要があるからといって、他のライブラリに静的にリンクできないわけではありません。FAQ が言っていることは、「静的に」リンクされたプログラムでさえ、動的にリンクされたライブラリがいくつかあるということだけです。静的リンクが「不可能」または「機能しない」と言っているのではありません。

于 2010-08-07T12:31:39.780 に答える
13

他の回答に追加:

他の回答で述べられている理由により、ほとんどの Linux ディストリビューションには推奨されませんが、実際には、静的にリンクされたバイナリを実行するために特別に作成されたディストリビューションがあります。

スタリの説明から:

static linux は、各タスクと静的にリンクされている各ツール (st、surf、dwm、dmenu などの一部の X クライアントを含む) に最適なツールの厳選されたコレクションに基づいています。

また、可能であれば、glibc やその他の肥大化した GNU ライブラリを回避することで、バイナリ サイズの削減も目指しています (初期の実験では、静的にリンクされたバイナリは通常、動的にリンクされた glibc の対応するものよりも小さいことが示されています!!!)。これは、Ulrich Drepper が静的リンクについて考えていることとはかなり反対であることに注意してください。

静的にリンクされたバイナリがより速く起動するという副次的な利点により、ディストリビューションはパフォーマンスの向上も目標としています。

静的リンクは、依存関係の削減にも役立ちます。

詳しくは、静的リンクと動的リンクに関するこの質問をご覧ください。

于 2015-01-01T05:11:58.257 に答える