通常對程序進行編譯的時候,可能帶一些條件(如不同平台、架構有不同的代碼實現),讓編譯器只對滿足條件的代碼進行編譯,將不滿足條件的代碼舍棄,這就是條件編譯。golang中,稱之為編譯約束,進行編譯約束的方式有2種分別:
- 編譯標簽(build tag)
- 文件后綴
編譯標簽 (build tag)
在源碼文件頂部添加注釋,來決定文件是否參與編譯
// +build <tags>
- 以逗號分開表示
AND
- 以空格分開表示
OR
!
表示NOT
- 一個文件可以有多個
+build
構建標記,它們之間的關系是邏輯與
的關系
標簽可以指定為以下內容:
- 操作系統,環境變量中
GOOS
的值,如:linux
、darwin
、windows
等等。可以通過go env
查看GOOS
環境變量的值。 - 操作系統的架構,環境變量中
GOARCH
的值,如:arch64
、x86
、i386
等等。可以通過go env
查看GOARCH
環境變量的值。 - 使用的編譯器,
gc
或者gccgo
。 - 是否開啟CGO,
cgo
。 - golang版本號: 比如Go Version 1.1為
go1.1
,Go Version 1.12版本為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
進行編譯。
利用ldflags在編譯過程中為變量賦值
本節為附加說明,不屬於條件編譯的范疇。有時我們需要在編譯過程中為變量賦值,此時可以利用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可以有效減少編譯出來地程序的大小,但不利於進行調試和日志追蹤。
參考文章
本文轉載自:Go 知識點(18)— 條件編譯(編譯標簽、文件后綴)_wohu1104的博客-CSDN博客_go 條件編譯