如何在Arch Linux编译可在Ubuntu服务器运行的Go应用?
解决Go程序跨GLIBC版本兼容问题(依赖sqlite3)
不用非得在Ubuntu实体机上编译,有几个更灵活的方案可以解决你的问题:
1. 使用Docker模拟Ubuntu环境编译
这是最省心的方法,不用在本地安装Ubuntu系统:
- 拉取和你服务器版本一致的Ubuntu镜像(比如Ubuntu 20.04,对应较低的GLIBC版本)
- 启动容器并挂载你的项目目录
- 在容器内安装Go环境和sqlite3编译依赖
- 执行常规的
go build .编译,生成的二进制会适配Ubuntu的GLIBC版本,能直接在服务器运行
命令示例:
# 拉取Ubuntu 20.04镜像 docker pull ubuntu:20.04 # 启动容器并挂载当前项目目录到容器内的/app docker run -it --rm -v $(pwd):/app ubuntu:20.04 /bin/bash # 在容器内完成编译准备和编译 apt update && apt install -y golang gcc libsqlite3-dev cd /app go build .
编译完成后,容器内的/app/conc2d-api就是可直接在服务器运行的二进制文件。
2. 静态编译(打包所有依赖到二进制)
因为项目依赖sqlite3必须开启CGO,我们可以尝试静态编译,把GLIBC和sqlite3都打包进二进制:
使用以下编译命令:
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -tags sqlite_omit_load_extension -ldflags '-w -s -linkmode external -extldflags "-static"' .
-tags sqlite_omit_load_extension:禁用sqlite3的扩展加载功能,降低静态编译的复杂度-linkmode external -extldflags "-static":强制使用外部链接器并静态链接所有系统依赖
注意:部分系统可能对静态链接GLIBC有兼容性限制,但大部分场景下这个方法能解决版本不匹配问题。
3. 直接在Ubuntu环境编译(实体机/虚拟机/WSL)
如果上面两种方法都不想尝试,那确实可以在Ubuntu环境编译——不管是本地装Ubuntu虚拟机、Windows的WSL2,还是直接在服务器上编译。只要编译环境的GLIBC版本和服务器一致,生成的二进制就能直接运行。
为什么你之前的方法没用?
- Arch Linux的GLIBC版本通常远高于Ubuntu服务器,在Arch上编译的程序会依赖高版本GLIBC,服务器无法提供,所以报错
CGO_ENABLED=0会禁用CGO,但go-sqlite3必须依赖CGO才能操作sqlite数据库,因此出现Stub错误GOOS=linux GOARCH=amd64仅指定目标系统和架构,无法解决GLIBC依赖版本不匹配的核心问题
内容的提问来源于stack exchange,提问作者doobdargent
相关产品推荐
相关产品推荐

