CGO

我在 Mac 下使用交叉编译 Linux x86 架构的 go 程序,一切非常顺利。

指令如下

1
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build

但是当我在 Linux 下运行的时候却报了如下错误

1
failed to create user table: Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

也就是需要 c 语言环境,也就意味着需要把 CGO_ENABLED 改为 1

我改了之后再次编译,发现这次编译失败

1
2
3
4
5
6
7
# runtime/cgo
linux_syscall.c:67:13: error: call to undeclared function 'setresgid'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
linux_syscall.c:67:13: note: did you mean 'setregid'?
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/unistd.h:597:6: note: 'setregid' declared here
linux_syscall.c:73:13: error: call to undeclared function 'setresuid'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
linux_syscall.c:73:13: note: did you mean 'setreuid'?
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/unistd.h:599:6: note: 'setreuid' declared here

于是想着干脆跑到 Linux 下编译得了,但是我本地并没有现成的 Linux,只好使用 Docker 来编译

Docker

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
FROM golang:latest

# 安装必要的构建工具
RUN apt-get update && apt-get install -y \
                              gcc \
                              libc6-dev \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /app

# 设置默认环境变量
ENV GOOS=linux \
    GOARCH=amd64 \
    CGO_ENABLED=1 \
    GO111MODULE=on \
    GOPROXY=https://goproxy.cn

# 默认构建命令
CMD ["go", "build", "."]

Dockerfile 写好了开始构建

1
docker build --platform linux/amd64 -t go-builder .

启动容器开始编译

1
docker run --rm -v $(pwd):/app go-builder

编译完成,拷贝到服务器,启动。

1
/lib64/libc.so.6: version `GLIBC_2.34' not found (required by xxx)

又报错了,一顿操作,又回到了原点。

这个错误可以通过安装 GLIBC 的版本来解决,但是我怕把环境搞出问题,还是放弃了这种做法。

想了想还是把 go-sqlite3 去掉,换成不需要 C 环境的库。

pure go

找了一圈决定使用 modernc.org/sqlite

改动如下

1
2
-	github.com/mattn/go-sqlite3 v1.14.28 // Added SQLite3 dependency
+	modernc.org/sqlite v1.34.3 // SQLite3 dependency (pure Go)

代码改动

1
2
3
4
5
-	_ "github.com/mattn/go-sqlite3"
+	_ "modernc.org/sqlite"

-	db, err := sql.Open("sqlite3", "./xxx.db")
+	db, err := sql.Open("sqlite", "./xxx.db")

改动不大几分钟搞定。