如何减少.cabal文件的build-depends字段中的重复?

dav*_*420 58 haskell cabal

这是一个.cabal文件:

Name:                myprogram
Version:             0.1
-- blah blah blah
Cabal-version:       >=1.9.2

Executable myprogram
  HS-source-dirs:       src
  Main-is:              Main.hs
  Build-depends:        attoparsec == 0.10.*,
                        base == 4.3.*,
                        -- long long list of packages

Test-Suite test
  HS-source-dirs:       test, src
  Type:                 exitcode-stdio-1.0
  Main-is:              Main.hs
  Build-depends:        attoparsec == 0.10.*,
                        base == 4.3.*,
                        -- long long list of packages
                        QuickCheck == 2.4.*
Run Code Online (Sandbox Code Playgroud)

有没有什么办法可以用"与可执行文件相同,加上QuickCheck"替换测试套件的长编译依赖包列表?

编辑:版本信息.

  • cabal-dev 0.9
  • cabal-install 0.10.2
  • Cabal图书馆1.10.2.0
  • GHC 7.0.4
  • Haskell平台2011.4.0.0

Tox*_*ris 33

有没有什么办法可以用"与可执行文件相同,加上QuickCheck"替换测试套件的长编译依赖包列表?

从来没听说过.但是,build-depends通过将项目结构化为三个目标,有一种方法只能提及一次包列表:

  1. 包含所有代码的库,需要长构建依赖列表.
  2. 一个只包含一个文件的可执行文件,它依赖于base和上面的库.
  3. 依赖于上面的库以及您正在使用的测试包的测试套件.

也许这种方法是indygemma的答案所提出的,但是如同诺曼·拉姆齐在评论中指出的那样,提出的Cabal文件将无法实现.以下是Cabal文件中所需内容的要点.有关适用于我的完整示例,您可以查看此Cabal文件.

name: my-program
version: ...

library
  hs-source-dirs: src-lib
  build-depends: base, containers, ...
  exposed-modules: My.Program.Main, ...

executable my-program
  hs-source-dirs: src-exec
  main-is: my-program.hs
  Build-depends: base, my-program

test-suite tests
  type: exitcode-stdio-1.0
  hs-source-dirs: src-test
  main-is: tests.hs
  other-modules: ...
  build-depends: base, my-program, test-framework, ...
Run Code Online (Sandbox Code Playgroud)

重点:

  • 这三个目标有三个独立的源目录.这有必要阻止GHC在构建其他目标时重新编译库文件.

  • 所有应用程序代码都在库中.可执行文件只是一个包装器,如下所示:

    import My.Program.Main (realMain)
    main = realMain
    
    Run Code Online (Sandbox Code Playgroud)
  • 该库公开了测试所需的所有模块.

最后一点强调了这种方法的缺点:您最终不得不暴露内部模块.这种方法的主要好处是Cabal文件中的重复较少,更重要的是,构建过程中的重复较少:库代码只构建一次,然后链接到可执行文件和测试套件中.

  • 在Cabal-1.26(尚未发布)中,可能用`library my-internal-lib`替换`library`节,这使得一个名为"my-internal-lib"的内部库只能在内部看到包中的组件,而不是其他用户.请参阅https://github.com/haskell/cabal/pull/3022 (4认同)

pha*_*dej 9

从版本2.2开始,Cabal支持常见节,重复构建信息字段:https: //cabal.readthedocs.io/en/latest/developing-packages.html#common-stanzas

cabal-version:       2.2
name:                myprogram
version:             0.1
-- blah blah blah

common deps
  build-depends: base ^>= 4.11,
                 -- long long list of packages
  ghc-options: -Wall

library
  import: deps
  exposed-modules: Foo

test-suite tests
  import: deps
  type: exitcode-stdio-1.0
  main-is: Tests.hs
  build-depends: foo
Run Code Online (Sandbox Code Playgroud)


sja*_*obi 5

您也可以考虑使用hpack而不是手动编写 .cabal 文件:

\n\n

在 hpack 的 package.yaml 格式中,您可以指定一个公共dependencies字段,其条目将添加到每个组件中build-depends字段,在生成 .cabal 文件时,

\n\n

例如查看hpack自带的package.yaml和生成的hpack.cabal

\n\n

要开始将 hpack 与现有包一起使用,您可以使用hpack-convert,它将从现有 .cabal 文件生成 package.yaml。

\n\n

要创建使用 hpack 的新包,您可以使用 stack 的simple-hpack模板,如下所示:stack new mypkg simple-hpack

\n\n

如果使用进行开发,则不必调用hpack手动调用从更新的包重新生成 .cabal 文件。yaml \xe2\x80\x93 堆栈将自动执行此操作。

\n