Golang 的一个动态链接依赖问题
upx 是一个压缩二进制的工具,如上图,经过压缩之后,这些 binary 的体积都减少了 46%。
静态链接 CGO 的依赖
如果使用 glibc 的是,是不能静态链接的:
root@f88271a666f9:/workspace# go build -ldflags "-linkmode external -extldflags '-static'" ./cmd/spex
# git.garena.com/shopee/platform/spex/cmd/spex
/usr/bin/ld: /go/pkg/mod/github.com/confluentinc/confluent-kafka-go@v1.5.2/kafka/librdkafka/librdkafka_glibc_linux.a(rddl.o): in function `rd_dl_open':
(.text+0x1d): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-883441031/000004.o: in function `_cgo_26061493d47f_C2func_getaddrinfo':
/tmp/go-build/cgo-gcc-prolog:58: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
因为 glibc 依赖了 libnss ,libnss 支持不同的 provider,必须被 dynamic link.
所以这里只有使用 musl 替换 glibc 了。librdkafka 和 golang 的封装 confluent-kafka-go 都支持 musl 构建。只要在构建的时候指定 --tags musl 即可。alpine 是基于 musl 的发行版,这里直接使用 alpine Linux 进行构建。
然后指定使用外部 ld,指定 flags 使用 -static,编译出来的 binary 就完全是静态链接的了。编译过程如下:
$ docker run -it -v $(pwd):/workspace -v /Users/xintao.lai/.netrc:/root/.netrc golang:alpine3.14
/go $ cd /workspace/
/workspace $ apk add git alpine-sdk
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/37) Insta

文章讲述了在Golang中使用CGO时遇到的动态链接依赖问题,特别是涉及到glibc的情况。通过使用musl库和alpineLinux,可以实现静态链接,避免对运行时共享库的依赖。文章提供了交叉编译的步骤和示例,包括安装musl-cross工具和设置编译选项。

1万+

被折叠的 条评论
为什么被折叠?



