命令列表
build compile packages and dependencies
clean remove object files
doc show documentation for package or symbol
env print Go environment information
bug start a bug report
fix run go tool fix on packages
fmt run gofmt on package sources
generate generate Go files by processing source
get download and install packages and dependencies
install compile and install packages and dependencies
list list packages
run compile and run Go program
test test packages
tool run specified go tool
version print Go version
vet run go tool vet on packages
go build
-
如果目录里有 main 包,就会生成二进制可执行文件
- 如果没有 main 包,build 指令仅仅检查编译是否可以通过,编译完成后会丢弃编译时生成的所有临时包对象
-
默认在当前目录下生成二进制文件
- 使用
-o
参数显式指定输出路径和文件名
- 使用
-
默认作用范围为当前文件夹
- 也可以显式指定目录编译
- 绝对路径或者相对于gopath的路径
go build ~/go/src/github.com/xxx/xxx
...
递归编译目录下的所有包go build flysnow.org/tools/...
编译tools目录下的所有main包
- 也可以显式指定目录编译
-
执行go build时一般传入文件夹作为参数,而不是
.go
文件- 否则如果
package main
下有多个文件的话,就必须把所有.go
文件作为参数
- 否则如果
-
-race
参数开启竞争检测- 如果有竞争风险终端会有warning 输出
- 会影响性能,不要用于线上
-
简单函数可能会被自动内联,导致堆栈被隐藏
- 可以在debug时通过
-gcflags="all=-l -N"
参数禁止内联和优化 -N
是禁止优化,-l
是禁止内联
- 可以在debug时通过
-
-n
参数可以打印所有编译过程中的命令,但不真正执行- 包括创建临时目录,查找依赖信息,执行源代码编译,收集链接库文件,生成可执行文件,移动可执行文件
- 参考:https://zhuanlan.zhihu.com/p/62922404
-
编译缓存
- go在编译后会把中间结果(
.a
文件)缓存下来,实现增量编译,后续编译的速度会大大提升 - 所以连续两次
go build -v
打印的命令会不一样 - 可以使用
go build -a
强制重新编译 - 使用
go clean -cache
可以清除编译缓存
- go在编译后会把中间结果(
-
go编译引入一个库必须要依赖库的源代码
- 不能是编译好的二进制文件(即
.a
文件).a
文件只能被编译器用作编译缓存
- 因为不能保证二进制包编译使用与最终链接相同的依赖项版本
- 原因:https://github.com/golang/go/issues/28152
- 不能是编译好的二进制文件(即
-
跨平台(交叉)编译:
- 举例:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
- 存在交叉编译的情况时,cgo 是不应该被用的
- 因为目标环境可能没有安装所需的动态链接库
- 例如docker的一些镜像
- 通过
CGO_ENABLED=0
关闭- golang 是默认开启 cgo 工具的,即
CGO_ENABLED=1
- golang 是默认开启 cgo 工具的,即
- 关闭 cgo 后,在构建过程中会忽略 cgo 并静态链接所有的依赖库
- 而开启 cgo 后,方式将转为动态链接
- 因为目标环境可能没有安装所需的动态链接库
- 举例:
-
条件编译
- 只支持文件级别的条件编译
- 方法一: 文件开头的编译标签
- 编译标签需要和下面的包声明(例如
package main
)用空行隔开- 否则会被视为包声明的注释
- 一行内的所有条件为或的关系
- 例如
// +build dawin freebsd
- 例如
- 每一行之间的条件为与的关系
!
为在该平台不编译// +build !linux
- 上述条件编译时自动触发的,我们还可以通过build的tag参数手动触发
- 文件:
// +build jsoniter
- 命令:
go build -tag=jsoniter
- 文件:
- 编译标签需要和下面的包声明(例如
- 方法二:文件后缀
- 如果你的源文件包含
_$GOOS.go
或者_$GOARCH.go
后缀,那么这个源文件只会在这个平台/系统下编译 - 这两个后缀可以结合在一起使用,但是要注意顺序
_$GOOS_$GOARCH.go
- 不能反过来用
_$GOARCH_$GOOS.go
- 如果你的源文件包含
- 参考:https://blog.csdn.net/varding/article/details/12675971
go run
- 必须要包含main函数的go文件作为参数
- 编译和执行程序,但不在本目录生成二进制文件
- 实际是在临时目录编译完成后直接执行并删除临时目录
- 使用–work保留这个目录
- 和go build的区别就在于没有把编译产物移动到当前目录
- 实际是在临时目录编译完成后直接执行并删除临时目录
go install
- 编译并安装项目到
$GOPATH/bin
目录下- 当存在多个GOPATH目录时,只安装到第一个目录
- 从
go 1.16
开始,项目路径后必须带上版本号或分支名,从而安装指定版本的可执行文件- 除非当前目录含有
go.mod
,此时会编译本安装当前版本
- 除非当前目录含有
- 只安装含有main包的项目(即生成可执行文件)
go env
- 不加参数即为查看环境参数
- 也可以只看某一个环境变量
- 例如
go env GOROOT
- 例如
- 也可以只看某一个环境变量
-w
设置全局环境变量- 例如
go env -w GOBIN=$HOME/bin
- 例如
go version
go version -v <二进制文件>
可以查看可执行文件的go版本go version -v <二进制文件>
可以查看可执行文件所有依赖库及其版本
go clean
-i
清除关联的安装的包和可运行文件,也就是通过go install安装的文件-n
把需要执行的清除命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的-x
打印出来执行的详细命令,其实就是 -n 打印的执行版本-r
循环的清除在 import 中引入的包-cache
删除所有go build命令的缓存-testcache
删除当前包所有的测试结果-modcache
删除所有module依赖下载缓存
go fmt
- -w 指示该工具在适当的位置重写文件
- -s指示该工具在可能的情况下对代码进行简化
- -d指示该工具输出更改的差异
- -l只显示已更改文件的名称,而不是差异
gofmt
以递归方式工作- 如果将目录传递给它,将格式化该目录下的所有文件
go fmt
等价于gofmt -l -w
go vet
- 配置Goland的
file watcher
golint
- 配置Goland的
file watcher