【发布时间】:2014-01-23 04:52:47
【问题描述】:
我有一个 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 时为 every 二进制文件触发一个空 ghc --make;不幸的是,这很慢并且使输出混乱(我想看看什么时候链接了,什么时候没有链接)。
ghc -M 只为每个 .o 文件生成依赖行,但不会为链接的可执行文件生成依赖行。关于哪些 .o 文件链接到哪个可执行文件的信息(给定主模块 binN.hs 的名称)显然在那里,但我并不完全清楚是否可以使用任何 Makefile 魔法来实现它。
我只能想办法通过为.hsdepend编写一个后处理器来做到这一点,但这似乎太过分了。
谁能提出更好的解决方案?
【问题讨论】:
标签: haskell makefile dependencies ghc