如何在GHC依赖关系生成中使用'make'

时间:2013-10-23 14:56:47

标签: haskell makefile ghc

我有几个(独立的)文件需要花费很长时间才能编译,因此根据Don Stewart的回答here,我想我会尝试并行编译。

我按照here的说明进行操作,因此我的makefile看起来像

quickbuild:
    ghc --make MyProg.hs -o MyProg

depend:
    ghc -M -dep-makefile makefile MyProg

# DO NOT DELETE: Beginning of Haskell dependencies
...
MyProg.o : MyProg.hs
MyProg.o : B.hi
MyProg.o : C.hi
...
# DO NOT DELETE: End of Haskell dependenciesghc

(注意:与the docs相反,GHC似乎默认为“Makefile”而不是“makefile”,即使存在“makefile”。)

我的问题是:如何使quickbuild依赖于任何自动依赖(以便make实际上并行运行)?我尝试将'MyProg.o'添加到'quickbuild'的依赖列表中,但'make'(正确地)抱怨没有规则来构建'B.hi'。

1 个答案:

答案 0 :(得分:1)

我建议不要将make用于此类目的。

查看ghc-parmake及其问题,especially this one - GHC有一个非常复杂的重新编译检查器,你不能用Makefile复制它(它可以检测你自己项目之外的包文件是否有变化)。

对于并行运行多个GHC,您也不会从并行make -j获得大的加速(实际上不是> 2),因为激活多个GHC具有较高的启动开销,{{1} }。特别是,每个新的GHC调用都必须解析并检查所编译模块的所有依赖项中涉及的所有接口ghc --make文件; .hi缓存它们。

相反,使用GHC 7.8的新ghc --make - 它确实是平行的。

它比手动编写的Makefile更可靠,更省力,并且比使用文件时间戳的Make更好recompilation avoidance


在第一个视图中,这听起来像是Haskell的缺点,但实际上并非如此。在其他喜欢使用ghc --make -j进行构建的语言中,比如说C ++,不可能注意到项目之外的文件何时发生变化;在编译器本身中有一个构建系统,如make,可以注意到这一点。