Loading article…
依存関係地獄とは、他のソフトウェアパッケージの特定のバージョンに依存するソフトウェアパッケージをインストールした一部のソフトウェアユーザーが感じるフラストレーションを表す俗語です。 [1]
依存関係の問題は、複数のパッケージが同じ共有パッケージまたはライブラリに依存しているが、それらのパッケージが共有パッケージの異なる非互換バージョンに依存している場合に発生します。共有パッケージまたはライブラリを 1 つのバージョンでしかインストールできない場合、ユーザーは依存パッケージの新しいバージョンまたは古いバージョンを取得して問題に対処する必要があります。これにより、他の依存関係が壊れ、問題が別のパッケージ セットに押し付けられる可能性があります。
問題
依存地獄にはいくつかの形があります。
- 多くの依存関係
- アプリケーションは多くのライブラリに依存しているため、ダウンロードに時間がかかり、ディスク容量が大量に必要となり、移植性も非常に高くなります (すべてのライブラリがすでに移植されているため、アプリケーション自体の移植は容易です)。また、すべての依存関係を見つけるのが難しい場合もありますが、リポジトリを用意することで解決できます (下記参照)。これは部分的には避けられないことです。特定のコンピューティング プラットフォーム( Javaなど) で構築されたアプリケーションではそのプラットフォームのインストールが必要ですが、他のアプリケーションでは必要ありません。これは、アプリケーションが大きなライブラリの小さな部分を使用する場合 (コードのリファクタリングで解決できます)、または単純なアプリケーションが多くのライブラリに依存している場合に特に問題になります。[2]
- 依存関係の長い連鎖
- が
appに依存しliba、 は に依存しlibb、... は に依存し、 は に依存しますlibz。これは、依存関係を手動で解決する必要がある場合の「多くの依存関係」とは異なります。たとえば、 をインストールしようとすると、まずappをインストールするように求められ、 をインストールしようとすると、次に をインストールするように求められます。ただし、この長い依存関係のチェーン中に、同じパッケージの異なる 2 つのバージョンが必要になるという競合が発生することがあります[3] (以下の競合する依存関係を参照)。これらの長い依存関係のチェーンは、すべての依存関係を自動的に解決するパッケージ マネージャーを使用することで解決できます。面倒なこと (すべての依存関係を手動で解決すること) 以外に、手動での解決により、依存関係の循環や競合が隠される可能性があります。libalibalibb - 競合する依存関係
- あるソフトウェアの依存関係を解決すると、モグラ叩きのように別のソフトウェアの互換性が失われる場合があります。
app1が に依存しlibfoo 1.2、app2が に依存しlibfoo 1.3、 の異なるバージョンをlibfoo同時にインストールできない場合、app1と をapp2同時に使用 (インストーラが依存関係をチェックする場合はインストール) することはできません。可能であれば、異なる依存関係の同時インストールを許可することでこの問題を解決します。または、新しい依存関係をインストールするには、既存の依存関係を、それに依存するすべてのソフトウェアとともにアンインストールする必要があります。 Linux システムで異なるディストリビュータからパッケージをインストールする場合 (非推奨) [要出典]の問題は、結果として生じる依存関係の長いチェーンにより、何千ものパッケージが依存するC 標準ライブラリ( GNU C ライブラリなど) の競合バージョンが発生する可能性があることです。これが発生した場合、ユーザーはそれらのパッケージをすべてアンインストールするように求められます。 - 循環依存関係
application Aが の特定のバージョンに依存し、そのバージョンがないと実行できない場合application B、一方、 はapplication Bの特定のバージョンに依存し、そのバージョンがないと実行できないapplication A場合、アプリケーションをアップグレードすると別のアプリケーションが壊れます。このスキームは分岐が深くなる可能性があります。コアシステムに影響したり、ソフトウェア自体を更新したりすると、その影響は非常に大きくなる可能性があります。特定のランタイムライブラリ (B) が機能することを必要とするパッケージマネージャー (A) は、このライブラリ (B) を次のバージョンにアップグレードするときに、プロセスの途中でパッケージマネージャー (A) 自体が壊れる可能性があります。ライブラリ (B) のバージョンが正しくないため、パッケージマネージャー (A) が壊れているため、ライブラリ (B) のロールバックやダウングレードは不可能です。通常の解決策は、両方のアプリケーションをダウンロードして展開することです。一時的な環境内から行う場合もあります。- パッケージマネージャーの依存関係
- 用意されたパッケージをパッケージマネージャ(例:APT )経由でインストールすると依存性地獄が発生する可能性はありますが[4] 、主要なパッケージマネージャは成熟しており、公式リポジトリは適切に管理されているため、その可能性は低いです。これは、 Debianの現在のリリースやUbuntuなどの主要な派生製品の場合に当てはまります。ただし、パッケージインストーラ(例: RPMやdpkg )経由でパッケージを直接インストールすると、依存性地獄が発生する可能性があります。
- ダイヤモンド依存
- ライブラリ A がライブラリ B と C に依存している場合、B と C は両方ともライブラリ D に依存しますが、B にはバージョン D.1 が必要で、C にはバージョン D.2 が必要です。最終的な実行可能ファイルには D のバージョンが 1 つしか存在できないため、ビルドは失敗します。
- yum [5]のようなパッケージマネージャーは、リポジトリ内のパッケージ間で競合が発生しやすく、 CentOSやRed Hat Enterprise LinuxなどのLinuxディストリビューションでは依存関係地獄を引き起こします。
ソリューション
- 依存関係の削除
- 多くのソフトウェア ライブラリは、ほとんどのユーザーのニーズを満たすために、寛大な方法で記述されていますが、ホスト コードでは機能のごく一部しか必要とされない場合があります。ソースを調べることで、機能をはるかにコンパクトな方法で書き直すことができます (ライセンスに関して)。一般に、これによりアプリケーション コードが大幅に削減され、その後のメンテナンス コストも削減され、プログラマーはソフトウェア記述スキルを向上させることができます。
- バージョン番号
- この問題の非常に一般的な解決策は、標準化された番号体系を持つことであり、ソフトウェアは各バージョン(メジャーバージョンとも呼ばれる)に特定の番号を使用し、各リビジョン(マイナーバージョンとも呼ばれる)にもサブ番号を使用します(例:10.1、または5.7 )。メジャーバージョンは、そのバージョンを使用していたプログラムが互換性がなくなった場合にのみ変更されます。マイナーバージョンは、他のソフトウェアの動作を妨げない程度の単純なリビジョンでも変更される可能性があります。このような場合、ソフトウェアパッケージは、特定のメジャーバージョンと任意のマイナーバージョン(特定のマイナーバージョン以上)を持つコンポーネントを要求するだけで済みます。このようにすることで、マイナーバージョンが変更されても、それらは引き続き動作し、依存関係は正常に解決されます。セマンティックバージョニング(別名「SemVer」[6])は、特別にフォーマットされた番号を使用してソフトウェアバージョン管理スキームを作成する技術仕様を生成する取り組みの一例です。
- アプリケーションごとのプライベートバージョン
- Windows 2000で導入されたWindows ファイル保護は、アプリケーションがシステム DLL を上書きするのを防止しました。開発者は代わりに、アプリケーションのディレクトリにあるアプリケーションごとのライブラリのコピーである「プライベート DLL」を使用するように推奨されました。これは、ローカル パスがシステム ディレクトリよりも常に優先されるという Windows 検索パスの特性を利用して、システム全体のライブラリがあります。これにより、特定のアプリケーション バージョンによるライブラリ バージョンの容易かつ効果的なシャドウイングが可能になり、依存関係地獄を防止できます。[7]
- TrueOS ( FreeBSDベースのオペレーティングシステム)の前身であるバージョン8.2までのPC-BSDは、パッケージと依存関係を/Programs内の自己完結型ディレクトリに配置し、システムライブラリがアップグレードまたは変更された場合の破損を回避します。パッケージ管理には独自の「PBI」(プッシュボタンインストーラ)を使用します。[8]
- 複数のバージョンの並列インストール
- バージョン番号付けソリューションは、バージョン番号付けをオペレーティング システムでサポートされている機能に昇格させることで改善できます。これにより、アプリケーションは一意の名前とバージョン番号の制約によってモジュール/ライブラリを要求できるようになり、ライブラリ/モジュールのバージョンを仲介する責任がアプリケーションからオペレーティング システムに効果的に移行されます。共有モジュールは、モジュールの以前のバージョンまたはそれ以降のバージョンに依存するアプリケーションを壊すリスクなしに、中央リポジトリに配置できます。各バージョンには、同じモジュールの他のバージョンと並んで独自のエントリが与えられます。
- このソリューションは、Windows Vista以降のMicrosoft Windowsオペレーティングシステムで使用されています。Windows Vistaでは、グローバルアセンブリキャッシュは、関連するサービスを備えた中央レジストリの実装であり、インストールシステム/パッケージマネージャーと統合されています。Gentoo Linuxは、スロットと呼ばれる概念でこの問題を解決し、共有ライブラリの複数のバージョンをインストールできるようにします。[9]
- スマートパッケージ管理
- 一部のパッケージ マネージャーは、相互に依存するソフトウェア コンポーネントを同時にアップグレードするスマート アップグレードを実行できるため、メジャー番号の非互換性の問題も解決されます。
- 現在のLinuxディストリビューションの多くは、依存性の問題を解決するためにリポジトリベースのパッケージ管理システムも実装しています。これらのシステムは、 RPM、dpkg 、またはその他のパッケージング システムの上位層であり、定義済みのソフトウェア リポジトリを検索して依存性を自動的に解決するように設計されています。これらのシステムの例としては、Apt、Yum、Urpmi、ZYpp、Portage、Pacmanなどがあります。通常、ソフトウェア リポジトリは、 FTPサイトまたは Web サイト、ローカル コンピュータ上のディレクトリ、またはネットワーク経由で共有されているディレクトリ、またはそれほど一般的ではありませんが、 CD や DVD などのリムーバブル メディア上のディレクトリです。これにより、これらのリポジトリにパッケージ化されたソフトウェアの依存性地獄が解消されます。これらのリポジトリは通常、 Linux ディストリビューション プロバイダーによって保守され、世界中にミラーリングされます。これらのリポジトリは巨大であることが多いですが、すべてのソフトウェアをリポジトリに含めることは不可能であるため、依存性地獄が発生することがあります。すべての場合において、リポジトリのメンテナーは依存性地獄に直面しています。[4]
- インストーラーのオプション
- ソフトウェアはそれぞれ異なる依存関係を持っているため、新しいパッケージごとにさらにいくつかのパッケージのインストールが必要になるため、依存関係要件の悪循環、つまり要件のツリーがどんどん拡大していく可能性があります。Debian のAdvanced Packaging Toolなどのシステムでは、ユーザーにさまざまなソリューションを提示し、ユーザーが必要に応じてソリューションを受け入れるか拒否できるようにすることで、この問題を解決できます。
- プログラミングの容易な適応性
- アプリケーション ソフトウェアが、プログラマーが OS、ウィンドウ マネージャー、またはデスクトップ環境を扱うインターフェイス レイヤーを新しい標準や変更される標準に簡単に適応できるように設計されている場合、プログラマーは環境作成者またはコンポーネント ライブラリ設計者からの通知を監視し、ユーザー向けの更新でソフトウェアをすばやく調整するだけで済みます。すべて最小限の労力で、コストと時間のかかる再設計は必要ありません。この方法により、プログラマーは、自分たちが依存している人々に、関係者の誰にとっても負担にならない適切な通知プロセスを維持するよう圧力をかけるようになります。
- コード開発と保守における厳格な互換性要件
- アプリケーションとライブラリが下位互換性の保証を念頭に置いて開発および保守されている場合、アプリケーションまたはライブラリは、何も壊すことなくいつでも新しいバージョンに置き換えることができます。これにより、多数の依存関係が軽減されるわけではありませんが、パッケージ マネージャーまたはインストーラーの作業ははるかに簡単になります。
- ソフトウェアアプライアンス
- 依存関係の問題を回避するもう 1 つの方法は、アプリケーションをソフトウェア アプライアンスとして展開することです。ソフトウェア アプライアンスは、依存関係を事前に統合された自己完結型のユニットにカプセル化するため、ユーザーはソフトウェアの依存関係の解決について心配する必要がなくなります。代わりに、その負担はソフトウェア アプライアンスの開発者に移ります。コンテナーとそのイメージ ( Dockerや Docker Hubによって提供されるものなど) は、ソフトウェア アプライアンスの実装と見なすことができます。
- ポータブルアプリケーション
- 完全に自己完結型で、何もインストールする必要がないアプリケーション(または既存の従来型アプリケーションのバージョン)。必要なコンポーネントがすべて含まれるようにコード化されているか、必要なファイルをすべて独自のディレクトリ内に保持するように設計されており、依存関係の問題は発生しません。これらは、接続されているシステムとは独立して実行できることが多いです。RISC OSおよびROX Desktop for Linuxのアプリケーションは、アプリケーションディレクトリを使用します。これは、ほぼ同じように機能します。プログラムとその依存関係は、独自のディレクトリ(フォルダー)に自己完結型です。[10]
- この配布方法は、Unix 系プラットフォーム向けに設計されたアプリケーションを Windows に移植する場合にも有効であることが証明されていますが、最も顕著な欠点は同じ共有ライブラリが複数インストールされることです。たとえば、gedit、GIMP、HexChatの Windows インストーラーにはすべて、これらのプログラムがウィジェットのレンダリングに使用するGTKツールキットの同一のコピーが含まれています。一方、各アプリケーションで異なるバージョンの GTK が必要な場合は、これが正しい動作であり、依存関係地獄をうまく回避できます。
プラットフォーム固有
特定のコンピューティング プラットフォームでは、「依存関係地獄」は多くの場合、ローカル固有の名前、通常はコンポーネントの名前で呼ばれます。
- DLL ヘル – 16 ビットMicrosoft Windowsで発生する依存関係ヘルの一種。
- 拡張機能の競合–従来の Mac OS で発生する依存関係地獄の一種。
- JAR 地獄- 2004 年にApache Mavenなどのビルド ツールがこの問題を解決する前に、Java ランタイム環境 で発生していた依存関係地獄の一種。[引用が必要]
- RPM地獄 - Red Hat Linuxディストリビューションや、パッケージマネージャとしてRPMを使用するその他のディストリビューションで発生する依存関係地獄の一種。 [11]
参照
- キャッチ22何かがそれ自体の否定に依存する状況を文学的に描写したもの
- 構成管理 – ソフトウェアのバージョンを管理するための技術とツール
- 結合 – ソフトウェア成果物間の依存関係の形式
- 動的なデッドコードの除去
- パッケージマネージャー
- PBI
- ソフトウェアアプライアンス
- 静的ライブラリ
- サプライチェーン攻撃
- Nix パッケージ マネージャー
- 左パッド
参考文献
- ^ Michael Jang (2006). Linux annoyances for geeks . O'Reilly Media. p. 325. ISBN 9780596552244. 2012年2月16日閲覧。
- ^ Donald, James (2003-01-25). 「共有ライブラリの移植性の向上」(PDF)。プリンストン大学。2007-09-26のオリジナル(PDF)からアーカイブ。2010-04-09に取得。
- ^ Stevens, Al (2001-05-01). 「見つけられるのは良い仕事; 依存関係カルーセル」J-DDJ . 26 (5). www.drdobbs.com/blog: 121–124. ISSN 1044-789X. 2011-08-11 にオリジナルからアーカイブ。2010-04-10に取得。
- ^ ab Pjotr Prins; Jeeva Suresh & Eelco Dolstra (2008-12-22). 「Nix はすべての Linux ディストリビューションの依存関係地獄を修正します」。linux.com。2015-07-08 にオリジナルからアーカイブ。2013-05-22に取得。APT
、RPM、FreeBSD Ports Collection を含むすべての一般的なパッケージ マネージャーは、破壊的なアップグレードの問題を抱えています。アップグレードを実行すると (単一のアプリケーションであれ、オペレーティング システム全体であれ)、パッケージ マネージャーは現在システムにあるファイルを新しいバージョンで上書きします。パッケージが常に完全に下位互換性がある限り、これは問題にはなりませんが、現実の世界では、パッケージは完全に下位互換性があるわけではありません。Firefox をアップグレードし、パッケージ マネージャーが GTK の新しいバージョンも必要であると判断したとします。新しい GTK が下位互換性が十分でない場合、システム上の他のアプリケーションが突然動作しなくなる可能性があります。 Windows の世界では、同様の問題が DLL 地獄として知られていますが、依存関係地獄は、Unix の世界でも同様に、あるいはそれ以上に大きな問題です。これは、Unix プログラムが多くの外部依存関係を持つ傾向があるためです。
- ^ 「Yum Dependency Hell」。2016年12月19日時点のオリジナルよりアーカイブ。2015年12月28日閲覧。
- ^ 「プロジェクトウェブサイト: semver.org」。
- ^ Anderson, Rick (2000-01-11). 「DLL 地獄の終焉」. microsoft.com. 2001-06-05 時点のオリジナルからアーカイブ。2010-07-07に取得。
- ^ pbiDIR
- ^ gentoo.org のスロット
- ^ 「アプリケーション ディレクトリ」 。2013年9 月 7 日閲覧。
- ^ Weinstein, Paul (2003-09-11). 「Linux は迷惑か?」. linuxdevcenter.com . 2010-04-10閲覧。
外部リンク
- コンテキスト独立性
- 依存関係ウォーカー
- 暗黙の依存関係
- Mac依存
