golang1.17镜像使用musl-gcc构建Go项目报__TMC_END__隐藏符号错误
问题原因
- 核心触发点是Go 1.10及之后版本,默认开启了*位置无关可执行文件(PIE)*的编译模式,你使用的musl 1.1.19版本与静态编译参数的组合,和该默认配置存在冲突:
- Go 1.9版本默认不会自动开启PIE编译,因此你的原有配置可以正常运行
go build指定的静态编译参数,和Go默认的PIE模式冲突,musl 1.1.19版本的静态库未适配该场景下的__TMC_END__符号导出,就会触发隐藏符号引用错误
- 从apt安装的musl-tools如果版本低于1.2.0,同样存在该符号导出问题,也会复现报错
解决方案
你可以任选以下任意一种方案修复问题:
方案1:强制关闭Go的PIE编译模式
在go build参数中添加-buildmode=exe强制关闭PIE模式,修改后的编译指令如下:
CC=/usr/local/musl/bin/musl-gcc go build -buildmode=exe --ldflags '-s -w -linkmode external -extldflags "-static"'
该方案改动最小,不需要调整Dockerfile其他配置,兼容性最好。
方案2:给外部链接器添加关闭PIE的参数
在extldflags参数中追加-no-pie,让gcc链接阶段关闭PIE,修改后的编译指令如下:
CC=/usr/local/musl/bin/musl-gcc go build --ldflags '-s -w -linkmode external -extldflags "-static -no-pie"'
效果和方案1一致,适合不想修改Go编译模式的场景。
方案3:升级musl版本
将你编译安装的musl版本升级到1.2.0及以上,新版本的musl已经修复了该符号导出问题,仅需修改Dockerfile中下载musl的相关指令即可。
内容的提问来源于stack exchange,提问作者DeYuro
相关产品推荐
相关产品推荐

