通常对程序进行编译的时候,可能带一些条件(如不同平台、架构有不同的代码实现),让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。golang中,称之为​​编译约束​​,进行编译约束的方式有2种分别:

  • 编译标签(build tag)
  • 文件后缀

编译标签 (build tag)

在源码文件顶部添加注释,来决定文件是否参与编译

// +build <tags>

说明:

  • 以空格分开表示AND
  • 以逗号分开表示OR
  • !表示NOT

标签可以指定为以下内容:

​GOOS​​linux​​darwin​​windows​​go env​​GOOS​​GOARCH​​arch64​​x86​​i386​​go env​​GOARCH​​gc​​gccgo​​cgo​​go1.1​​go1.12​​go build -tags​
​(linux AND 386) OR (darwin AND (NOT cgo))​
// +build linux,386 darwin,!cgo
​(linux OR darwin) AND amd64​
// +build linux darwin
// +build amd64
​ignore​
// +build ignore
​// +build​
// +build linux

// main package comment
package main
​build tag​
// +build linux
package main

文件后缀

除了编译标签,编译器也会根据文件后缀来自动选择编译文件,格式如下:

$filename_$GOOS.go
$filename_$GOARCH.go
$filename_$GOOS_$GOARCH.go
​$filename​​$GOOS​​$GOARCH​
​tcp.go​​tcp_linux_x86.go​
GOOS=linux GOARCH=x86 go build
​tcp_linux_x86.go​
GOOS=linux GOARCH=x86 go build
​tcp.go​

利用ldflags在编译过程中为变量赋值

​ldflags​​go build​
go build -ldflags "-w -s -X main.Version=${VERSION} -X github.com/demo/version.BuildNo=${BUILD_NO}"

参数说明:

-w 删除DWARF信息:编译出来的程序无法用gdb进行调试。

-s 删除符号表:panic的stack trace没有文件名/行号信息,等价于C/C++程序被strip。

-X 替换包中的变量的值。


加上-w -s可以有效减少编译出来地程序的大小,但不利于进行调试和日志追踪。