go.mod中module路径必须与远程仓库URL逐字符一致,否则Android交叉编译时会因checksum mismatch或cannot find module失败;需严格匹配大小写、斜杠及子组路径,并确保replace目标含有效go.mod且路径为相对路径。

go.mod module路径必须与远程仓库URL完全一致
模块路径不匹配是交叉编译移动端(如Android)时最常导致checksum mismatch或cannot find module的根本原因。Go在解析依赖时,会严格比对go.mod中module声明和import语句中的路径——哪怕只差一个斜杠、大小写或子路径层级,都会在目标平台构建时触发校验失败,尤其当CI环境拉取私有仓库或GitLab子组项目时更明显。
- 检查你的
go.mod第一行:module值必须和代码托管地址**逐字符一致**,例如托管在gitlab.com/group/subgroup/myapp,就不能写成module myapp或module gitlab.com/group/myapp - 本地开发用
go mod init myproj起名后推到GitHub?立刻修正go.mod为module github.com/yourname/myproj,否则别人go get时会校验失败 - Android构建通常在CI中执行,而CI拉取的是远程tag或commit,
replace指令不会生效——所以生产构建前务必删掉go.mod里的replace行,改用go get github.com/you/lib@v1.2.3锁定版本
Android交叉编译时不能依赖CGO,但go.mod仍需兼容cgo-enabled标准库
你可能遇到unable to find runtime/cgo.a警告,或import "C"被误触发——这不是go.mod写错了,而是Go Android运行时本身隐式依赖cgo,即使你代码里没写任何C。此时go.mod里的依赖声明必须允许cgo-enabled构建环境解析,否则go build会在准备阶段卡住。
-
CGO_ENABLED=0是必须的(否则生成的二进制会链接宿主机glibc,无法在Android上运行),但go.mod里引用的包(比如net、os/user)仍要保持原样,不要手动替换为纯Go分支 - 避免在
go.mod中使用replace指向一个没有go.mod的本地目录——Go会fallback到legacy mode,而Android目标平台不支持该模式,直接报no required module provides package - 如果依赖某个含C代码的第三方库(如
github.com/mattn/go-sqlite3),它在CGO_ENABLED=0下根本无法编译;要么彻底移除该依赖,要么接受它不支持Android——没有中间方案
私有模块或本地调试依赖必须用相对路径+go.mod
开发阶段想用本地修改的SDK适配Android?replace能用,但路径和结构稍有偏差就会静默失效,尤其在跨平台构建时。
-
replace github.com/you/sdk => ../sdk——路径必须是相对于当前go.mod的**相对路径**,不能用~/sdk或绝对路径 - 被
replace的目标目录**必须包含有效的go.mod**,且其module声明要与原导入路径一致;否则Go会忽略该replace,继续尝试拉远程版本 - Android构建常在Docker或CI容器中运行,这些环境默认不挂载父目录;若用
../sdk,需确保构建命令的工作目录是模块根目录,且../sdk实际可达
GOOS=android时go.sum校验行为与Linux不同
Android平台的go.sum文件内容和校验逻辑和Linux略有差异,尤其当你混合使用replace和indirect依赖时,容易在交叉编译时出现verifying ...: checksum mismatch。
立即学习“go语言免费学习笔记(深入)”;
- 每次修改
go.mod或执行go get后,务必运行go mod tidy && go mod verify,而不是只看本地能否编译通过 - Android构建前,先在本地用
CGO_ENABLED=0 GOOS=android GOARCH=arm64 go list -m all确认所有依赖都能解析成功——这条命令会模拟Android构建环境的模块解析路径 - 如果
go.sum里出现// indirect标记的行,而对应模块在Android上实际不可用(比如用了syscall非Android实现),go build不会提前报错,而是在链接阶段失败,错误信息模糊(如undefined reference to 'getifaddrs')
module,而是错误出现在replace指向的私有模块里——那个模块自己没设好go.mod,或者它的依赖又嵌套了另一层不兼容Android的C绑定,这种问题只会在线上构建时暴露,本地完全测不出来。


















