web-dev-qa-db-ja.com

CabalとStackの違いは何ですか?

昨日、私は Stack という新しいHaskellツールについて学びました。一見したところ、Cabalとほぼ同じ仕事をしているように見えます。それで、それらの違いは何ですか?スタックはCabalの代替品ですか?どの場合にCabalの代わりにStackを使用する必要がありますか? StackがCabalにできないことは何ですか?

84
ZhekaKozlov

スタックはCabalの代替品ですか?

はいといいえ。

どの場合にCabalの代わりにStackを使用する必要がありますか? StackがCabalにできないことは何ですか?

Stackdefaultによってキュレーションされたスタックパッケージを使用するため、パッケージは一緒にビルドされることがわかっています。カバルでは、カバル地獄に襲われる可能性があります。 Stackはパッケージをローカルにキャッシュするため、次回そのパッケージ(またはその推移的な依存関係)を使用するときにすべてを最初からコンパイルすることはありません。スタック以外のパッケージを使用するためのプロビジョニングもあるため、パッケージがスタックスナップショットに存在しない場合でも行ってください。

個人的に、私はStackが好きで、すべてのHaskell開発者にStackを使用することをお勧めします。それらの開発はfastです。彼らは後方互換性について(それほど)心配しません。そして、それはmuchより良いUXを持っています。そして、stackCabalがまだ提供していないものがあります:

  • StackはGHCをダウンロードして、隔離された場所に保管します。
  • Dockerサポート(Haskellアプリケーションのデプロイに非常に便利です)
  • 再現可能なHaskellスクリプト :パッケージのバージョンを特定でき、問題なく常に実行されることを保証できます。
  • stack build --fast --file-watchを実行する機能。存在するローカルファイルを変更すると、これは自動的に再構築されます。 --pedanticオプションと一緒に使用することは、私にとって大きな問題です。
  • external git repositoryを依存関係として指定する機能。 Cabal 2.4 で始まるcabalは、依存関係として外部gitリポジトリもサポートします。 (ここで注意すべき点は、Stackがこの機能を3年以上使用しており、Cabalがついに追いついたことです)。
  • Stackは、 templates を使用したプロジェクトの作成をサポートしています。また、独自のカスタムテンプレートもサポートしています。
  • スタックには組み込みの hpack がサポートされています。これは、業界でより広く使用されているyamlファイルを使用して、cabalファイルを書き込むための代替(IMO、より良い)方法を提供します。
  • Interoにはスムーズなエクスペリエンスがあります Stackを使用する場合

違いを説明するニースのブログ投稿があります: なぜStackはCabalではないのですか?

58
Sibi

以下では、比較される2つのツールをcabal-installおよびstackと呼びます。特に、cabal-installを使用して、両方のツールで使用される一般的なインフラストラクチャであるCabalライブラリとの混乱を避けます。大まかに言えば、cabal-installstackCabalのフロントエンドであり、それらの重要な違いはデフォルトのワークフローに要約されます次のとおりです。

  • デフォルトでは、cabal-installは、プロジェクトのビルドを要求されたときに、その.cabalファイルで指定された依存関係を調べ、依存関係ソルバーを使用して(可能な場合)それを満たすパッケージとパッケージのバージョン。このセットは、 Hackage 全体(すべてのパッケージとすべてのバージョン、過去と現在)から取得されます。実行可能なビルドプランが見つかると、デフォルトで、選択されたバージョンの依存関係がインストールされ、~/.cabalのどこかにあるインストール済みパッケージの単一データベースに登録されます。

  • 一方、stackは、最初に stack.yamlresolverフィールドを確認します。そのフィールドは通常、 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.yamlextra-depsの適切なフィールドを設定することにより、使用中のStackageスナップショットからは利用できないパッケージを使用でき、packagesカスタムlocationで、Hackageにないパッケージ用)。これらの非Stackageパッケージは、スナップショットから分離して、プロジェクトごとにインストールされます。また、stack solverコマンドもあります。このコマンドは、Hackage(つまり、非Stackage)依存関係の自動依存関係解決を実行します。

最後に、バージョンを緩和する代替方法として、 Nixスタイルのローカルビルド のサポートがcabal-installに追加されていることに言及する価値があります。 cabal sandboxよりも潜在的に便利な競合。この機能は、プレビューリリースとしてcabal-install 1.24から入手できます。

27
duplode

FAQから収集できることから、StackはCabalライブラリを使用しているが、cabal.exeバイナリ(より正確にはcabal-installとして知られています)。プロジェクトの目的は、自動サンドボックス化と依存性地獄の回避であるように見えます。

つまり、同じCabalパッケージ構造を使用し、このようなものを管理するための異なるフロントエンドを提供するだけです。 (おもう!)

9