我有几个(独立的)文件需要花费很长时间才能编译,所以我想我会尝试并行编译,根据Don Stewart的回答 here. 我按照方向here,所以我的makefile看起来像 quickbuild: ghc --make MyProg.hs -o MyProgdepend: g
我按照方向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’.
我建议不要将make用于此类目的.查看ghc-parmake及其问题,especially this one – GHC有一个非常复杂的重新编译检查器,您无法使用Makefile复制(它可以检测到您自己项目之外的包文件是否发生更改).
对于并行运行多个GHC,您也不会从并行make -j获得大的加速(实际上不是> 2),因为激活多个GHC具有高启动开销,这可以通过ghc –make来避免.特别是,每个新的GHC调用都必须解析并检查所有正在编译的模块的所有依赖项中涉及的接口.hi文件; ghc –make缓存它们.
相反,使用GHC 7.8的新ghc –make -j – 它是真正平行的.
它比手动编写的Makefile更可靠,更省力,并且recompilation avoidance比Make可以更好地处理文件时间戳.
在第一个视图中,这听起来像是Haskell的缺点,但实际上并非如此.在其他喜欢使用make进行构建的语言中,比如说C,你不可能注意到你项目之外的文件何时发生变化;在编译器本身有一个构建系统,如ghc –make允许注意到这一点.