与Cabal一起“引导”

时间:2012-02-16 16:53:45

标签: haskell cabal

想象一下如下的Makefile:

stage1 : Stage1.hs
       ghc -o stage1 Stage1.hs
Stage1.hs : stage0 
       stage0 > Stage1.hs
stage0 : Stage0.hs
       ghc -o stage0 Stage0.hs

当前目录首先包含Makefile和Stage0.hs,并生成stage1。

以下是问题:

  1. 如何在Cabal中完成上述操作?我应该只用挂钩做这件事吗? (例如thisthis。) 如果钩子必须依赖于要构建的包中的另一个程序怎么办?
  2. 如果Setup.hs变得足够复杂以至于需要它自己,那该怎么办? 依赖管理?
  3. 是否有一个类似的东西的cabalized包?如果Happy包含一个依赖于Happy调用的cabalized测试程序,那将是一个很好的例子。

1 个答案:

答案 0 :(得分:5)

对于像这样的情况,Cabal很棘手。

正如你所说,如果你可以将所有内容都压缩到Setup.hs,你就可以将头痛的数量降到最低。

如果您有真正复杂的预处理器,我建议这样做:

  1. 为每个预处理器创建一个cabal包,具有自己的依赖项等。因此,对于stage0,您将拥有这样的cabal文件:

    Name:
      mypackage-stage0
    Version:
      0.1
    -- ...
    
    Executable mpk-stage0
      Default-language:
        Haskell2010
      Main-is:
        Stage0.hs
      -- ...
    
  2. 对于stage1,您需要生成源代码,因此在运行{{1}的preBuild的{​​{1}}中添加Setup.hs挂钩可执行文件:

    mypackage-stage1

    然后,您将在前一阶段添加构建工具依赖项:

    mpk-stage0

    这应该适用于最近的cabal版本;否则,您可能需要添加main = defaultMainWithHooks simpleUserHooks { preBuild = -- ... something involving `system "mpk-stage1 Stage1.hs"` -- Note that shell redirection `> bla.hs` doesn't necessarily work -- on all platforms, so make your `mpk-stage1` executable take an -- output file argument } 依赖项。

  3. 每次进行级联更改时, 需要依次重建每个包(这是必要的,因为cabal不管理跨项目依赖项更改),所以你需要一个执行Executable mpk-stage1 -- ... Main-is: Stage1.hs Build-tools: mypackage-stage0 或类似内容的脚本。

  4. Cabal从来没有为这种项目而建,所以如果你想做这样的事情,变得棘手。如果你想以更连贯的方式生成代码,你应该考虑使用Template Haskell。