如何减less.cabal文件的构build依赖字段中的重复?

这是一个.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.* 

有什么办法可以替代testing套件的构build依赖包的长列表“与可执行文件相同,加上QuickCheck”?

编辑:版本信息。

  • cabal-dev 0.9
  • cabal-install 0.10.2
  • Cabal库1.10.2.0
  • GHC 7.0.4
  • Haskell平台2011.4.0.0

有什么办法可以替代testing套件的构build依赖包的长列表“与可执行文件相同,加上QuickCheck”?

从来没听说过。 然而,有一种方法只提一次构build依赖包列表,方法是将您的项目构build为三个目标:

  1. 一个包含所有代码的库,并且需要很长的依赖于构build的列表。
  2. 一个只包含一个文件的可执行文件,依赖于上面的库和库。
  3. 一个依赖于上面的库的testing套件,以及你正在使用的testing包。

也许这种方法是indygemma的答案提出的,但是在那里提出的cabal文件不会完全实现,正如Norman Ramsey在评论中指出的那样。 这是你需要在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, ... 

重要的一点:

  • 三个目标有三个独立的源目录。 这是build立其他目标时,停止ghc重新编译库文件所必需的。

  • 所有的应用程序代码都在库中。 可执行文件只是一个包装,就像这样:

     import My.Program.Main (realMain) main = realMain 
  • 该库提供了testing所需的所有模块。

最后一点突出了这种方法的缺点:最终不得不公开内部模块。 这种方法的主要优点是在cabal文件中重复性较低,而且更重要的是在构build过程中重复性较低:库代码将只被构build一次,然后链接到可执行文件和testing套件。

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

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

例如,请参阅hpack自己的package.yaml和生成的hpack.cabal 。

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

要创build一个使用hpack的新包,可以像下面这样使用栈的simple-hpack模板: stack new mypkg simple-hpack

如果您使用堆栈进行开发,则不必手动调用hpack来从更新的package.yaml重新生成.cabal文件 – 堆栈将自动执行。

没有简单的方法:

  • 你可以使用m4并指定你的依赖一次,但是当你改变它的时候你需要通过m4重新处理你的Cabal文件。

  • 你可以将你正在testing的代码移动到一个库中,然后在你的Build-depends中指定库来进行testing。 这需要你安装一个库,甚至只是运行testing。

  • 你可以不把testing放在cabal文件中。 用ghc –make构build它,这会引入依赖关系。 但是,那么你失去了集体融合。

.cabal文件有一个可选的部分,可以解决你的问题。

 name: myprogram version: 0.1 -- blah blah blah cabal-version: >=1.9.2 library build-depends: attoparsec == 0.10.* , base == 4.3.* -- long long list of packages executable myprogram hs-source-dirs: src main-is: Main.hs test-suite test hs-source-dirs: test, src type: exitcode-stdio-1.0 main-is: Main.hs build-depends: QuickCheck == 2.4.*