前言
首先我自己没有对 Golang 很深了解,一切都在学习中,不过还好目前为止学习得还算顺利,毕竟写的都是人话。
在本文章中我不会去锐评有关 musl 的东西,毕竟我不会C,没啥资格聊这个。
正文
这次的适配记录的起因是因为我的 复活版TPClash 项目群中有用户反馈 Alpine Linux 无法正常运行,后面想了想 Alpine Linux 是使用 musl 作为 C标准函式库(libc) 的,这么一想起不来也正常了
像 Alpine Linux 一样使用 musl 的发行版其实很多,我自认为用的人比较多的发行版例如 OpenWrt 和 Gentoo,所以能解决这个问题的话还是有必要的。
CGO 是什么?
估计很多刚学 Go 的人和我一样很懵,虽然没啥人简短总结,不过算是找到了个比较简短的解释。
Go 作为当下最火的开发语言之一,它的优势不必多说。Go 对于高并发的支持,使得它可以很方便的作为独立模块嵌入业务系统。有鉴于我司大量的 C/C++存量代码,如何 将 Go 和 C/C++进行打通就尤为重要。**Golang 自带的 CGO 可以支持与 C 语言接口的互通。**本文首先介绍了 cgo 的常见用法,然后根据底层代码分析其实现机制,最后在特定场景下进行 cgo 实践。
我的项目用到了C
我自己还没学完 Golang,所以我让 GPT-3.5 给了个回答。
在使用 musl 作为 C 标准库的 Linux 发行版中,可能会出现与 glibc 不同的问题,尤其是在涉及到 C 语言代码的 Go 项目中。以下是一些建议和解决方案:
交叉编译: 一个通用的方法是在开发环境中使用 glibc,但在部署目标系统上使用 musl。这可以通过交叉编译来实现。在构建 Go 项目时,可以通过设置环境变量
CC
来指定使用的 C 编译器。例如:bashCC=musl-gcc go build
这将使用 musl-gcc 编译器来构建你的 Go 项目,确保 musl 库被链接到二进制文件中。
静态链接: 如果交叉编译并不适用,考虑将 C 代码静态链接到 Go 二进制文件中。这样,你可以在目标系统上运行 Go 二进制文件而不必依赖目标系统上的 C 库。可以通过设置
CGO_ENABLED
环境变量为0
来禁用 CGO,并使用-ldflags
标志将 C 代码静态链接到 Go 二进制文件中。例如:bashCGO_ENABLED=0 go build -ldflags="-linkmode external -extldflags -static"
这会禁用 CGO 并在构建时将 C 代码静态链接到 Go 二进制文件中。
使用正确的编译器和工具链: 确保在目标系统上使用正确的编译器和工具链。如果目标系统使用 musl,确保在目标系统上安装了 musl 工具链和库。
检查依赖库的兼容性: 如果你的项目依赖于其他库,确保这些库与 musl 兼容。有些库可能依赖于特定于 glibc 的特性,因此在 musl 系统上可能会遇到问题。
查看错误日志: 如果你遇到问题,查看错误日志并检查特定于 musl 的问题。这可能包括一些系统调用的不同行为或缺失的功能。
请注意,这些建议可能需要根据你的具体情况进行调整。在处理与 musl 兼容性问题时,了解 musl 的特性和与 glibc 的差异是很重要的。
—— ChatGPT 3.5
我的项目没有用到C
如果你的项目中没有用到C的话,其实是可以关掉的,关掉也是最简单的解决方法。
很简单,在编译的时候加个环境变量关掉 CGO 就好了。
如果你是在普通的终端中
写到底层环境变量中(如 /etc/enviroment
或 ~/.bashrc
)或每次新建终端时输入:
export CGO_ENABLED=0
如果你是在 Github Actions 中
在 env
中加入:
env:
CGO_ENABLED: 0
结尾
总的来说问题就是这样解决的了,有啥不对欢迎大佬在评论区补充。