Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号
Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号 我正在尝试在 Debian Bookworm 上编译一个与 Debian Bullseye 兼容的二进制文件。我已经解压了适用于 Bullseye 的旧版 Glibc/OpenSSL,并尝试链接它们:
export CGO_LDFLAGS="-Xlinker -rpath=/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu,-rpath=/home/bodqhrohro/git/libssl/usr/lib/x86_64-linux-gnu,--dynamic-linker=/home/bodqhrohro/git/glibc/lib64/ld-linux-x86-64.so.2 -L/home/bodqhrohro/git/libssl/usr/lib/x86_64-linux-gnu -L/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu -include /home/bodqhrohro/git/force_link_glibc_2.27.h"
但在生成的二进制文件中,仍然有一些符号需要 Glibc 2.33:
0000000000000000 F *UND* 0000000000000000 lstat64@GLIBC_2.33
0000000000000000 F *UND* 0000000000000000 fstat64@GLIBC_2.33
0000000000000000 F *UND* 0000000000000000 stat64@GLIBC_2.33
我该如何解决这个问题?
更多关于Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我低估了这个问题……还有更多符号需要 Glibc 2.34:
0000000000000000 F *UND* 0000000000000000 pthread_join@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_rwlock_destroy@GLIBC_2.34
0000000000000000 w F *UND* 0000000000000000 __pthread_key_create@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_rwlock_rdlock@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_mutex_trylock@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_mutexattr_settype@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_setaffinity_np@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_kill@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_mutexattr_init@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_create@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 __libc_start_main@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_attr_getstacksize@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_rwlock_init@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_detach@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_mutexattr_destroy@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_setname_np@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_rwlock_unlock@GLIBC_2.34
0000000000000000 F *UND* 0000000000000000 pthread_rwlock_wrlock@GLIBC_2.34
更多关于Golang编译时使用旧版Glibc仍会调用Glibc 2.33中的某些符号的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在 Go 编译时,即使指定了旧版 Glibc 的路径,某些符号仍可能链接到新版 Glibc,这是因为 Go 的运行时和标准库可能依赖较新的系统调用封装。以下是解决方案:
-
使用
CGO_ENABLED=0进行静态编译(推荐): 这会完全避免链接 Glibc,但可能不适用于依赖 CGO 的项目。CGO_ENABLED=0 go build -o output_binary main.go -
强制链接旧版符号: 创建包装头文件(如
glibc_compat.h),使用asm重定向符号。例如:// glibc_compat.h #include <sys/stat.h> // 重定向 stat64 到 stat64@GLIBC_2.2.5 __asm__(".symver stat64, stat64@GLIBC_2.2.5"); __asm__(".symver fstat64, fstat64@GLIBC_2.2.5"); __asm__(".symver lstat64, lstat64@GLIBC_2.2.5");编译时通过
-include包含此头文件:export CGO_CFLAGS="-include /path/to/glibc_compat.h" go build -o output_binary main.go -
使用
-static链接所有库: 如果项目依赖 CGO,可尝试静态链接 Glibc(需确保旧版 Glibc 支持静态链接):export CGO_LDFLAGS="-static -L/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu" go build -o output_binary main.go -
通过
ldd和objdump验证符号: 编译后检查二进制文件的依赖和符号版本:objdump -T output_binary | grep -E "stat64|fstat64|lstat64" ldd output_binary
示例:完整编译命令(结合方法2):
export CGO_CFLAGS="-include /home/bodqhrohro/glibc_compat.h"
export CGO_LDFLAGS="-L/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu -Wl,-rpath=/home/bodqhrohro/git/glibc/lib/x86_64-linux-gnu"
go build -o bullseye_compatible_binary main.go
注意:Go 的工具链(如 go 命令本身)可能依赖系统 Glibc,建议在 Bullseye 环境中使用相同版本的 Go 进行编译,或使用 Docker 容器确保环境一致性。

