【问题标题】:Haskell Stack Static Binary relocation R_X86_64_32 against `__TMC_END__' can not be used when making a shared objectHaskell Stack Static Binary relocation R_X86_64_32 针对 `__TMC_END__' 在制作共享对象时不能使用
【发布时间】:2017-01-01 21:15:42
【问题描述】:

在我的stack.yaml 中使用以下内容(尝试)通过堆栈编译静态二进制文件时:

ghc-options:
    "*": -static -optc-static -optl-static -optl-pthread -fPIC

我收到此错误:

usr/bin/ld: /usr/lib/gcc/x86_64-amazon-linux/4.8.3/crtbeginT.o: relocation R_X86_64_32 against `__TMC_END__' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-amazon-linux/4.8.3/crtbeginT.o: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)

我正在使用启用了 docker 的堆栈和自定义的 Amazon Linux 映像来构建用于 AWS Lambda 的静态二进制文件。

我之前没有使用静态二进制编译的经验,所以我对这个链接器错误感到有些困惑。请问有什么想法吗?

这是使用 -v 的 gcc 参数:

/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads -Wl,--no-as-needed -Wl,-rpath<snipped LOADS> -lHSghc<SNIPPED LOADS> -lpq -lz -lrt -lutil -ldl -lgmp

【问题讨论】:

  • 如果您可以提供失败的 gcc 调用,这将有所帮助。可能将-v 添加到ghc-options 行就可以了。
  • 嗯,这是一个错误吗?使用 gcc 调用更新帖子
  • This blog post 使用 Alpine 和 Musl 可能是更可靠的方法。你可以在this build script看到它的实践。
  • 优秀的帖子和示例,但不幸的是它导致Error parsing targets: The specified targets matched no packages. Perhaps you need to run 'stack init'?

标签: haskell gcc ghc haskell-stack


【解决方案1】:

@Reid Barton 是对的,关于问题的根本原因。这里真正的问题是堆栈默认构建共享二进制文件。通过传递-static 或 ghc-options: -optl-static 选项,我们仅分别处理 ghc 层和 ld 层。

stack
 |_ cabal
      |_ ghc
          |_ gcc
              |_ ld (linker)

解决问题的正确方法是告诉 cabal 我们需要一个静态二进制文件,因为它会引导构建。

sausade 在 reddit 上提供了如何做到这一点的答案:您只需在可执行部分的 .cabal 文件中添加以下内容:

directive:

`ld-options: -static`

这将向 cabal 暗示我们需要一个静态二进制文件,因此它不会将 -shared 传递给 ghc。

所以一旦你在你的 cabal 文件中添加了这个指令,你只需要运行:

stack install --ghc-options="-fPIC"

瞧!

P.S:如果您的系统上没有静态库(例如 Archlinux)ld 将回退到动态链接


上一个答案:

这是一个没有人愿意修复的老 gcc 问题。 https://bugs.launchpad.net/ubuntu/+source/gcc-4.4/+bug/640734

对于你原来的问题,这里有两个有用的链接来告诉你如何去做:

【讨论】:

    【解决方案2】:

    我在这里猜测了一下,但我认为这只是在构建系统背后破坏事物的情况。

    写错了

    ghc-options:
        "*": -static
    

    因为构建动态或静态库的选择会对构建其余部分的运行方式产生影响。这里看起来 Stack 或 Cabal 告诉 ghc 构建一个动态库,并且这个标志覆盖了您设置 -static 的尝试。结果 gcc 可能以选项组合 -shared -static 结束,这导致了 Erèbe 的回答中提到的错误。 (如果你的旗帜 -static 战胜了 -dynamic,那么 ghc 可能已经成功构建了一个静态库,但 Stack/Cabal 可能会对下一步做什么感到困惑。)

    这样做的正确方法是不要在ghc-options 中使用-static,而是告诉Stack不要首先构建共享库。我不知道你在 Stack 中是怎么做到的,但阴谋集团的标志是 --disable-shared

    【讨论】:

      猜你喜欢
      • 2018-09-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 2017-04-10
      • 2013-10-22
      • 2014-07-29
      • 1970-01-01
      相关资源
      最近更新 更多