【问题标题】:"Bootstrapping" with Cabal与阴谋集团“引导”
【发布时间】:2012-02-16 16:53:45
【问题描述】:

想象一个像下面这样的 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 测试程序,那将是一个完美的例子。

【问题讨论】:

  • 在 Happy 和 Alex 的情况下,Cabal 已经知道如何处理它们,因此您只需列出 Exposed-ModulesOther-Modules 中的模块,Cabal 就会生成 .hs 文件并自动编译它们。
  • 确实如此。我也许应该提到preprocessor-tools

标签: haskell cabal


【解决方案1】:

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,您需要生成源代码,因此在您的Setup.hs 中为运行mypackage-stage1mypackage-stage1 添加一个preBuild 挂钩,以运行mpk-stage0 可执行文件:

    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
      }
    

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

    Executable mpk-stage1
      -- ...
      Main-is:
        Stage1.hs
      Build-tools:
        mypackage-stage0
    

    这应该适用于最近的阴谋集团版本;否则,您可能需要添加 Build-depends: 依赖项。

  3. 每次进行级联更改时都需要依次重建每个包(这是必要的,因为 cabal 不管理跨项目依赖项更改),因此您需要一个执行 for project in mypackage-stage0 mypackage-stage1; do (cd $project; cabal install); done 或类似的脚本。

Cabal 从来都不是为这种项目而构建的,所以如果你想做这样的事情,它很棘手。如果您想以更连贯的方式生成代码,您应该考虑使用 Template Haskell。

【讨论】:

  • 非常感谢您的快速回复,很抱歉迟到了。阴谋集团从来没有为这种项目而建,这确实是我的怀疑。仅供参考,我的临时解决方案是为每个可执行文件添加一个标志,并使用主 Makefile.am 来驱动编译。您的建议似乎有所改进,但弹出
  • 其他问题。如果我不想在用户系统中安装 stage0 怎么办?是否可以在构建系统中本地注册一个临时包?模板 Haskell 是否支持多阶段代码生成?最后,如果我自己找到答案,我应该在这里写成 cmets 吗?或者发布另一个答案来回答我自己的问题?谢谢!
  • 遗憾的是,您不能制作临时可执行文件。模板 Haskell 可以在多个阶段使用;您可以使用 TH 生成生成 Haskell 代码的 TH 代码。如果您认为您的答案对其他人有帮助,您应该发布自己的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
相关资源
最近更新 更多