我有几个(独立的)文件需要很长时间才能编译,所以我想我会尝试并行编译,根据 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”的规则。

最佳答案

我建议不要将 make 用于这种目的。

查看 ghc-parmake 及其问题,especially this one - GHC 有一个非常复杂的重新编译检查器,您无法使用 Makefile 进行复制(例如,它可以检测您自己项目之外的包文件是否发生更改)。

您也不会从并行运行多个 GHC 的并行 make -j 中获得大的加速(实际上不会> 2),因为触发多个 GHC 具有很高的启动开销,而 ghc --make 避免了这一开销。特别是,每次新的 GHC 调用都必须解析和类型检查您正在编译的模块的所有依赖项中涉及的所有接口(interface) .hi 文件; ghc --make 缓存它们。

相反,使用 GHC 7.8 的新 ghc --make -j - 它是真正并行的。

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

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

关于haskell - 如何在 GHC 依赖生成中使用 'make',我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19545257/

10-13 06:05