LoginSignup
3

More than 5 years have passed since last update.

Stackでextra-depsを自動設定する方法の比較

Last updated at Posted at 2016-08-11

Stackで不用意に依存関係を触って失敗したので、extra-depsを設定する方法についてちゃんと調べてみました。stack solverstack init --solverの振舞いの相違について例を用いて説明します。

Stackのバージョンは0.1.10.0 i386です。執筆時点でのltsの最新バージョンは6.11です。

またstackコマンドには適宜--forceを付けていると読み替えてください。

入力例

元はstack new solver-test new-templateで生成したものです。それを、Stackageに含まれないuriパッケージと依存関係に起因するエラーの原因となるgtkパッケージを使うように編集したわざとらしい例になっています。

solver-test.cabal
name:                solver-test
version:             0.1.0.0
synopsis:            Initial project template from stack
description:         Please see README.md
homepage:            https://github.com/githubuser/solver-test#readme
license:             BSD3
license-file:        LICENSE
author:              Author name here
maintainer:          example@example.com
copyright:           2016 Author name here
category:            Web
build-type:          Simple
-- extra-source-files:
cabal-version:       >=1.10

library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
  default-language:    Haskell2010

executable solver-test-exe
  hs-source-dirs:      app
  main-is:             Main.hs
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  build-depends:       base
                     , solver-test
                     , gtk
                     , uri
  default-language:    Haskell2010

test-suite solver-test-test
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  build-depends:       base
                     , solver-test
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

source-repository head
  type:     git
  location: https://github.com/githubuser/solver-test
app/Main.hs
module Main where

import Lib
import Graphics.UI.Gtk
import Text.URI

main :: IO ()
main = return ()

とりあえずstack init

stack initすると次のようなメッセージが出力されます。

Writing default config file to: /home/.../dev/haskell/solver-test/stack.yaml
Basing on cabal files:
- /home/.../dev/haskell/solver-test/solver-test.cabal

Checking against build plan lts-6.10

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


Checking against build plan lts-5.15

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


Checking against build plan nightly-2016-08-06

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


Checking against build plan nightly-2016-05-25

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


Checking against build plan lts-6.11

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


Checking against build plan lts-5.18

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


There was no snapshot found that matched the package bounds in your .cabal files.
Please choose one of the following commands to get started.

    stack init --resolver lts-6.10
    stack init --resolver lts-5.15
    stack init --resolver nightly-2016-08-06
    stack init --resolver nightly-2016-05-25
    stack init --resolver lts-6.11
    stack init --resolver lts-5.18

You'll then need to add some extra-deps. See:

    https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md#extra-deps

You can also try falling back to a dependency solver with:

    stack init --solver

長ったらしいですが、「uriパッケージが見つからない」ということをスナップショットのバージョンごとに言っているだけです。

さらに後半部分では次に試すべきことが2つ書かれています。
1. stack init --resolver xxxの後、extra-depsを編集。
2. stack init --solver

まずは1.の方法から見てみます。

1.の方法 - stack solver

今回はresolverとしてlts-6.10を選びます。

$ stack init --resolver lts-6.10 --force
Writing default config file to: /home/.../dev/haskell/solver-test/stack.yaml
Basing on cabal files:
- /home/.../dev/haskell/solver-test/solver-test.cabal

Checking against build plan lts-6.10

* Build plan did not match your requirements:
    uri not found
    - solver-test requires -any


Selected resolver: lts-6.10
Wrote project config to: /home/.../dev/haskell/solver-test/stack.yaml

無事stack.yamlが生成されたので、次はextra-depsへの記述を行います。記述内容はstack solverで計算させることが出来ます。時間とメモリを食う作業なので注意。

$ stack solver
Asking cabal to calculate a build plan, please wait
This command is not guaranteed to give you a perfect build plan
It's possible that even with the changes generated below, you will still need to do some manual tweaking
extra-deps:
- uri-0.1.6.4

To automatically modify your stack.yaml file, rerun with '--modify-stack-yaml'

今回extra-depsに記述するべき内容が出力されるので、これをstack.yamlにコピペしてやればOKです。
また、メッセージの最後にある通り、--modify-stack-yamlを付けてやればstack.yamlを自動で編集してくれます。但し、結果を覚えてくれる訳ではないので同じだけ時間がかかります。

2.の方法 - stack init --solver

次に2.の方法を試してみます。
stack init --solverを実行するとstack.yamlが次のような内容になります。

stack.yaml(抜粋)
# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
resolver: ghc-7.10.3

# Local packages, usually specified by relative directory name
packages:
- '.'

# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
extra-deps:
- cairo-0.13.3.0
- gio-0.13.3.0
- glib-0.13.4.0
- gtk-0.14.5
- pango-0.13.3.0
- safe-0.3.9
- uri-0.1.6.4
- utf8-string-1.0.1.1

resolverがghcになっていることに注意してください。この場合stackは、Stackageのスナップショットではなくコンパイラ付属のパッケージを使用します。実際extra-depsに追加されたcairogioglibgtkpangosafeutf8-stringはStackage(例えばlts-6.10)に含まれているものです。

そしてこれはビルドに失敗し、次のようなエラーを出力します。

    /tmp/stack20983/cairo-0.13.3.0/Setup.hs:5:8:
        Could not find module ‘Gtk2HsSetup’
        Use -v to see a list of the files searched for.

Gtk2HsSetupgtk2hs-buildtoolsというパッケージ(これも本来Stackageに含まれる)のバージョン0.13.1.0以降が公開しているモジュールです。今回はこのモジュールに対する依存関係を解決できなかった1ということですね。

こちらに書いてありますが、stack init --solverではコンパイルできるものが出てくるとは限りません。

Stackageのスナップショットを使わないというのは非常にもったいないので、stack init --solverを使うのはなるべく控えたほうが良さそうです。

まとめ

  • stack solverの場合は出力をコピペしてやる必要がある。但し、--modify-stack-yamlを付けてやれば自動編集してくれる。
  • stack init --solverではビルドできるものが出てくるとは限らない。
  • stackのメッセージはとても親切なのでよく読むべき。

  1. ちなみに依存関係が解決できない理由はよく理解できていません。githubのissueのこれこれが関係あるとは思うのですが。 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3