Golang中找不到Libc.so.6的解决方法
Golang中找不到Libc.so.6的解决方法 当我在一台机器上运行使用 Go 1.15.5 编译的可执行文件时,会出现以下错误,但使用 1.14.12 版本编译时则运行正常。这让我感到困惑,我原本以为 Go 的可执行文件是静态链接的,没有任何依赖?
./softtube.download: /lib/x86_64-linux-gnu/libc.so.6: 找不到版本 `GLIBC_2.32’ (被 ./softtube.download 需要)
我编译时使用的机器运行的是 Manjaro Cinnamon,而出问题的电脑运行的是 Linux Mint 20。
我在这里有什么地方理解错了吗?难道 Go 的可执行文件不是“独立”的吗?
更多关于Golang中找不到Libc.so.6的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
显然我不太擅长阅读自己的代码 😊
谢谢!
更多关于Golang中找不到Libc.so.6的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
根据我在softtube.download中看到的情况,您引用了internal/softtube.core,而它又引用了github.com/go-sql-driver/mysql,后者使用了net包。
我认为Go语言中有一些功能使用了libc,例如net和os/user包(我想这也是为什么在使用net包时竞态检测器无法工作的原因之一)。如果你没有使用这些包,那么你的程序可以进行静态编译,或者可能有一些编译时选项来使用这些包的纯Go版本。我还在阅读一些相关的错误报告,比如这个。
我必须承认,我对静态链接和动态链接的了解并不深入。但据我所知,net 包使用 cgo 来处理一些对操作系统的调用(例如,我相信将主机名解析为 IP 地址的查找就是通过 libc 完成的)。
编辑:另外,关于选项,我认为你可以在执行 go build 命令之前设置 CGO_ENABLED=0 来禁用 cgo。我认为 cgo 是唯一一处你可能会遇到动态链接的地方,并且需要你明确选择退出。
CGO_ENABLED=0
Go 1.15版本开始,当使用net包且系统支持cgo时,Go会在某些情况下动态链接glibc。这是因为Go 1.15将DNS解析默认切换到了glibc的getaddrinfo函数,以获得更好的本地DNS配置兼容性。
解决方法:
- 静态编译(推荐):
CGO_ENABLED=0 go build -o softtube.download
这会完全静态链接,不依赖glibc。
- 使用纯Go的DNS解析器:
go build -tags netgo -o softtube.download
这会强制使用Go实现的DNS解析器。
- 降级glibc依赖(编译时):
go build -ldflags="-extldflags=-Wl,--wrap=getaddrinfo" -o softtube.download
示例验证:
# 查看二进制文件的动态库依赖
ldd softtube.download
# 查看glibc版本要求
objdump -p softtube.download | grep GLIBC
根本原因:你的Manjaro系统有较新的glibc(2.32+),而Linux Mint 20的glibc版本较旧。Go 1.15+在动态链接时会绑定编译时的glibc版本符号。
生产环境建议:
# Docker多阶段构建示例
FROM golang:1.15-alpine AS builder
RUN apk add --no-cache gcc musl-dev
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o app .
FROM scratch
COPY --from=builder /app/app /app
ENTRYPOINT ["/app"]
这样编译的程序可以在任何Linux发行版上运行,无需考虑glibc版本差异。


