go build用于调试,生成可执行文件到当前目录;go install用于安装,将main包二进制安装至$GOBIN(默认$HOME/go/bin),要求模块路径合法且包为main,否则报错。

直接用 go build 和 go install 就够了,别一上来就写 Makefile —— 大多数项目根本不需要它。
go build 和 go install 到底该用哪个
构建命令行工具时,选错会导致二进制找不到、PATH 混乱、或安装失败。
-
go build默认把可执行文件生成在当前目录,不改$PATH,适合调试和临时运行 -
go install强制安装到$GOBIN(默认$HOME/go/bin),要求模块路径合法且包为main,否则报cannot install non-main package - 如果
go.mod里module声明是example.com/myapp,那go install ./cmd/serve会生成$GOBIN/serve,可直接终端调用 -
go install ./批量安装所有main包,但若某个cmd/foo/下没main.go或包名不是package main,会报no Go files in …
为什么不要用 go build ./
它看起来省事,实则污染源码、行为不可控、不适合部署。
-
go build ./只扫描当前目录下一级的包,不会递归进cmd/serve/这类嵌套结构 - 它会在每个含
main包的子目录里生成同名二进制,比如在./cmd/serve/下生成serve文件,而不是你期望的./bin/serve - 正确做法是显式指定输出路径:
go build -o ./bin/serve ./cmd/serve - 如果要用 Makefile 封装,别硬写
go build ./,改用go list -f '{{.ImportPath}}' ./cmd/动态获取包路径再构建
跨平台构建必须注意的两个坑
交叉编译不是设个 GOOS 就完事,链接和后缀容易翻车。
立即学习“go语言免费学习笔记(深入)”;
-
GOOS=windows GOARCH=amd64 go build会自动加.exe后缀;linux或darwin则无后缀,别在-o里硬写myapp.exe -
-ldflags="-X main.version=1.0.0"要求变量路径完全匹配:如果version定义在internal/version/version.go,就得写成-X github.com/yourname/myapp/internal/version.Version=1.0.0,否则链接静默失败,变量值为空字符串 - Go 1.21+ 默认关闭 GOPATH 模式,
$GOBIN必须在$PATH中才能直接调用go install生成的命令
真正麻烦的不是命令怎么写,而是模块路径是否合法、main 包是否被正确识别、以及 -X 引用的包路径是否和 import 路径一字不差 —— 这些地方出错,不会报错,只会让结果不符合预期。


















