必须显式设置GO111MODULE=on,否则Makefile中go mod tidy会因GOPATH模式忽略go.mod而报错“no modules downloaded”;应在每条命令前加GO111MODULE=on或开头export该变量。

Makefile里调用go mod tidy会失败?检查GO111MODULE环境变量
默认情况下,Go在 GOPATH 模式下运行时会忽略 go.mod,导致 go mod tidy 报错“no modules downloaded”或直接跳过。必须显式启用模块模式。
- 在 Makefile 中所有 Go 命令前加
GO111MODULE=on,例如:deps: \tGO111MODULE=on go mod tidy
- 如果项目根目录没有
go.mod,先手动运行go mod init example.com/myapp,否则go mod tidy无目标可处理 - CI/CD 环境中容易漏掉该变量,建议统一在 Makefile 开头导出:
export GO111MODULE=on
如何让make deps只更新缺失依赖而不升级已有版本
go mod tidy 默认会拉取最小版本满足要求的依赖,但不会主动降级或保留 lock 文件中已记录的版本——它只做“补全+清理”,不是“重算”。真正控制版本锁定靠的是 go.sum 和 go.mod 中的 require 行。
- 执行
go mod tidy后,go.mod中新增的依赖会带精确版本(如github.com/sirupsen/logrus v1.9.3),而go.sum自动更新校验和 - 若想保留当前所有依赖版本不动,只补全缺失项,确保不出现
go get -u或go get package@latest类命令 - 避免在 Makefile 中写
go get ./...—— 它绕过go.mod约束,可能引入不兼容版本
并发执行 go mod download 失败?别在Makefile里用 -j 参数
Make 的 -j 并行模式对 go mod download 不友好:多个进程同时写入 $GOPATH/pkg/mod 目录,易触发文件锁冲突或校验失败,报错类似 invalid checksum 或 permission denied。
- 把依赖下载单独做成原子目标,不参与并行调度:
.NOTPARALLEL: deps
- 如需加速下载,改用
go mod download -x查看实际 fetch 过程,确认是否因代理或网络问题卡住 - 企业内网环境建议提前配置
GO_PROXY,并在 Makefile 中导出:export GO_PROXY=https://goproxy.cn,direct
怎么判断 make deps 是否真的更新了依赖
仅靠命令退出码无法判断是否有变更——go mod tidy 成功时总是返回 0,无论有没有修改文件。必须检查文件内容变化。
立即学习“go语言免费学习笔记(深入)”;
- 在 Makefile 中用
git status -s go.mod go.sum辅助验证(适合 Git 环境) - 更通用的做法:运行前后分别生成哈希,例如
before: $(shell sha256sum go.mod go.sum 2>/dev/null || echo none) deps: \tGO111MODULE=on go mod tidy \t@if [ "$$(sha256sum go.mod go.sum | cut -d' ' -f1)" != "$(before)" ]; then echo "✅ dependencies updated"; else echo "➡️ no change"; fi
- 注意:
go mod tidy可能重排go.mod中 require 行顺序,即使版本没变也会触发 diff,这不是 bug
GO111MODULE=on 的作用域——它只影响紧邻的那条命令,漏写或写在 recipe 外部都会失效。还有人把 make clean 设计成删 go.mod,结果下次 make deps 又从头 init,彻底丢掉原有依赖约束。


















