MENU

记一次在macos交叉编译cgo的坑

May 30, 2022 • linux,golang阅读设置

最近使用 golang 开发了一个 telegram 的机器人。
准备使用 docker 进行部署,因为我的开发机是 macos 的系统,且 sqlite 在 linux 上运行需要 CGO 的支持。
着实让我踩了一些坑在里面,记录一下以免后期再犯。

首先说目标

我的开发机是 macos 系统,我需要在 macos 上编译出 linux 使用的二进制文件,然后丢到 linux 服务器上运行。

最开始的编译

最开始我想的很简单,直接把 GOOS 设置为 linux 然后打包二进制就行了。

  • GOOS=linux go build -o captcha-bot

然后运行的时候提示错误:

  • failed to initialize database, got error Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

ok,这个错误很明显,sqlite 需要 CGO 的支持

第二次编译

  • CGO_ENABLED=1 GOOS=linux go build -o captcha-bot

编译的时候就提示错误了:

  • # runtime/cgo
  • linux_syscall.c:67:13: error: implicit declaration of function 'setresgid' is invalid in C99 [-Werror,-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:593:6: note: 'setregid' declared here
  • linux_syscall.c:73:13: error: implicit declaration of function 'setresuid' is invalid in C99 [-Werror,-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:595:6: note: 'setreuid' declared here

苦苦 google 一番,发现在 macos 的 CGO 编译需要 musl-cross 的支持~,找了好久的资料 ==
于是乎安装 musl-cross,macos 的安装命令:

  • brew install FiloSottile/musl-cross/musl-cross

帽子戏法

最终装好 musl-cross
编译命令:

  • CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CXX=x86_64-linux-musl-g++ go build -o captcha-bot

ok,这次编译不报错了,很完美。
然后运行二进制,坑来了,linux 服务器识别不到这个文件?,报错:

  • : No such file or directory

又倒回去看资料,发现 linux 服务器还需要安装一个 musl 的支持。。。

  • # debian安装命令
  • apt-get install -y musl

最后终于可以完美运行了!

有兴趣的可以看看我新开源的 telegram 机器人:https://github.com/assimon/captcha-bot
主要用于新人入群验证,防止机器人入群刷广告。

非常感谢本篇博文给出的解决方案,我找了好久:https://www.baifachuan.com/posts/4862a3b1.html

Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

已有 1 条评论
  1. 可以给 go build 命令指定 `-ldflags="-linkmode external -extldflags '-static'"`,静态编译出来的二进制就不依赖 musl 库了。