昨日、私は Stack という新しいHaskellツールについて学びました。一見したところ、Cabalとほぼ同じ仕事をしているように見えます。それで、それらの違いは何ですか?スタックはCabalの代替品ですか?どの場合にCabalの代わりにStackを使用する必要がありますか? StackがCabalにできないことは何ですか?
スタックはCabalの代替品ですか?
はいといいえ。
どの場合にCabalの代わりにStackを使用する必要がありますか? StackがCabalにできないことは何ですか?
Stack
はdefaultによってキュレーションされたスタックパッケージを使用するため、パッケージは一緒にビルドされることがわかっています。カバルでは、カバル地獄に襲われる可能性があります。 Stackはパッケージをローカルにキャッシュするため、次回そのパッケージ(またはその推移的な依存関係)を使用するときにすべてを最初からコンパイルすることはありません。スタック以外のパッケージを使用するためのプロビジョニングもあるため、パッケージがスタックスナップショットに存在しない場合でも行ってください。
個人的に、私はStackが好きで、すべてのHaskell開発者にStackを使用することをお勧めします。それらの開発はfastです。彼らは後方互換性について(それほど)心配しません。そして、それはmuchより良いUXを持っています。そして、stack
はCabal
がまだ提供していないものがあります:
stack build --fast --file-watch
を実行する機能。存在するローカルファイルを変更すると、これは自動的に再構築されます。 --pedantic
オプションと一緒に使用することは、私にとって大きな問題です。違いを説明するニースのブログ投稿があります: なぜStackはCabalではないのですか?
以下では、比較される2つのツールをcabal-installおよびstackと呼びます。特に、cabal-installを使用して、両方のツールで使用される一般的なインフラストラクチャであるCabalライブラリとの混乱を避けます。大まかに言えば、cabal-installとstackはCabalのフロントエンドであり、それらの重要な違いはデフォルトのワークフローに要約されます次のとおりです。
デフォルトでは、cabal-installは、プロジェクトのビルドを要求されたときに、その.cabal
ファイルで指定された依存関係を調べ、依存関係ソルバーを使用して(可能な場合)それを満たすパッケージとパッケージのバージョン。このセットは、 Hackage 全体(すべてのパッケージとすべてのバージョン、過去と現在)から取得されます。実行可能なビルドプランが見つかると、デフォルトで、選択されたバージョンの依存関係がインストールされ、~/.cabal
のどこかにあるインストール済みパッケージの単一データベースに登録されます。
一方、stackは、最初に stack.yaml
のresolver
フィールドを確認します。そのフィールドは通常、 Stackagesnapshotを指定します。これは、相互に既知であるfixedバージョンを持つHackageパッケージのサブセットです互換性があります。 stackは、デフォルトで、スナップショットによって提供されるもののみを使用して依存関係を満たそうとします。 1つのスナップショットからインストールされたパッケージは、異なる分離されたデータベースに登録され、GHCの個別のインストールは、スナップショットに必要なものを考慮して維持されます。このアプローチは、インストールされたパッケージ間にバージョンの非互換性がないことを保証することにより、少し柔軟性を犠牲にします(cabal-installで単一のパッケージデータベースを使用する場合の一般的な問題、 この記事 )、およびexactプロジェクトのビルドに使用される依存関係のバージョンを常に把握できること(これは、再現可能なビルドを保証するのに役立ちます)完全に肉付けされたプロジェクト、およびコンパニオン.hs
ファイルなしで自己完結型.cabal
スクリプトの依存関係を簡単に指定するため)。
上記の説明は、各ツールのデフォルトのワークフローを対象としていることに注意してください。 stackでできることの大部分は、cabal-installを使用して、デフォルトからステップアウトすることで(またはその逆)、何らかの方法で(おそらく便利ではない)達成できます。特に:
cabal-installcabal sandbox
コマンドを使用して各プロジェクトの分離パッケージデータベースをサポートしますが、stackおよびStackageスナップショットとは異なり、インストール済みパッケージをプロジェクト間で共有することはできません。 。 .cabal
とは別に、ビルドに使用される依存関係のバージョンをcabal freeze
とは別に修正することもできます。 (1つの関連するstack機能をcabal-installなしで使用すると、個別のGHCインストール、つまりstack setup
を管理できます。)
stackプロジェクトは、Hackageからは利用できるがStackageからは利用できないパッケージに対してstack.yaml
(extra-deps
の適切なフィールドを設定することにより、使用中のStackageスナップショットからは利用できないパッケージを使用でき、packages
カスタムlocation
で、Hackageにないパッケージ用)。これらの非Stackageパッケージは、スナップショットから分離して、プロジェクトごとにインストールされます。また、stack solver
コマンドもあります。このコマンドは、Hackage(つまり、非Stackage)依存関係の自動依存関係解決を実行します。
最後に、バージョンを緩和する代替方法として、 Nixスタイルのローカルビルド のサポートがcabal-installに追加されていることに言及する価値があります。 cabal sandbox
よりも潜在的に便利な競合。この機能は、プレビューリリースとしてcabal-install 1.24から入手できます。
FAQから収集できることから、StackはCabalライブラリを使用しているが、cabal.exe
バイナリ(より正確にはcabal-installとして知られています)。プロジェクトの目的は、自動サンドボックス化と依存性地獄の回避であるように見えます。
つまり、同じCabalパッケージ構造を使用し、このようなものを管理するための異なるフロントエンドを提供するだけです。 (おもう!)