前言

最近使用 golang 编写了一个 DNS 解析代理转发的工具,功能类似于 dns2socks,目标是准备在我 x86_64 的 OpenWRT 软路由系统中运行的;

由于我的开发机系统是 Rock Linux8 使用 golang 编译出来的应用程序默认链接的是 Glibc 库;而 OpenWRT 系统内置的是一套 musl libc 的精简系统库;

musl 是在Linux系统调用 API 之上构建的 C 标准库的实现,包括基础语言标准、POSIX 和广泛认可的扩展中定义的接口。musl轻量 、快速、简单、免费,并力求在标准一致性和安全性方面做到 正确。

musl is an implementation of the C standard library built on top of the Linux system call API, including interfaces defined in the base language standard, POSIX, and widely agreed-upon extensions. musl is lightweight, fast, simple, free, and strives to be correct in the sense of standards-conformance and safety.

因此在我开发机上由 golang 默认编译出来的程序虽然也是 x86_64 架构,但确无法在 x86_64 的 OpenWRT 系统下运行,
会报错:
-ash: ./dns2socksgo: not found

如下:
glibc-on-musl-not-running.png

静态编译

好在强大的 go 编译器可以通过指定 CGO_ENABLE=0 选项来进行纯静态的编译,让应用程序不依赖于任何外部共享库,完全独立运行,限制条件是应用程序内必须完全不包含任何 C 的代码以及未引用任何包含 C 代码的go package;

我的程序比较简单,纯静态编译后可正常运行,如下:
statically-linked-running.png

musl 交叉编译

但是,作为专门为 OpenWRT 系统开发的程序,我依然还是希望能跟系统原生的工具一样,链接到系统自带的 musl libc 库来运行,这样可以保持应用程序的功能纯粹性,降低程序体积;毕竟动态共享库才Linux系统下程序的正统奥义!~~

开发机安装 musl 编译器

下载 musl 源代码

最新源码在官网查看说明 https://musl.libc.org/

wget https://musl.libc.org/releases/musl-1.2.5.tar.gz

为源代码打安全补丁

在 musl 官网看到目前最新的 1.2.5 版本存在一个 CVE-2025-26519 安全漏洞,需要打两个 patch 来修正;

由于这两个 patch 都是针对 src/locale/iconv.c 源码进行了几行修改,所以我就直接参照 patch 文件内容,手动修改了源代码所设计的几行;

tar zxvf musl-1.2.5.tar.gz
cd musl-1.2.5
# 手动编辑源码文件,修补安全漏洞
vim src/locale/iconv.c 

编译安装 musl

编译安装很简单,标准的 Linux 编译三步走

./configure
make
make install
# 默认编译后的安装路径为 /usr/local/musl/;
# 为了能全局使用 musl-gcc 指令,可以在 PATH 环境变量中添加 /usr/local/musl/bin 
# 我是直接将 musl-gcc 软连接到了 /usr/local/bin/ 路径下
ln -s /usr/local/musl/bin/musl-gcc /usr/local/bin

现在就能正常使用 musl-gcc 编译器了
musl-gcc.png

使用 musl 重新编译 go 程序

现在可以开始使用 musl 来重新编译我的 golang 程序了,并让其动态链接到 musl libc 库

# 进入golang 项目目录
cd go_proj/dns2socksgo

# 指定 CC 编译器,启用 CGO,重新编译
CC=musl-gcc CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o dns2socksgo .

现在编译出来的程序已经是正确链接到 musl libc 的动态链接程序了,并且在 OpenWRT 系统下也正常运行;
Linked-musl-libc-running.png

Last modification:March 1, 2025
如果觉得我的文章对你有用,请随意赞赏