【问题标题】:Generating correct link dependencies for GHC and Makefile style builds为 GHC 和 Makefile 样式构建生成正确的链接依赖项
【发布时间】: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


    【解决方案1】:

    我的建议是,不要费心尝试完成这项工作。它应该可以工作,如果可以工作,那就太好了,但是 ghc 的-M 支持目前已被破坏(例如,它不会生成正确的依赖规则,并省略了一些非 Haskell 文件的规则)。实际上,要让它可靠地工作需要付出很大的努力,最终会引发比严格必要的更多的重建。

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

    【讨论】:

    • 是否也可以使用一个ghc --make 构建多个可执行文件?因为我认为在从同一个模块构建多个二进制文件时并行运行多个它们是不安全的。
    • ghc --make 的一次调用不会构建多个二进制文件,但有一些方法可以解决这个问题而不会带来太多麻烦。可能最有用的是制作一个将所有公共代码指定为库的 cabal 配置。或者串行构建您的可执行文件,但由于大多数目标文件将由第一个可执行文件构建,其余部分将主要是链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2023-04-11
    相关资源
    最近更新 更多