持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
背景,旧项目升级
今天对一老项目升级,Go 版本从 1.10 升级到 1.16。
操作方法
按照惯例,将老项目的 src 删除,增加 go.mod 文件,修改引用路径,修改配置文件加载方式,将原来的依赖复制到 vendor 目录,直接使用 vendor 方式编译,发现成功了。
直接发至测试环境,此时到现在为止都很正常。
我再次检查go.mod,打开一看,里面居然是空的,require 里面是空的。
直接执行 go mod tidy && go mod vendor,好家伙,几千个更新,一顿操作下来,go.mod 中 require 有内容了。
在测试环境的 docker 中运行报错了
直接本地编译成功,打 tag 发布测试环境,发现报了一个错误
standard_init_linux.go:195: exec user process caused "no such file or directory
standard_init_linux.go:195: exec user process caused "no such file or directory
standard_init_linux.go:195: exec user process caused "no such file or directory
解决方法
猜测是go mod tidy && go mod vendor 后,一些间接依赖包被引入了,这些引入的包开启了cgo.
关闭cgo编译,试一试果然解决
CGO_ENABLED=0 go build -o xxx main.go
CGO_ENABLED的作用
当CGO_ENABLED=1,进行编译时会将文件中引用libc的库(比如常用的net包),以动态链接的方式生成目标文件。
当CGO_ENABLED=0,进行编译时则会把在目标文件中未定义的符号(外部函数)一起链接到可执行文件中。