build 参数
使用方法usage: go build [-o output] [-i] [build flags] [packages]
go build的使用比较简洁,所有的参数都可以忽略,直到只有go build,这个时候意味着使用当前目录进行编译, 因此:
go build = go build . = go build main.go
go build 主要参数是 -o output 指定编译输出的名称,代替默认的包名。
此外还有一些基础参数,包括install, run, test都能用的参数包括:
1 | -gcflags 'arg list': 垃圾回收参数 |
其中通过利用 -ldflags
参数,可以向链接器传递指令。向链接器传一个 -X 指令可以设置程序中字符串变量的值。利用这个方法能够实现例如在编译时设置程序的版本信息, 例如:
1 | package main |
通过设置 go build -ldflags '-X main._version_="v0.2"'
编译后输出的版本信息就是v0.2, 通过-X参数可以很方便的设置一些频繁改动的变量。需要注意的是-X只能给string类型变量赋值
如果要设置多个变量可以: go build -ldflags "-X importpath.name=value -X importpath_2.name_2=value_2"
如果要赋值的变量包含空格,需要用引号将 -X 后面的变量和值都扩起来:go build -ldflags "-X 'importpath.name=a string contains space' -X 'importpath_2.name_2=v
通过利用-gcflags
参数, 可以做一些逃逸分析等操作,用-gcflags
给go编译器传入参数,也就是传给go tool compile的参数,因此可以用go tool compile --help
查看所有gcflags可用的参数, 例如:
1 | go build -gcflags -gcflags='log=-N -l' main.go |
Go 交叉编译
go build 提供了跨平台编译,默认情况下,都是根据我们当前的机器生成的可执行文件,比如你的是Linux 64位,就会生成Linux 64位下的可执行文件。
可以通过go env 来查看当前的环境变量
1 | ➜ ~ go env |
在上面的环境变量中,与跨平台编译有关的变量有GOOS, GOARCH, GOOS指的是目标操作系统, GOARCH指的是目标处理器的架构。
GOOS可选的值包括: android,darwin(MACOS 10.11和上述和IOS), dragonfly,freebsd,illumos,js, linux,netbsd,,openbsd 和。 plan9solariswindows
GOARCH可选的值包括 amd64(64位x86,最成熟的端口), 386(32位x86),arm(32位ARM),arm64(64位ARM), ppc64le(PowerPC 64位,little-endian),ppc64(PowerPC 64位(big-endian), mips64le(MIPS 64位,little-endian),mips64(MIPS 64位,big-endian), mipsle(MIPS 32位,little-endian),mips(MIPS 32位,big-endian) ), s390x(IBM System z 64位,big-endian)和 wasm(WebAssembly 32位)。
关于他们的对应关系可以参考官方文档
在交叉编译中通过指定不同的GOOS跟GOARCH,就可以编译成不同平台的可执行文件
例如可以在linux系统下编译成window跟mac的可执行文件
1 | CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go |
可以在mac系统中编译成linux跟windows的可执行文件
1 | CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go |
编译技巧
go build mod
使用 go build -mod=vendor
来构建项目,因为在 go modules
模式下 go build
是屏蔽 vendor 机制的,所以需要特定参数重新开启 vendor 机制, 这样子断点调试的时候,就能够在vendor文件夹下断点了。如果golang的版本大于等于1.14, 则默认使用-mod=vendor
go build tag
-ldflags 可以传递指令,也可以通过// +build
标记去做,如下所示:
1 | // +build release |
上面代码的关键是 // +build release
这行代码,注意这行代码前后须有一个空行隔开,例如在第一行时,接下来要空出一行。这个文件只会被go bulid识别到,而go run等命令不会去识别这个文件,而且vscode, golang等编辑器也会略过这个文件。
通过引入 // +build的好处就是可以作为文件包, 比如main包要引入其他main 包的方案中,可以创建一个空的文件,然后引入文件。
1 | // +build tools |