web-dev-qa-db-ja.com

Linux用の配布可能なバイナリを作成するときに、libstdc ++やlibgccを静的にリンクすることは良い習慣ですか?

コンテキスト:JNIを使​​用する オープンソースプロジェクト があります。自分でビルドすることも可能ですが、ほとんどのユーザーは標準のJava Maven、Gradle、SBTなどのツールを使用して、コンパイル済みのバイナリイメージを含むJARをダウンロードします。これはWindowsでは問題がありますが、Linuxでは複雑になります。

ほとんどのLinuxディストリビューションと互換性があるように、これらのパッケージを作成するときにどれだけ静的にリンクする必要があるのか​​と思います。たとえば、Alpine Linuxにはlibstdc ++が付属していないことを知っています。つまり、小さなDockerコンテナーでは失敗します。

古いバージョンの可能性もあります。たとえば、nmをざっと見ると、リンクしていることがわかります_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21および__vsnprintf_chk@@GLIBC_2.3.4。ホストのバージョンが3.4.21および2.3.4より古い場合はどうなりますか?

しかし、私が見たほとんどの文献は libgccにリンクしない を教えてくれます。それは本当ですか? clangに切り替えても同じですか(独自の標準ライブラリがありますか?)

3
Robert Fraser

静的リンクglibcは禁止事項です。私の理解では、これはディストリビューション用にカスタマイズされていることが多いので、異なるLinuxディストリビューション/リリースを実行しているマシンにそれを配布したくありません。 MUSLのように静的にリンクできるドロップインの代替品があります。私はそれらを試したことがないので、その点に関する残りは読者に任されています。他のすべてを静的にリンクすることは問題ありません。

私が非常にうまく使用した1つのアプローチは、古いLinuxリリースでバイナリをビルドすることです(可能な場合は静的リンクを行うことを含みます)。これらのバイナリは上位互換性があります。したがって、過去10年間のほとんどのディストリビューションでバイナリが実行されるという保証を自分で得ることができるはずです(指摘したように、アルパインはMUSLを使用しているため、互換性を確保するためにアルパインでビルドする必要がある場合があります)。技術的に言えば、互換性のために最新のリリースを使用して古いglibcバージョンをターゲットにすることができますが、古いリリースを使用する方が簡単であることがわかりました。

7
GrandmasterB

一般に、優れたシステムシチズンになるためには、システムライブラリにできる限り依存し、ライブラリを静的にリンクしないようにする必要があります。コードは、特定のABIに依存するのではなく、ソースレベルの依存関係のみを持つ必要があります。プロジェクトはオープンソースプロジェクトであるため、パッケージングを行っている人に、ターゲットシステムで使用可能なシステムライブラリを使用してアプリを再コンパイルさせるだけで問題ありません。これにより、システムにとって可能な限り小さな無駄のないアプリケーションが生成され、ユーザーが20の異なるプログラムに個別にパッチを適用する必要がなくなるため、セキュリティの脆弱性がある同じライブラリに静的にリンクするため、システム全体のセキュリティが向上します。

プロジェクトがクローズドソースソフトウェアであった場合、パッケージャがアプリケーションを再コンパイルできない可能性があるため、すべてのシステムを自分で再コンパイルする必要があるため、これはよりトリッキーになります。

さらに、すべての依存関係と静的にリンクされたユニバーサルアプリを提供することもできます。これにより、アプリをパッケージ化していないディストリビューションを使用しているユーザーが、自分で再コンパイルすることなくアプリを実行できます。静的にリンクされたプログラムを提供する場合、2つのオプションがあります。サポートされているターゲットシステムで使用できることがわかっているいくつかのライブラリを除くすべてを静的にリンクするか(これには独自の悪夢が付属します)、またはアプリをスナップまたはフラットパック。後者がユニバーサルアプリを提供する最も簡単な方法であることをお勧めします。

Linux用の配布可能なバイナリを作成するときに、libstdc ++やlibgccを静的にリンクすることは良い習慣ですか?

計画されているサポートされているターゲットシステムを確認する必要があります。 libstdc ++がプリインストールされていない可能性のある最小限のディストリビューションをサポートする予定の場合は、はい、静的にリンクする必要があります。それ以外の場合は、必要はありません。アプリが肥大化するだけです。これらの基本的なシステムライブラリは、異なるディストリビューション間でも非常に安定したABIを持つように設計されています。いくつかの注意事項を除けば、システムで使用できる場合は、システムにインストールされているどのバージョンでもアプリが問題なく動作することはほぼ確実です。

アプリケーションを静的にリンクする場合は、musl libcなど、静的にリンクするように設計されたlibcの使用を検討してください。

1
Lie Ryan