web-dev-qa-db-ja.com

Linuxの静的リンクは死んでいますか?

実際、Linuxでは-staticgccフラグは機能しません。 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の使用はhighly推奨notです。これにより、システム上のプログラムの動作に一貫性がなくなるためです。

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

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

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

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

この機能は、以下の観点から役に立たないと見なされました。

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

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

10〜15年前のLKMLとglibcのメールリストアーカイブを掘ってみてください。かなり前に、LKMLに関連するものを見てきました。

26
Dummy00001

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

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

39
Ketil

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

静的リンクの魅力を感じない人は、通常、カーネルと下位レベルのオペレーティングシステムの領域で働きます。多くの* nixライブラリ開発者は、絶え間なく変化する100のライブラリをリンクしようとする避けられない問題に対処するために生涯を費やしてきました。快適に動作するバックフリップを知りたい場合は、オートツールをご覧ください。

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

他の観点からは、そこに異議を唱えることはたくさんあり、オープンソースソフトウェアがそれらすべてを可能にしているのは素晴らしいことです。

19
moodboom

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

12
Dean Harding

静的リンクが復活しました!

  • 多くの(ほとんど?)Goプログラミング言語の実行可能ファイルは静的にリンクされています。
    • 増加した移植性と下位互換性が人気の理由の1つです。
  • 他のプログラミング言語でも、Haskellなどの静的リンクを実際に簡単にするための同様の取り組みがあります(私はこれに取り組んでいます effort )。
  • 構成可能Linuxディストリビューション/ NixOS / nixpkgs のようなパッケージセットにより、大部分をリンク可能そのパッケージの静的(たとえば、そのpkgsStaticパッケージセットは、あらゆる種類の静的にリンクされた実行可能ファイルを提供できます)。
  • 静的リンクにより、リンク時に未使用コードの除去が改善され、実行可能ファイルが小さくなります。
  • musl のようなlibcs​​は、静的リンクを簡単かつ正確にします。
  • いくつかの大きなソフトウェアindustryリーダーはこれに同意します。たとえば、 Googleは静的リンクを対象とした新しいlibcを作成しています "静的な非PIEおよび静的なPIEリンクをサポートする"「現時点では、動的な読み込みとリンクのサポートに投資するつもりはありません」)。
10
nh2

他の回答を追加:

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

Staliの説明から:

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

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

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

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

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

9