【问题标题】:Why does GHC take so long to link?为什么 GHC 需要这么长时间才能链接?
【发布时间】:2011-08-05 06:40:12
【问题描述】:
>cabal update
>cabal install cabal-install
.......
[43 of 44] Compiling Distribution.Client.Install ( Distribution/Client/Install.hs, dist/build/cabal/cabal-tmp/Distribution/Client/Install.o )
[44 of 44] Compiling Main             ( Main.hs, dist/build/cabal/cabal-tmp/Main.o )
Linking dist/build/cabal/cabal ..

然后我会等待很长时间才能完成链接。

真诚的!

【问题讨论】:

    标签: haskell


    【解决方案1】:

    很可能是链接器本身。众所周知,来自 binutils 的标准 ld 很慢。如果你想加快速度(并且生活在边缘),请尝试安装Gold linker。在 Ubuntu(我假设是 Debian)上,这将是:

    sudo apt-get install binutils-gold
    

    我已经在我的家庭系统上使用它一段时间了,还没有问题。

    【讨论】:

    • ld 确实很慢,但这无济于事,因为 ghc 进行静态链接并尝试链接很多东西,所以链接器有很多工作要做.在我稍旧的 1GB 内存的 macbook 上,ld 经常会耗尽内存并开始交换。
    • 很公平,我确信 GHC 可以提供帮助,我只是指出一些容易实现的目标。
    • @John L:好吧,如果它很慢,因为 GHC 使用比必要慢的链接器进行的链接比必要的多,有两种明显的方法可以改善整体结果,但只有一种没有不需要弄乱 GHC 的内部结构。 ;]
    • @C. A. McCann:确实如此。但是,如果标准 ld 是您系统的唯一可用链接器(对我来说是 OS X),那么您的选择就是与 GHC 混淆或与您的链接器混淆。巧合的是,在过去的一个月里,我对链接器的了解比我想象的要多得多……
    • 哇,数量级差异。很好的建议。
    【解决方案2】:

    这应该是注释,但我无法在 cmets 中这样格式化代码:

    我设法使用黄金作为 GHC 使用的链接器,通过安装 binutils-gold(如 Michael Snoyman 的回答中所建议)然后替换符号链接 /usr/bin/ld 来解决像 /usr/bin/ld.gold: --hash-size=31: unknown option 这样的标准 ghc-with-gold 错误通过以下脚本(使用chmod +x 可执行):

    #!/usr/bin/env python2
    
    import sys
    import os
    import subprocess
    
    
    tofilter = [
        "--hash-size",
        "--reduce-memory-overheads",
    ]
    
    filtered = [ a for a in sys.argv if not any(a.startswith(p) for p in tofilter) ]
    filtered[0] = "/usr/bin/ld.gold"
    
    subprocess.check_call(subprocess.list2cmdline(filtered))
    

    请注意,尝试使用ghc -pgml /usr/bin/ld.goldghc -pgml /usr/bin/ld.whateverElse 设置链接器是不够的,因为-pgml 的参数需要替代GCC,而不是LD。 GHC调用GCC,GCC调用/usr/bin/ld;这就是上述脚本有效的原因。

    【讨论】:

    • 对于即将发布的 GHC 版本(可能是 7.8)将不再需要:hackage.haskell.org/trac/ghc/ticket/6063#comment:19
    • 如此期待。
    • 谢谢,我想我会试试这个解决方法。奇怪的是,根据 cmets here,链接器检测应该在您 configure 绑定器时发生,但我没有发现当我使用从源代码分发编译的绑定器时会发生这种情况.有谁知道我可能做错了什么?
    • 这应该使用subprocess.check_call,而不是os.system,因为后者将执行shell 扩展,否则将保持未扩展。我花了大约两天时间试图找到这个。
    • @bgamari 好的,现在使用subprocess.check_call
    【解决方案3】:

    默认情况下,GHC 会创建一个独立的库/可执行文件(静态链接)。

    现在支持动态链接已经有一段时间了,所以您可以尝试开启它。由于要做的工作更少,链接器可能会更快。另一方面,您需要确保在执行时您所依赖的动态库可用(Linux 上的 LD_LIBRARY_PATH 变量)。

    【讨论】:

      猜你喜欢
      • 2019-11-13
      • 1970-01-01
      • 2012-04-29
      • 2020-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 2017-09-22
      • 2021-07-17
      相关资源
      最近更新 更多