我有几个(独立的)文件需要花费很长时间才能编译,因此根据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'。
答案 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
,可以注意到这一点。