golang with cgo throws error collect2: error: ld returned 1 exit status

golang with cgo throws error collect2: error: ld returned 1 exit status

我正在编译一个 golang 包,其中包括使用 cgo 的共享 c 库的集成。 docker 图像 golang:1.15.15golang:1.16.6 中的所有内容都成功构建,但由于 golang:1.16.7(也 golang:1.17),它失败并出现错误:

/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `feenableexcept'
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `floor'
...
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `memoFree'
/usr/bin/ld: src/foobar/lib/libXYZ.so: undefined reference to `memoMalloc'
collect2: error: ld returned 1 exit status

我查看了 golang 发行说明,没有找到 cgo 的任何相关更改。

我检查了 gcc 和 ld 的版本,它们都不一样。我什至用 go1.13.8gcc (Ubuntu 8.4.0-3ubuntu2) 8.4.0GNU ld (GNU Binutils for Ubuntu) 2.34 设置了一个 ubuntu 发行版,我 运行 解决了这个问题,所以我想 go不会导致它。

你有什么线索或建议,我怎样才能找到这个问题的根本原因?检查gcc和ld是否正确,或者还有哪些工具需要调查?

感谢 Zyl,我能够缩小问题范围。

我检查了几个发行版(bullseye、buster、stretch),使用 bullseye 时,构建失败了。在我的例子中,来自 binutilsgccld 版本都没有引起问题。

看来,链接器处理 DT_NEEDED 标记的默认设置已更改。我使用 and adding export CGO_LDFLAGS=-Wl,--no-as-needed to the environment. According to https://manpages.debian.org/bullseye/binutils-common/gold.1.en.html 的解决方案解决了我的问题,这是 ld.gold 链接器的默认设置,但不是 ld.

对我帮助很大的是 go build 命令的 -x 标志,可以查看为 cgo.

执行的 gcc 命令