如何构建 CGO 程序静态链接到 glibc 和动态链接到 libGL.so?

Posted

技术标签:

【中文标题】如何构建 CGO 程序静态链接到 glibc 和动态链接到 libGL.so?【英文标题】:How to build CGO program static linking to glibc and dynamic linking to libGL.so? 【发布时间】:2022-01-23 04:50:26 【问题描述】:

我的操作系统是 Kali,运行 GLIBC_2.32。我需要为运行 GLIBC_2.28 的 debian 10 系统构建 CGO 应用程序。

如果我go build用动态链接,在debian系统上不能运行,显示GLIBC不匹配:

version `GLIBC_2.29` not found
version `GLIBCXX_3.4.29` not found
version `GLIBC_2.32` not found

所以我尝试了静态链接:CGO_LDFLAGS='-static' go build。一个 gui 库使用 OpenGL,它显示错误:

# github.com/go-gl/gl/v3.2-core/gl
/usr/bin/ld: cannot find -lGL

找了一会发现libGL和gpu驱动有关,不能静态链接。

然后我尝试通过以下方式动态链接 libGL.so 和静态链接其他库:

CGO_LDFLAGS='-L/usr/lib/x86_64-linux-gnu -Bdynamic -lGL -static' go build

但同样的错误:“找不到 -lGL”

我不想用 docker,太重了。而且我认为从 debian 10 升级到 11 并不能解决问题,将来可能会有其他一些客户端运行不同的操作系统。最好的解决方案是什么?

【问题讨论】:

即使是静态链接的,glibc 也需要在宿主系统上匹配(这通常是你不应该静态链接 glibc 的原因)。有一些 c 库,如 musl,用于静态链接。 【参考方案1】:

然后我尝试通过以下方式动态链接 libGL.so 并静态链接其他库: CGO_LDFLAGS='-L/usr/lib/x86_64-linux-gnu -Bdynamic -lGL -static' go build

-static 标志告诉链接器:执行完全静态链接。不管放在-lGL之前还是之后,意思都是一样的。

要静态链接某些库并动态链接其他库,请参阅this answer。

也就是说,您尝试做的事情是不可能的:如果您的链接中有任何动态库,那么libc.so.6 必须也被动态链接。

不想用docker,太重了。

太糟糕了。你必须使用 docker,或者设置一个chroot 环境,或者自己构建一个“Linux 到旧版 Linux”的交叉编译器。 docker 可能最容易实现。

【讨论】:

以上是关于如何构建 CGO 程序静态链接到 glibc 和动态链接到 libGL.so?的主要内容,如果未能解决你的问题,请参考以下文章

CGO静态库和动态库

CGO静态库和动态库

Linux软硬链接和动静态库详解

Linux软硬链接和动静态库详解

Linux软硬链接和动静态库详解

CGO 编译和链接参数