为GHC和Makefile样式构建生成正确的链接依赖项

时间:2014-01-05 20:40:31

标签: haskell makefile dependencies ghc

我有一个Haskell项目,其中大部分可执行文件来自大多数相同的模块。我正在使用Makefile来启用并行构建,它几乎以我想要的方式工作。这是我当前Makefile的精简版本,其中的想法来自http://www.haskell.org/ghc/docs/latest/html/users_guide/separate-compilation.html#using-make

HFLAGS=-O3 -Wall -v0 -fno-ignore-asserts
HASKELLS=bin1 bin2 bin3 bin4 bin5 bin6 bin7 bin8 bin9

all: $(HASKELLS)

%.hi: %.o
    @:

%.hi %.o: %.hs
    ghc -c $(HFLAGS) $<

$(HASKELLS): %: %.o
    ghc --make $(HFLAGS) $@

.hsdepend: *.hs
    ghc -M -dep-makefile .hsdepend *.hs
    rm -f .hsdepend.bak

include .hsdepend

如您所见,我仍然使用ghc --make进行链接(仅限);这样,各个模块可以并行编译,ghc --make只调用链接器。

不幸的是,这不是万无一失的:仅当 bin1.o 比可执行文件更新时才会触发重新链接,例如 bin1 ,但如果只有一个其他目标文件已更新。当在模块中进行更改以使其导致 .o 文件更新时,可能会发生这种情况,但模块的界面不会更改,即 .hi 文件未被触及。

一个替代解决方案是每次调用make时触发每个二进制文件的空ghc --make;不幸的是,这很慢并且使输出变得混乱(我希望看到什么东西被链接,什么时候没有)。

ghc -M仅为每个 .o 文件生成一个依赖关系行,但链接的可执行文件没有生成依赖关系。有关哪个 .o 文件链接到哪个可执行文件(给定主模块的名称 binN.hs )的信息显然是存在的,但是我不完全清楚可以使用任何Makefile魔法来实现它。

我只能通过为 .hsdepend 编写后处理器来想办法做到这一点,但这似乎过分了。

有人能提出更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我的建议是,不要费心去做这项工作。它应该工作,如果它工作会很好,但ghc的-M支持当前被破坏(因为它没有生成适当的依赖规则,并且省略了一些非Haskell文件的规则)。实际上让它可靠地工作将需要付出很多努力,最终将触发更多的重建,而不是严格必要的。

此外,对并行构建的支持已合并到GHC中,因此当ghc​​-7.8发布时,您将能够使用普通ghc --make来获得并行构建。或者你现在可以使用ghc的HEAD。