--- title: "Go Tricks 0:build" date: 2021-11-12T11:33:36+07:00 draft: false --- ## 编译 `go build` 可以用 `-gcflags` 传递 go 编译器参数,帮助信息可通过 `go tool compile --help` 查看。 主要用 `-m` 参数检查代码的编译优化、逃逸、函数内联情况。 也可以用 `-ldflags` 连给链接器传参,帮助信息可通过 `go tool link --help` 查看。 主要用途有 - `-s -w` 来减小输出二进制的体积 (更小体积可加壳) - `-s`: 删除符号表,panic 时 stack trace 没有文件名/行号信息 - `-w`: 删除 DWARF 信息,二进制无法通过 gdb 调试。 - 利用 `go build -ldflags "-X main.version=1.1` 来进行编译时变量赋值(限 `string` 类型) ## 条件编译 go 中实现条件编译可以通过编译标签(build tag)和文件名(xxx_linux_x64.go)两种方式。 ### 编译标签(build tag) 通过在源码文件顶部添加注释标签,来指示编译器条件编译动作 ```go // +build ``` 就是标签,可以有多个,多个标签的分割符用来指示标签之前的关系 - 以空格分割表示 AND - 以逗号分割表示 OR - !表示 NOT 标签可能指示的内容 - **操作系统**。如 `linux, darwin, windows` 等,对应 $GOOS 的值 - **操作系统架构**。如 `arch64, x64, i386`,对应 $GOARCH 的值 - **编译器**。如 `gc, gccgo` - **是否开启 CGO**。 `cgo` - **go版本**。如 `go1.1, go1.1.2` - **自定义标签**。通过 `go build -tags 指定。 举例 ```golang // +build linux,386 darwin,!cgo ``` 表示编译条件为: (linux AND 386) OR (darwin AND !cgo) ```golang // +build linux darwin // +build amd64 ``` 表示多个条件, (linux OR darwin) AND amd64 ```golang // +build ignore ``` 表示此文件忽略,不参与编译。 最后, `// +build ` 的下一行必须为空行。 ### 文件名表示条件 格式: ```shell $filename_$GOOS.go $filename_$GOARCH.go $filename_$GOOS_$GOARCH.go ``` 举例 比如有两个文件 `setopt.go` 和 `setopt_linux.go` 执行 ```shell GOOS=linux go build ``` 将编译后者。