ubuntu で実行可能ファイルを静的にリンクすると、その実行可能ファイルが mint os などの別のディストリビューション内で動作しない可能性はありますか? またはフェドーラ?プロセッサの種類が影響を受けることは知っていますが、それ以外に注意する必要があることはありますか? これがばかげた質問である場合は申し訳ありません。助けてくれてありがとう
8 に答える
いくつかのまれなケースがありますが、ほとんどの場合、静的リンクで良好な状態になっているはずです。頭に浮かぶのはlibnssです。この特定のライブラリを静的にリンクすることは基本的に不可能です。これは、その機能 (アクセス許可、認証、セキュリティ タスク) が原因です。ただし、glibc のバージョンが類似している限り、この問題については問題ありません。
プログラムがボリューム マネージャーなどのカーネルの微妙な機能を使用する必要がある場合、カーネル インターフェイスがわずかに変更される可能性があるため、プログラムがディストリビューション間で静的にリンクされて動作する可能性はほとんどありません。
ネットワーク サービス、GUI アプリケーション、言語ツール (コンパイラ/インタプリタなど) など、移植性について議論することさえ理にかなっている種類のほとんどの典型的なアプリケーションでは、このような問題は発生しません。
あるコンピューターでプログラムを静的にリンクしてから、システムが基本的に同じように動作する別のコンピューターにそのプログラムを移動すると、問題なく動作するはずです。これが静的リンクのポイントです。プログラムが依存する他のファイルがないこと - 完全に自己完結型であるため、実行できる限り、「ホスト」システムと同じように実行されます。
これは、プログラムが実行時に他のファイル (ライブラリ) の要素を組み込む動的リンクとは対照的です。動的にリンクされたプログラムを、依存するライブラリが異なる (または存在しない) 別のシステムに移動すると、動作しません。
ほとんどの場合、実行可能ファイルは問題なく動作します。実行可能ファイルが機能するために異常な存在に依存しない限り、問題はありません。(そして、異常な存在に依存している場合は、動的にリンクしても同じ問題が発生します。)
同じ CPU が使用されている限り、静的リンクは、異なる UNIX 環境間の互換性のために通常、動的リンクよりも安全です。
静的にリンクされたバイナリを失敗させるには、同じプロセッサ アーキテクチャを前提として、a.out バイナリ形式を使用してシステム上でリンクするなどの操作を行い、ELF を実行しているシステム上でそれを実行しようとする必要があります。リンクされたバージョンも同様に失敗します。
では、なぜ人々は定期的に静的リンクをしないのでしょうか? 2 つの理由:
- 実行可能ファイルが大きくなり、時には非常に大きくなり、
- ライブラリのバグが修正された場合、プログラムを再リンクしてバグ修正にアクセスする必要があります。ライブラリで重大なセキュリティ バグが修正された場合は、exe を再リンクして再配布する必要があります。
同様のハードウェア上の同様のバージョンのOSでのみ実行されることを保証できる限り、プログラムは静的にリンクされていれば正常に動作します。したがって、2.6 Linux用にビルドし、静的にリンクする場合は、(ほぼ)すべての2.6Linuxディストリビューションで問題なく実行できます。
GLIBCの一部を静的にリンクすることはできないため、それらを使用している場合は、とにかく動的にリンクする必要があることに注意してください。私が調査していたとき、メモリからネームサービススタッフ(nss)の部分に動的リンクが必要でした。
(たとえば)Linux用のプログラムを静的にリンクして、BSDまたはWindowsで実行されることを期待することはできません。BSDとUnixは、Linuxと同じようにシステムコールを表示または処理しません。BSDには有効にできるLinuxエミュレーションレイヤーがあるので、少しうそをつきますが、そのままでは機能しません。
いいえ、動作しません。ディストリビューションの独立性のための静的リンクは、古いUNIX時代の概念であり、推奨されていません。とにかく静的ライブラリほど多くのライブラリを利用できないという事実があります。
Linux Standard Baseの方法に従ってください。これは、可能な限り多くのクロスディストリビューションポータビリティを取得する唯一のチャンスです。
FreeBSDおよびSolaris用にプログラムする場合、LSBも正常に機能します。
それどころか。ディストリビューションや OS を超えてバイナリを動作させる可能性がどのようなものであれ、それらの可能性は静的リンクによって最大化されます。静的リンクにより、実行可能ファイルはライブラリに関して自己完結型になります。別のシステムに存在しないファイルを読み取ろうとすると、まだ問題が発生する可能性があります。
移植性の可能性をさらに高めるには、dietlibc または他の libc とリンクしてみてください。 Linux Journal の記事では、いくつかの候補について言及しています。小さくてシンプルな libc は、ディストリビューションごとに異なるファイルシステム内のものに依存する可能性が低くなります。
上記の理由により、絶対に必要でない限り、何かを静的にリンクすることは避けます。
そうは言っても、同じアーキテクチャの他の同様のカーネルで動作するはずです (つまり、linux 2.4.x を実行しているマシンで静的にリンクする場合、ローダー VDSO は Linux 2.6 では異なり、VDSO は仮想動的共有オブジェクトであり、カーネルがローダーコードを含むすべてのプロセスに公開する共有オブジェクト)。
その他の落とし穴には、/etc が思った場所にない、ログが別の場所にある、システム ユーティリティが存在しないか異なる (ubuntu は update-rc.d を使用し、RHEL は chkconfig を使用する) などがあります。
選択の余地がない場合もあります。私は、LVM2 の文字列ベースの cmdlib インターフェイスと通信して execv(). を使用するプログラムを作成していました。見よ、サポートする必要のあるディストリビューションの 30% にはそのライブラリが含まれておらず、入手する方法がありませんでした。そのため、バイナリ パッケージを作成するときに、静的オブジェクトに対してリンクする必要がありました。
glibc を使用している場合は、getpwnam() やその仲間のようなものが引き続き機能することを確信できます.. ハードコードされたパスを必ず監視してください (できれば、実行時に構成できるようにすることをお勧めします)。