在制作共享对象时,不能使用Haskell Stack静态二进制重定位R_X86_64_32与`__TMC_END__'

Ale*_*lex 7 gcc haskell ghc haskell-stack

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

ghc-options:
    "*": -static -optc-static -optl-static -optl-pthread -fPIC
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

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)
Run Code Online (Sandbox Code Playgroud)

我正在使用启用了docker的堆栈和一个自定义的Amazon Linux映像,用于构建与AWS Lambda一起使用的静态二进制文件.

我以前没有静态二进制编译的经验,所以我对这个链接器错误感到有点困惑.有什么想法吗?

这是使用-v的gcc args:

/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
Run Code Online (Sandbox Code Playgroud)

Erè*_*èbe 5

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

\n\n
stack\n |_ cabal\n      |_ ghc\n          |_ gcc\n              |_ ld (linker)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

reddit 上的 sausade 提供了有关如何执行此操作的答案:您只需将以下内容添加到 .cabal 文件的可执行部分中:

\n\n
directive:\n\n`ld-options: -static`\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

因此,一旦您在 cabal 文件中添加了该指令,您只需运行:

\n\n

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

\n\n

瞧\xc3\xa0!

\n\n

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

\n\n
\n\n

之前的回答:

\n\n

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

\n\n

对于您原来的问题,这里有两个有用的链接来向您展示如何做到这一点:

\n\n\n