go build 仅编译显式指定的包,识别可执行文件的关键是 package main 声明;非 main 包仅做检查不输出文件,且默认不递归子目录,需明确指定如 ./cmd/app 才能生成对应二进制。

go build 不能直接构建整个“项目”,它只编译你明确指定的包(目录或文件),且只保留 main 包的可执行结果。
go build 怎么识别要编译的是可执行文件还是库
关键看包声明:package main 才会生成可执行文件;其他包名(如 package utils)编译后不输出文件,仅做语法和依赖检查。
- 运行
go build main.go→ 输出main(Linux/macOS)或main.exe(Windows) - 运行
go build utils.go→ 无输出,但会报错 ifutils.go里不是main包且有未解决的 import - 运行
go build ./cmd/serve→ 若该目录下有package main,则生成serve可执行文件 - 运行
go build ./internal/handler→ 不生成任何文件,只验证能否编译通过
为什么 go build . 没生成预期的二进制文件
因为 . 表示当前目录,而当前目录的包名很可能不是 main。常见于模块根目录放 go.mod,但没放 main.go。
- 检查当前目录是否含
package main:运行grep "^package main" *.go - 如果 main 文件在
./cmd/app下,就得用go build ./cmd/app,而不是go build . -
go build不会递归扫描子目录找main包;./...会,但它会为每个匹配的main包都生成一个二进制,容易混乱 - 错误示例:
go build .在根目录执行,结果静默成功但无输出——说明当前包不是main,只是检查通过了
交叉编译时 GOOS/GOARCH 必须提前设置
Go 不支持在 go build 命令里用 --os 这类参数;必须靠环境变量控制目标平台。
- 编译 Linux 二进制(即使你在 macOS 上):
GOOS=linux GOARCH=amd64 go build -o myapp ./cmd/app - 编译 ARM64 macOS:
GOOS=darwin GOARCH=arm64 go build -o myapp ./cmd/app - Windows 下需用
set GOOS=windows && set GOARCH=386 && go build ...(PowerShell 或 CMD 语法不同) - 漏设
GOARCH可能导致生成非预期架构(例如 macOS 默认是arm64,但 CI 机器可能是amd64)
go:build 标签写错会导致文件被完全忽略
//go:build 是构建约束指令,不是注释。位置、格式、拼写错一点,文件就既不参与编译,也不报错。
- 正确写法(顶格、双斜杠、无空格):
//go:build linux,且必须在文件最顶部,前面只能有空行或//注释 - 错误写法:
go:build linux(缺//)、// go:build linux(中间多空格)、//go:build linux // +build darwin(混用旧语法) - 验证方式:
go list -f '{{.GoFiles}}' ./pkg,看目标文件是否出现在输出中 - 跨平台代码里,常因标签写错导致某平台编译失败却查不出原因——因为对应文件根本没被加载











