想象一下如下的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。
以下是问题:
答案 0 :(得分:5)
对于像这样的情况,Cabal很棘手。
正如你所说,如果你可以将所有内容都压缩到Setup.hs
,你就可以将头痛的数量降到最低。
如果您有真正复杂的预处理器,我建议这样做:
为每个预处理器创建一个cabal包,具有自己的依赖项等。因此,对于stage0
,您将拥有这样的cabal文件:
Name:
mypackage-stage0
Version:
0.1
-- ...
Executable mpk-stage0
Default-language:
Haskell2010
Main-is:
Stage0.hs
-- ...
对于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
}
依赖项。
每次进行级联更改时, 需要依次重建每个包(这是必要的,因为cabal不管理跨项目依赖项更改),所以你需要一个执行Executable mpk-stage1
-- ...
Main-is:
Stage1.hs
Build-tools:
mypackage-stage0
或类似内容的脚本。
Cabal从来没有为这种项目而建,所以如果你想做这样的事情,会变得棘手。如果你想以更连贯的方式生成代码,你应该考虑使用Template Haskell。